ContactsProvider2.java revision 3cb415e7b97c3e318d7a16aaf7cc5c6b825d349a
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; 205870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikovimport com.android.providers.contacts.ContactLookupKey.LookupKeySegment; 21e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikovimport com.android.providers.contacts.OpenHelper.AggregatedPresenceColumns; 2228f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.AggregationExceptionColumns; 2328f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.Clauses; 24d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport com.android.providers.contacts.OpenHelper.ContactsColumns; 2528f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.DataColumns; 2625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikovimport com.android.providers.contacts.OpenHelper.DisplayNameSources; 2728f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.GroupsColumns; 2828f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.MimetypesColumns; 2911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikovimport com.android.providers.contacts.OpenHelper.NameLookupColumns; 305870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikovimport com.android.providers.contacts.OpenHelper.NameLookupType; 3167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport com.android.providers.contacts.OpenHelper.PackagesColumns; 32d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport com.android.providers.contacts.OpenHelper.PhoneColumns; 3328f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.PhoneLookupColumns; 344dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikovimport com.android.providers.contacts.OpenHelper.PresenceColumns; 35d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport com.android.providers.contacts.OpenHelper.RawContactsColumns; 3628f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.Tables; 37e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikovimport com.google.android.collect.Lists; 38e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 39b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.accounts.Account; 40caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikovimport android.accounts.AccountManager; 41c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.app.SearchManager; 42568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikovimport android.content.ContentProviderOperation; 43568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikovimport android.content.ContentProviderResult; 4435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintanaimport android.content.ContentUris; 4567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.content.ContentValues; 4667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.content.Context; 4735ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintanaimport android.content.Entity; 4867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.content.EntityIterator; 49568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikovimport android.content.OperationApplicationException; 503d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikovimport android.content.SharedPreferences; 5167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.content.UriMatcher; 523d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikovimport android.content.SharedPreferences.Editor; 53b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikovimport android.content.res.AssetFileDescriptor; 544f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamiltonimport android.database.Cursor; 55ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.database.DatabaseUtils; 56b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikovimport android.database.sqlite.SQLiteContentHelper; 57b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.database.sqlite.SQLiteCursor; 584f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamiltonimport android.database.sqlite.SQLiteDatabase; 594f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamiltonimport android.database.sqlite.SQLiteQueryBuilder; 60c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millarimport android.database.sqlite.SQLiteStatement; 614f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamiltonimport android.net.Uri; 62b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.os.RemoteException; 633d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikovimport android.preference.PreferenceManager; 64508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkeyimport android.provider.BaseColumns; 65de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract; 661b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikovimport android.provider.LiveFolders; 67b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions; 68de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.CommonDataKinds; 69d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 70de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.Data; 71ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.Groups; 72e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikovimport android.provider.ContactsContract.PhoneLookup; 731f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkeyimport android.provider.ContactsContract.Presence; 74d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts; 75eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkeyimport android.provider.ContactsContract.Settings; 763cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.BaseTypes; 77ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Email; 78ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 793cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Im; 803cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Nickname; 813cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization; 82de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.CommonDataKinds.Phone; 83b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Photo; 844097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 8567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 86a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamiltonimport android.telephony.PhoneNumberUtils; 87a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamiltonimport android.text.TextUtils; 88c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.util.Log; 894f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 90b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikovimport java.io.FileNotFoundException; 917e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintanaimport java.util.ArrayList; 925870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikovimport java.util.Collections; 93b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport java.util.HashMap; 945870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikovimport java.util.List; 95ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikovimport java.util.concurrent.CountDownLatch; 964f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 974f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton/** 984f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * Contacts content provider. The contract between this provider and applications 994f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * is defined in {@link ContactsContract}. 1004f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton */ 101de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikovpublic class ContactsProvider2 extends SQLiteContentProvider { 102caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov 103b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // TODO: clean up debug tag and rename this class 104b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private static final String TAG = "ContactsProvider ~~~~"; 1054f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 106619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // TODO: carefully prevent all incoming nested queries; they can be gaping security holes 107619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // TODO: check for restricted flag during insert(), update(), and delete() calls 108619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 1093cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** Default for the maximum number of returned aggregation suggestions. */ 1103cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private static final int DEFAULT_MAX_SUGGESTIONS = 5; 1113cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 1123d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov /** 1133d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov * Shared preference key for the legacy contact import version. The need for a version 1143d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov * as opposed to a boolean flag is that if we discover bugs in the contact import process, 1153d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov * we can trigger re-import by incrementing the import version. 1163d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov */ 1173d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov private static final String PREF_CONTACTS_IMPORTED = "contacts_imported_v1"; 1183d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov private static final int PREF_CONTACTS_IMPORT_VERSION = 1; 1193d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 120a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 1214f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 122d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final String STREQUENT_ORDER_BY = Contacts.STARRED + " DESC, " 123d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.TIMES_CONTACTED + " DESC, " 124d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.DISPLAY_NAME + " ASC"; 125d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar private static final String STREQUENT_LIMIT = 126d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov "(SELECT COUNT(1) FROM " + Tables.CONTACTS + " WHERE " 127d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.STARRED + "=1) + 25"; 128d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov 129d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final int CONTACTS = 1000; 130d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final int CONTACTS_ID = 1001; 1315870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private static final int CONTACTS_LOOKUP = 1002; 1325870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private static final int CONTACTS_LOOKUP_ID = 1003; 1335870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private static final int CONTACTS_DATA = 1004; 1345870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private static final int CONTACTS_FILTER = 1005; 1355870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private static final int CONTACTS_STREQUENT = 1006; 1365870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private static final int CONTACTS_STREQUENT_FILTER = 1007; 1375870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private static final int CONTACTS_GROUP = 1008; 1385870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private static final int CONTACTS_PHOTO = 1009; 1394f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 1405ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private static final int RAW_CONTACTS = 2002; 1415ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private static final int RAW_CONTACTS_ID = 2003; 1425ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private static final int RAW_CONTACTS_DATA = 2004; 1434f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 1446bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov private static final int DATA = 3000; 1456bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov private static final int DATA_ID = 3001; 146ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar private static final int PHONES = 3002; 147ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar private static final int PHONES_FILTER = 3003; 1484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final int EMAILS = 3004; 1494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final int EMAILS_FILTER = 3005; 1504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final int POSTALS = 3006; 151a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 1526bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov private static final int PHONE_LOOKUP = 4000; 1536bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 154b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov private static final int AGGREGATION_EXCEPTIONS = 6000; 155b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov private static final int AGGREGATION_EXCEPTION_ID = 6001; 156b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 1571f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey private static final int PRESENCE = 7000; 1581f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey private static final int PRESENCE_ID = 7001; 1591f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 16031b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov private static final int AGGREGATION_SUGGESTIONS = 8000; 16131b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 162eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey private static final int SETTINGS = 9000; 163eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 164ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private static final int GROUPS = 10000; 165ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private static final int GROUPS_ID = 10001; 166ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private static final int GROUPS_SUMMARY = 10003; 167ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 16835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana private static final int SYNCSTATE = 11000; 16935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 170c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov private static final int SEARCH_SUGGESTIONS = 12001; 171c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov private static final int SEARCH_SHORTCUT = 12002; 172c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 173a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov private static final int DATA_WITH_PRESENCE = 13000; 17419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov 1751b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov private static final int LIVE_FOLDERS_CONTACTS = 14000; 1761b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov private static final int LIVE_FOLDERS_CONTACTS_WITH_PHONES = 14001; 1771b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov private static final int LIVE_FOLDERS_CONTACTS_FAVORITES = 14002; 1781b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov private static final int LIVE_FOLDERS_CONTACTS_GROUP_NAME = 14003; 1791b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov 18067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey private interface ContactsQuery { 1815ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String TABLE = Tables.RAW_CONTACTS; 1829261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 18367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String[] PROJECTION = new String[] { 1846cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContactsColumns.CONCRETE_ID, 1856cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_NAME, 1866cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_TYPE, 187ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey }; 188ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1895ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final int RAW_CONTACT_ID = 0; 19067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int ACCOUNT_NAME = 1; 19167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int ACCOUNT_TYPE = 2; 19267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey } 19367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 194d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private interface DataContactsQuery { 195d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String TABLE = Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS; 19667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 19767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String[] PROJECTION = new String[] { 1986cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContactsColumns.CONCRETE_ID, 1993cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DataColumns.CONCRETE_ID, 200d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov ContactsColumns.CONCRETE_ID, 2013cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov MimetypesColumns.CONCRETE_ID, 202ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey }; 203ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 204d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final int RAW_CONTACT_ID = 0; 20567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int DATA_ID = 1; 206d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final int CONTACT_ID = 2; 20767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int MIMETYPE_ID = 3; 208ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2091f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 2103cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private interface DisplayNameQuery { 21167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String TABLE = Tables.DATA_JOIN_MIMETYPES; 2123cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 2133cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final String[] COLUMNS = new String[] { 2143cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov MimetypesColumns.MIMETYPE, 2153cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Data.IS_PRIMARY, 2163cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Data.DATA2, 2173cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov StructuredName.DISPLAY_NAME, 2183cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov }; 2193cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 2203cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int MIMETYPE = 0; 2213cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int IS_PRIMARY = 1; 2223cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int DATA2 = 2; 2233cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int DISPLAY_NAME = 3; 2243cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 2253cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 22614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov private interface DataDeleteQuery { 22767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String TABLE = Tables.DATA_JOIN_MIMETYPES; 2283cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 22988e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov public static final String[] CONCRETE_COLUMNS = new String[] { 2303cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DataColumns.CONCRETE_ID, 2313cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov MimetypesColumns.MIMETYPE, 2325ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Data.RAW_CONTACT_ID, 2333cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Data.IS_PRIMARY, 2343cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Data.DATA2, 23588e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov }; 23688e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov 23788e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov public static final String[] COLUMNS = new String[] { 23888e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov Data._ID, 23988e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov MimetypesColumns.MIMETYPE, 24088e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov Data.RAW_CONTACT_ID, 24188e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov Data.IS_PRIMARY, 24288e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov Data.DATA2, 2433cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov }; 2443cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 24514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public static final int _ID = 0; 2463cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int MIMETYPE = 1; 2475ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final int RAW_CONTACT_ID = 2; 2483cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int IS_PRIMARY = 3; 24988e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov public static final int DATA2 = 4; 2503cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 2513cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 25214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov private interface DataUpdateQuery { 253321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana String[] COLUMNS = { Data._ID, Data.RAW_CONTACT_ID, Data.MIMETYPE }; 25420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 25520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov int _ID = 0; 256321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana int RAW_CONTACT_ID = 1; 257321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana int MIMETYPE = 2; 25820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 25920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 26025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov private static final HashMap<String, Integer> sDisplayNameSources; 2613cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov static { 26225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov sDisplayNameSources = new HashMap<String, Integer>(); 26325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov sDisplayNameSources.put(StructuredName.CONTENT_ITEM_TYPE, 26425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov DisplayNameSources.STRUCTURED_NAME); 26525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov sDisplayNameSources.put(Organization.CONTENT_ITEM_TYPE, 26625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov DisplayNameSources.ORGANIZATION); 26725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov sDisplayNameSources.put(Phone.CONTENT_ITEM_TYPE, 26825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov DisplayNameSources.PHONE); 26925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov sDisplayNameSources.put(Email.CONTENT_ITEM_TYPE, 27025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov DisplayNameSources.EMAIL); 2713cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 27231b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 273caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov public static final String DEFAULT_ACCOUNT_TYPE = "com.google.GAIA"; 274df9fd6b239de5829b04cb413e4dfa3e6da649c38Fred Quintana public static final String FEATURE_LEGACY_HOSTED_OR_GOOGLE = "legacy_hosted_or_google"; 275caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov 276038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana /** Contains just BaseColumns._COUNT */ 277038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana private static final HashMap<String, String> sCountProjectionMap; 278e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov /** Contains just the contacts columns */ 2794f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton private static final HashMap<String, String> sContactsProjectionMap; 280ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov /** Contains contacts and presence columns */ 281ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov private static final HashMap<String, String> sContactsWithPresenceProjectionMap; 282ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov /** Contains just the raw contacts columns */ 283d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final HashMap<String, String> sRawContactsProjectionMap; 2844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** Contains columns from the data view */ 2854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final HashMap<String, String> sDataProjectionMap; 2869261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana /** Contains the data and contacts columns, for joined tables */ 287e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov private static final HashMap<String, String> sPhoneLookupProjectionMap; 288ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** Contains the just the {@link Groups} columns */ 289ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private static final HashMap<String, String> sGroupsProjectionMap; 290ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** Contains {@link Groups} columns along with summary details */ 291ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private static final HashMap<String, String> sGroupsSummaryProjectionMap; 292373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov /** Contains the agg_exceptions columns */ 293b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov private static final HashMap<String, String> sAggregationExceptionsProjectionMap; 294eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey /** Contains the agg_exceptions columns */ 295eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey private static final HashMap<String, String> sSettingsProjectionMap; 296373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov /** Contains Presence columns */ 297373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov private static final HashMap<String, String> sPresenceProjectionMap; 29819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov /** Contains Presence columns */ 299a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov private static final HashMap<String, String> sDataWithPresenceProjectionMap; 3001b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov /** Contains Live Folders columns */ 3011b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov private static final HashMap<String, String> sLiveFoldersProjectionMap; 3027e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 303b67163a1088f09c59f324350662eb18772fac6b6Evan Millar /** Sql where statement for filtering on groups. */ 304d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final String sContactsInGroupSelect; 30519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov 306c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar /** Precompiled sql statement for setting a data record to the primary. */ 307c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar private SQLiteStatement mSetPrimaryStatement; 3083cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** Precompiled sql statement for setting a data record to the super primary. */ 309c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar private SQLiteStatement mSetSuperPrimaryStatement; 310d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov /** Precompiled sql statement for incrementing times contacted for an contact */ 311f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov private SQLiteStatement mLastTimeContactedUpdate; 3123cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** Precompiled sql statement for updating a contact display name */ 31325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov private SQLiteStatement mRawContactDisplayNameUpdate; 31473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov /** Precompiled sql statement for marking a raw contact as dirty */ 31573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private SQLiteStatement mRawContactDirtyUpdate; 316e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov /** Precompiled sql statement for setting an aggregated presence */ 317e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov private SQLiteStatement mAggregatedPresenceReplace; 318e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov /** Precompiled sql statement for updating an aggregated presence status */ 319e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov private SQLiteStatement mAggregatedPresenceStatusUpdate; 320a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 3214f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton static { 3224f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton // Contacts URI matching table 323a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton final UriMatcher matcher = sUriMatcher; 324d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS); 325d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID); 326d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_DATA); 3273653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions", 3283653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov AGGREGATION_SUGGESTIONS); 3293653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/photo", CONTACTS_PHOTO); 3305870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/filter/*", CONTACTS_FILTER); 3315870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*", CONTACTS_LOOKUP); 3325870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*/#", CONTACTS_LOOKUP_ID); 3335870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/strequent/", CONTACTS_STREQUENT); 334ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/strequent/filter/*", 335ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov CONTACTS_STREQUENT_FILTER); 3365870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/group/*", CONTACTS_GROUP); 3373653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov 3385ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts", RAW_CONTACTS); 3395ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#", RAW_CONTACTS_ID); 3405ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/data", RAW_CONTACTS_DATA); 341b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 3424f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton matcher.addURI(ContactsContract.AUTHORITY, "data", DATA); 3434f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton matcher.addURI(ContactsContract.AUTHORITY, "data/#", DATA_ID); 344ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar matcher.addURI(ContactsContract.AUTHORITY, "data/phones", PHONES); 345ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter/*", PHONES_FILTER); 3464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "data/emails", EMAILS); 3474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter/*", EMAILS_FILTER); 348ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar matcher.addURI(ContactsContract.AUTHORITY, "data/postals", POSTALS); 3491f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 350ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey matcher.addURI(ContactsContract.AUTHORITY, "groups", GROUPS); 351ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey matcher.addURI(ContactsContract.AUTHORITY, "groups/#", GROUPS_ID); 352ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey matcher.addURI(ContactsContract.AUTHORITY, "groups_summary", GROUPS_SUMMARY); 353ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 35435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana matcher.addURI(ContactsContract.AUTHORITY, SyncStateContentProviderHelper.PATH, SYNCSTATE); 35535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 356a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton matcher.addURI(ContactsContract.AUTHORITY, "phone_lookup/*", PHONE_LOOKUP); 357b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "aggregation_exceptions", 358b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AGGREGATION_EXCEPTIONS); 359b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "aggregation_exceptions/*", 360b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AGGREGATION_EXCEPTION_ID); 3614f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 362eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey matcher.addURI(ContactsContract.AUTHORITY, "settings", SETTINGS); 363eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 364bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar matcher.addURI(ContactsContract.AUTHORITY, "presence", PRESENCE); 365bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar matcher.addURI(ContactsContract.AUTHORITY, "presence/#", PRESENCE_ID); 3661f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 367c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, 368c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SEARCH_SUGGESTIONS); 369c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", 370c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SEARCH_SUGGESTIONS); 371c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/#", 372c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SEARCH_SHORTCUT); 373c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3741b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "live_folders/contacts", 3751b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov LIVE_FOLDERS_CONTACTS); 3761b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "live_folders/contacts/*", 3771b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov LIVE_FOLDERS_CONTACTS_GROUP_NAME); 3781b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "live_folders/contacts_with_phones", 3791b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov LIVE_FOLDERS_CONTACTS_WITH_PHONES); 3801b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "live_folders/favorites", 3811b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov LIVE_FOLDERS_CONTACTS_FAVORITES); 3821b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov 38319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov // Private API 384a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "data_with_presence", DATA_WITH_PRESENCE); 38519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov } 38619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov 38719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov static { 388038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana sCountProjectionMap = new HashMap<String, String>(); 389038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana sCountProjectionMap.put(BaseColumns._COUNT, "COUNT(*)"); 390e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 3914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap = new HashMap<String, String>(); 3924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts._ID, Contacts._ID); 3934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME); 3944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.LAST_TIME_CONTACTED, Contacts.LAST_TIME_CONTACTED); 3954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.TIMES_CONTACTED, Contacts.TIMES_CONTACTED); 3964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.STARRED, Contacts.STARRED); 3974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP); 3984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID); 3994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.CUSTOM_RINGTONE, Contacts.CUSTOM_RINGTONE); 400f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov sContactsProjectionMap.put(Contacts.HAS_PHONE_NUMBER, Contacts.HAS_PHONE_NUMBER); 4014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.SEND_TO_VOICEMAIL, Contacts.SEND_TO_VOICEMAIL); 4025870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sContactsProjectionMap.put(Contacts.LOOKUP_KEY, Contacts.LOOKUP_KEY); 4034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 404ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov sContactsWithPresenceProjectionMap = new HashMap<String, String>(); 405ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov sContactsWithPresenceProjectionMap.putAll(sContactsProjectionMap); 406ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov sContactsWithPresenceProjectionMap.put(Contacts.PRESENCE_STATUS, 407e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov Presence.PRESENCE_STATUS + " AS " + Contacts.PRESENCE_STATUS); 408ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov sContactsWithPresenceProjectionMap.put(Contacts.PRESENCE_CUSTOM_STATUS, 409ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov Presence.PRESENCE_CUSTOM_STATUS + " AS " + Contacts.PRESENCE_CUSTOM_STATUS); 4104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 4114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap = new HashMap<String, String>(); 4124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts._ID, RawContacts._ID); 4134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID); 4144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_NAME); 4154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_TYPE); 4164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SOURCE_ID, RawContacts.SOURCE_ID); 4174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.VERSION, RawContacts.VERSION); 4184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.DIRTY, RawContacts.DIRTY); 4194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.DELETED, RawContacts.DELETED); 4204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.TIMES_CONTACTED, RawContacts.TIMES_CONTACTED); 4214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.LAST_TIME_CONTACTED, 4224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContacts.LAST_TIME_CONTACTED); 4234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.CUSTOM_RINGTONE, RawContacts.CUSTOM_RINGTONE); 4244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SEND_TO_VOICEMAIL, RawContacts.SEND_TO_VOICEMAIL); 4254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.STARRED, RawContacts.STARRED); 4264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE); 4274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SYNC1, RawContacts.SYNC1); 4284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SYNC2, RawContacts.SYNC2); 4294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SYNC3, RawContacts.SYNC3); 4304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SYNC4, RawContacts.SYNC4); 4312815f58f72f109790585931f601a63ddc02536a5Evan Millar 4324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap = new HashMap<String, String>(); 4334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data._ID, Data._ID); 4344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.RAW_CONTACT_ID, Data.RAW_CONTACT_ID); 4354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA_VERSION, Data.DATA_VERSION); 4364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.IS_PRIMARY, Data.IS_PRIMARY); 4374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.IS_SUPER_PRIMARY, Data.IS_SUPER_PRIMARY); 4384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.RES_PACKAGE, Data.RES_PACKAGE); 4394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.MIMETYPE, Data.MIMETYPE); 4404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA1, Data.DATA1); 4414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA2, Data.DATA2); 4424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA3, Data.DATA3); 4434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA4, Data.DATA4); 4444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA5, Data.DATA5); 4454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA6, Data.DATA6); 4464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA7, Data.DATA7); 4474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA8, Data.DATA8); 4484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA9, Data.DATA9); 4494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA10, Data.DATA10); 4504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA11, Data.DATA11); 4514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA12, Data.DATA12); 4524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA13, Data.DATA13); 4534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA14, Data.DATA14); 4544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA15, Data.DATA15); 4554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.SYNC1, Data.SYNC1); 4564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.SYNC2, Data.SYNC2); 4574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.SYNC3, Data.SYNC3); 4584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.SYNC4, Data.SYNC4); 4594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID); 4604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_NAME); 4614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_TYPE); 4624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.SOURCE_ID, RawContacts.SOURCE_ID); 4634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.VERSION, RawContacts.VERSION); 4644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.DIRTY, RawContacts.DIRTY); 4654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME); 4664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.CUSTOM_RINGTONE, Contacts.CUSTOM_RINGTONE); 4674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.SEND_TO_VOICEMAIL, Contacts.SEND_TO_VOICEMAIL); 4684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.LAST_TIME_CONTACTED, Contacts.LAST_TIME_CONTACTED); 4694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.TIMES_CONTACTED, Contacts.TIMES_CONTACTED); 4704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.STARRED, Contacts.STARRED); 4714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID); 4724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(GroupMembership.GROUP_SOURCE_ID, GroupMembership.GROUP_SOURCE_ID); 473a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 474e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap = new HashMap<String, String>(); 475e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup._ID, 476e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov ContactsColumns.CONCRETE_ID + " AS " + PhoneLookup._ID); 477e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.DISPLAY_NAME, 478e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov ContactsColumns.CONCRETE_DISPLAY_NAME + " AS " + PhoneLookup.DISPLAY_NAME); 479e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.LAST_TIME_CONTACTED, 480e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 481e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov + " AS " + PhoneLookup.LAST_TIME_CONTACTED); 482e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.TIMES_CONTACTED, 483e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov ContactsColumns.CONCRETE_TIMES_CONTACTED + " AS " + PhoneLookup.TIMES_CONTACTED); 484e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.STARRED, 485e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov ContactsColumns.CONCRETE_STARRED + " AS " + PhoneLookup.STARRED); 486e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.IN_VISIBLE_GROUP, 487e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + " AS " + PhoneLookup.IN_VISIBLE_GROUP); 488e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.PHOTO_ID, 489e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov Contacts.PHOTO_ID + " AS " + PhoneLookup.PHOTO_ID); 490e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.CUSTOM_RINGTONE, 491e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE + " AS " + PhoneLookup.CUSTOM_RINGTONE); 492e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.HAS_PHONE_NUMBER, 493e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov Contacts.HAS_PHONE_NUMBER + " AS " + PhoneLookup.HAS_PHONE_NUMBER); 494e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.SEND_TO_VOICEMAIL, 495e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 496e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov + " AS " + PhoneLookup.SEND_TO_VOICEMAIL); 497e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.NUMBER, 498e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov Phone.NUMBER + " AS " + PhoneLookup.NUMBER); 499e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.TYPE, 500e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov Phone.TYPE + " AS " + PhoneLookup.TYPE); 501e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sPhoneLookupProjectionMap.put(PhoneLookup.LABEL, 502e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov Phone.LABEL + " AS " + PhoneLookup.LABEL); 5039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 504e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov HashMap<String, String> columns; 5057e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 506ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Groups projection map 507ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns = new HashMap<String, String>(); 508ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns.put(Groups._ID, "groups._id AS _id"); 509035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana columns.put(Groups.ACCOUNT_NAME, Groups.ACCOUNT_NAME); 510035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana columns.put(Groups.ACCOUNT_TYPE, Groups.ACCOUNT_TYPE); 5119261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana columns.put(Groups.SOURCE_ID, Groups.SOURCE_ID); 5129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana columns.put(Groups.DIRTY, Groups.DIRTY); 5139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana columns.put(Groups.VERSION, Groups.VERSION); 51467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(Groups.RES_PACKAGE, PackagesColumns.PACKAGE + " AS " + Groups.RES_PACKAGE); 515ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns.put(Groups.TITLE, Groups.TITLE); 51667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(Groups.TITLE_RES, Groups.TITLE_RES); 517ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns.put(Groups.GROUP_VISIBLE, Groups.GROUP_VISIBLE); 5183cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.SYSTEM_ID, Groups.SYSTEM_ID); 51994021b213e4db367f60b30fcbfe9019e28571784Fred Quintana columns.put(Groups.DELETED, Groups.DELETED); 5203cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.NOTES, Groups.NOTES); 52138446bf47c5ee2080df69f5fc8a33ad2fa3e61b5Jeff Sharkey columns.put(Groups.SHOULD_SYNC, Groups.SHOULD_SYNC); 5223cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.SYNC1, Tables.GROUPS + "." + Groups.SYNC1 + " AS " + Groups.SYNC1); 5233cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.SYNC2, Tables.GROUPS + "." + Groups.SYNC2 + " AS " + Groups.SYNC2); 5243cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.SYNC3, Tables.GROUPS + "." + Groups.SYNC3 + " AS " + Groups.SYNC3); 5253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.SYNC4, Tables.GROUPS + "." + Groups.SYNC4 + " AS " + Groups.SYNC4); 526ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey sGroupsProjectionMap = columns; 527ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 5286cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov // RawContacts and groups projection map 529ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns = new HashMap<String, String>(); 530ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns.putAll(sGroupsProjectionMap); 531d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Groups.SUMMARY_COUNT, "(SELECT COUNT(DISTINCT " + ContactsColumns.CONCRETE_ID 532d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + ") FROM " + Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS + " WHERE " 533ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP 534ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + ") AS " + Groups.SUMMARY_COUNT); 535ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns.put(Groups.SUMMARY_WITH_PHONES, "(SELECT COUNT(DISTINCT " 536d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + ContactsColumns.CONCRETE_ID + ") FROM " 537d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS + " WHERE " 538ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP 539f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov + " AND " + Contacts.HAS_PHONE_NUMBER + ") AS " + Groups.SUMMARY_WITH_PHONES); 540ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey sGroupsSummaryProjectionMap = columns; 541ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 542b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov // Aggregate exception projection map 543b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov columns = new HashMap<String, String>(); 544b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov columns.put(AggregationExceptionColumns._ID, Tables.AGGREGATION_EXCEPTIONS + "._id AS _id"); 545b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov columns.put(AggregationExceptions.TYPE, AggregationExceptions.TYPE); 546d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(AggregationExceptions.CONTACT_ID, 547d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov "raw_contacts1." + RawContacts.CONTACT_ID 548d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + " AS " + AggregationExceptions.CONTACT_ID); 5495ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov columns.put(AggregationExceptions.RAW_CONTACT_ID, AggregationExceptionColumns.RAW_CONTACT_ID2); 550b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov sAggregationExceptionsProjectionMap = columns; 551b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 552eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey // Settings projection map 553eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey columns = new HashMap<String, String>(); 554eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey columns.put(Settings.ACCOUNT_NAME, Settings.ACCOUNT_NAME); 555eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey columns.put(Settings.ACCOUNT_TYPE, Settings.ACCOUNT_TYPE); 556eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey columns.put(Settings.UNGROUPED_VISIBLE, Settings.UNGROUPED_VISIBLE); 557eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey columns.put(Settings.SHOULD_SYNC, Settings.SHOULD_SYNC); 55868936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey columns.put(Settings.UNGROUPED_COUNT, "(SELECT COUNT(*) FROM (SELECT 1 FROM " 55968936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey + Tables.SETTINGS_JOIN_RAW_CONTACTS_DATA_MIMETYPES_CONTACTS + " GROUP BY " 56068936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey + Clauses.GROUP_BY_ACCOUNT_CONTACT_ID + " HAVING " + Clauses.HAVING_NO_GROUPS 56168936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey + ")) AS " + Settings.UNGROUPED_COUNT); 56268936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey columns.put(Settings.UNGROUPED_WITH_PHONES, "(SELECT COUNT(*) FROM (SELECT 1 FROM " 563e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Tables.SETTINGS_JOIN_RAW_CONTACTS_DATA_MIMETYPES_CONTACTS + " WHERE " 56468936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey + Contacts.HAS_PHONE_NUMBER + " GROUP BY " + Clauses.GROUP_BY_ACCOUNT_CONTACT_ID 56568936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey + " HAVING " + Clauses.HAVING_NO_GROUPS + ")) AS " 56668936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey + Settings.UNGROUPED_WITH_PHONES); 567eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey sSettingsProjectionMap = columns; 568eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 569373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns = new HashMap<String, String>(); 570373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence._ID, Presence._ID); 5714dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov columns.put(PresenceColumns.RAW_CONTACT_ID, PresenceColumns.RAW_CONTACT_ID); 572373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.DATA_ID, Presence.DATA_ID); 573373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.IM_ACCOUNT, Presence.IM_ACCOUNT); 574373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.IM_HANDLE, Presence.IM_HANDLE); 5754dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov columns.put(Presence.PROTOCOL, Presence.PROTOCOL); 5764dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov columns.put(Presence.CUSTOM_PROTOCOL, Presence.CUSTOM_PROTOCOL); 577373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.PRESENCE_STATUS, Presence.PRESENCE_STATUS); 578373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.PRESENCE_CUSTOM_STATUS, Presence.PRESENCE_CUSTOM_STATUS); 579373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov sPresenceProjectionMap = columns; 580373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov 581a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov sDataWithPresenceProjectionMap = new HashMap<String, String>(); 582a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov sDataWithPresenceProjectionMap.putAll(sDataProjectionMap); 583a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov sDataWithPresenceProjectionMap.put(Presence.PRESENCE_STATUS, 584e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov Presence.PRESENCE_STATUS); 585a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov sDataWithPresenceProjectionMap.put(Presence.PRESENCE_CUSTOM_STATUS, 586e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov Presence.PRESENCE_CUSTOM_STATUS); 58719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov 5881b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov // Live folder projection 5891b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov sLiveFoldersProjectionMap = new HashMap<String, String>(); 5901b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov sLiveFoldersProjectionMap.put(LiveFolders._ID, 5911b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov Contacts._ID + " AS " + LiveFolders._ID); 5921b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov sLiveFoldersProjectionMap.put(LiveFolders.NAME, 5931b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov Contacts.DISPLAY_NAME + " AS " + LiveFolders.NAME); 5941b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov 5951b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov // TODO: Put contact photo back when we have a way to display a default icon 5961b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov // for contacts without a photo 5971b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov // sLiveFoldersProjectionMap.put(LiveFolders.ICON_BITMAP, 5981b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov // Photos.DATA + " AS " + LiveFolders.ICON_BITMAP); 5991b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov 6004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsInGroupSelect = Contacts._ID + " IN " 6014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + "(SELECT " + RawContacts.CONTACT_ID 6024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS 6034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + RawContactsColumns.CONCRETE_ID + " IN " 6044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + "(SELECT " + DataColumns.CONCRETE_RAW_CONTACT_ID 6054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.DATA_JOIN_MIMETYPES 6064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + Data.MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 6074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + "' AND " + GroupMembership.GROUP_ROW_ID + "=" 6084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + "(SELECT " + Tables.GROUPS + "." + Groups._ID 6094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.GROUPS 6104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + Groups.TITLE + "=?)))"; 6114f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 6124f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 6133cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** 6143cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * Handles inserts and update for a specific Data type. 6153cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov */ 6163cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private abstract class DataRowHandler { 6173cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 6183cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov protected final String mMimetype; 619653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov protected long mMimetypeId; 6203cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 6213cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public DataRowHandler(String mimetype) { 6223cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mMimetype = mimetype; 6233cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 6243cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 625653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov protected long getMimeTypeId() { 626653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov if (mMimetypeId == 0) { 627653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov mMimetypeId = mOpenHelper.getMimeTypeId(mMimetype); 628653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 629653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov return mMimetypeId; 630653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 631653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 6323cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** 6333cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * Inserts a row into the {@link Data} table. 6343cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov */ 6355ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 636e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov final long dataId = db.insert(Tables.DATA, null, values); 637e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 638e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov Integer primary = values.getAsInteger(Data.IS_PRIMARY); 639e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov if (primary != null && primary != 0) { 640653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov setIsPrimary(rawContactId, dataId, getMimeTypeId()); 641e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 642e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 643e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov return dataId; 6443cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 6453cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 6463cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** 6473cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * Validates data and updates a {@link Data} row using the cursor, which contains 6483cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * the current data. 6493cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov */ 650653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor c, 651653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov boolean markRawContactAsDirty) { 65214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataUpdateQuery._ID); 65314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 654653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 655653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov if (values.containsKey(Data.IS_SUPER_PRIMARY)) { 656653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov long mimeTypeId = getMimeTypeId(); 657653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov setIsSuperPrimary(rawContactId, dataId, mimeTypeId); 658653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov setIsPrimary(rawContactId, dataId, mimeTypeId); 659653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 660653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov // Now that we've taken care of setting these, remove them from "values". 661653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov values.remove(Data.IS_SUPER_PRIMARY); 662653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov values.remove(Data.IS_PRIMARY); 663653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } else if (values.containsKey(Data.IS_PRIMARY)) { 664653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov setIsPrimary(rawContactId, dataId, getMimeTypeId()); 665653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 666653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov // Now that we've taken care of setting this, remove it from "values". 667653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov values.remove(Data.IS_PRIMARY); 668653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 669653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 670653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov if (values.size() > 0) { 671653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov mDb.update(Tables.DATA, values, Data._ID + " = " + dataId, null); 672653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 673653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 674653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov if (markRawContactAsDirty) { 675653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov setRawContactDirty(rawContactId); 676653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 6773cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 6783cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 6793cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public int delete(SQLiteDatabase db, Cursor c) { 68014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataDeleteQuery._ID); 68114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 68214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov boolean primary = c.getInt(DataDeleteQuery.IS_PRIMARY) != 0; 6833cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov int count = db.delete(Tables.DATA, Data._ID + "=" + dataId, null); 6843cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (count != 0 && primary) { 6855ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov fixPrimary(db, rawContactId); 6863cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 6873cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov return count; 6883cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 6893cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 6905ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private void fixPrimary(SQLiteDatabase db, long rawContactId) { 6915ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long newPrimaryId = findNewPrimaryDataId(db, rawContactId); 6923cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (newPrimaryId != -1) { 69314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov setIsPrimary(rawContactId, newPrimaryId, getMimeTypeId()); 6943cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 6953cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 6963cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 6975ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov protected long findNewPrimaryDataId(SQLiteDatabase db, long rawContactId) { 698e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov long primaryId = -1; 699e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov int primaryType = -1; 7005ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Cursor c = queryData(db, rawContactId); 7013cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov try { 702e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov while (c.moveToNext()) { 70314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataDeleteQuery._ID); 70414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov int type = c.getInt(DataDeleteQuery.DATA2); 705e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov if (primaryType == -1 || getTypeRank(type) < getTypeRank(primaryType)) { 706e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov primaryId = dataId; 707e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov primaryType = type; 708e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 7093cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7103cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } finally { 7113cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov c.close(); 7123cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 713e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov return primaryId; 714e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 715e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 716e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov /** 717e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov * Returns the rank of a specific record type to be used in determining the primary 718e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov * row. Lower number represents higher priority. 719e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov */ 720e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov protected int getTypeRank(int type) { 721e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov return 0; 7223cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7233cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7245ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov protected Cursor queryData(SQLiteDatabase db, long rawContactId) { 72514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov return db.query(DataDeleteQuery.TABLE, DataDeleteQuery.CONCRETE_COLUMNS, 72614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov Data.RAW_CONTACT_ID + "=" + rawContactId + 72714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov " AND " + MimetypesColumns.MIMETYPE + "='" + mMimetype + "'", 7283cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov null, null, null, null); 7293cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7303cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 73125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov protected void fixRawContactDisplayName(SQLiteDatabase db, long rawContactId) { 7323cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String bestDisplayName = null; 73325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov int bestDisplayNameSource = DisplayNameSources.UNDEFINED; 73425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov 73567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Cursor c = db.query(DisplayNameQuery.TABLE, DisplayNameQuery.COLUMNS, 7365ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Data.RAW_CONTACT_ID + "=" + rawContactId, null, null, null, null); 7373cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov try { 7383cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov while (c.moveToNext()) { 7393cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String mimeType = c.getString(DisplayNameQuery.MIMETYPE); 7403cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov boolean primary; 7413cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String name; 7423cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7433cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) { 7443cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov name = c.getString(DisplayNameQuery.DISPLAY_NAME); 7453cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov primary = true; 7463cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else { 7473cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov name = c.getString(DisplayNameQuery.DATA2); 7483cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov primary = (c.getInt(DisplayNameQuery.IS_PRIMARY) != 0); 7493cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7503cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7513cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (primary && name != null) { 75225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov Integer source = sDisplayNameSources.get(mimeType); 75325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov if (source != null && source > bestDisplayNameSource) { 75425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov bestDisplayNameSource = source; 7553cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov bestDisplayName = name; 7563cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7573cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7583cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7593cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7603cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } finally { 7613cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov c.close(); 7623cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7633cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 76425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov setDisplayName(rawContactId, bestDisplayName, bestDisplayNameSource); 765285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov if (!isNewRawContact(rawContactId)) { 766285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov mContactAggregator.updateDisplayName(db, rawContactId); 767285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov } 7683cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 769a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov 770a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov public boolean isAggregationRequired() { 771a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov return true; 772a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 7733cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7743cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7753cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public class CustomDataRowHandler extends DataRowHandler { 7763cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7773cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public CustomDataRowHandler(String mimetype) { 7783cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov super(mimetype); 7793cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7803cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7813cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7823cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public class StructuredNameRowHandler extends DataRowHandler { 7833cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7843cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private final NameSplitter mNameSplitter; 7853cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7863cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public StructuredNameRowHandler(NameSplitter nameSplitter) { 7873cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov super(StructuredName.CONTENT_ITEM_TYPE); 7883cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mNameSplitter = nameSplitter; 7893cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7903cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7913cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 7925ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 7933cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov fixStructuredNameComponents(values); 79414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 79514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = super.insert(db, rawContactId, values); 79614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 79714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov String givenName = values.getAsString(StructuredName.GIVEN_NAME); 79814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov String familyName = values.getAsString(StructuredName.FAMILY_NAME); 79914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.insertNameLookupForStructuredName(rawContactId, dataId, givenName, 80014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov familyName); 80125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 80214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov return dataId; 80314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 80414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 80514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov @Override 80614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor c, 80714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov boolean markRawContactAsDirty) { 808cabac02a2416b495e030654accffcbb5ae526678Dmitri Plotnikov 809cabac02a2416b495e030654accffcbb5ae526678Dmitri Plotnikov fixStructuredNameComponents(values); 810cabac02a2416b495e030654accffcbb5ae526678Dmitri Plotnikov 81114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataUpdateQuery._ID); 81214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 81314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 81414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov super.update(db, values, c, markRawContactAsDirty); 81514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 81614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov boolean hasGivenName = values.containsKey(StructuredName.GIVEN_NAME); 81714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov boolean hasFamilyName = values.containsKey(StructuredName.FAMILY_NAME); 81814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov if (hasGivenName || hasFamilyName) { 81914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov String givenName; 82014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov String familyName;// = values.getAsString(StructuredName.FAMILY_NAME); 82114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov if (hasGivenName) { 82214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov givenName = values.getAsString(StructuredName.GIVEN_NAME); 82314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } else { 82414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 82514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov // TODO compiled statement 82614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov givenName = DatabaseUtils.stringForQuery(db, 82714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov "SELECT " + StructuredName.GIVEN_NAME + 82814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov " FROM " + Tables.DATA + 82914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov " WHERE " + Data._ID + "=" + dataId, null); 83014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 83114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov if (hasFamilyName) { 83214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov familyName = values.getAsString(StructuredName.FAMILY_NAME); 83314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } else { 83414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 83514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov // TODO compiled statement 83614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov familyName = DatabaseUtils.stringForQuery(db, 83714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov "SELECT " + StructuredName.FAMILY_NAME + 83814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov " FROM " + Tables.DATA + 83914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov " WHERE " + Data._ID + "=" + dataId, null); 84014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 84114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 84214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.deleteNameLookup(dataId); 84314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.insertNameLookupForStructuredName(rawContactId, dataId, givenName, 84414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov familyName); 84514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 84625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 84714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 84814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 84914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov @Override 85014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public int delete(SQLiteDatabase db, Cursor c) { 85114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataDeleteQuery._ID); 85214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 85314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 85414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov int count = super.delete(db, c); 85514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 85614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.deleteNameLookup(dataId); 85725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 85814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov return count; 8593cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8603cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8613cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** 8623cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * Parses the supplied display name, but only if the incoming values do not already contain 8633cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * structured name parts. Also, if the display name is not provided, generate one by 8643cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * concatenating first name and last name 8653cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * 8663cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * TODO see if the order of first and last names needs to be conditionally reversed for 8673cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * some locales, e.g. China. 8683cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov */ 8693cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private void fixStructuredNameComponents(ContentValues values) { 8703cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String fullName = values.getAsString(StructuredName.DISPLAY_NAME); 8713cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (!TextUtils.isEmpty(fullName) 8723cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov && TextUtils.isEmpty(values.getAsString(StructuredName.PREFIX)) 8733cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov && TextUtils.isEmpty(values.getAsString(StructuredName.GIVEN_NAME)) 8743cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov && TextUtils.isEmpty(values.getAsString(StructuredName.MIDDLE_NAME)) 8753cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov && TextUtils.isEmpty(values.getAsString(StructuredName.FAMILY_NAME)) 8763cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov && TextUtils.isEmpty(values.getAsString(StructuredName.SUFFIX))) { 8773cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov NameSplitter.Name name = new NameSplitter.Name(); 8783cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mNameSplitter.split(name, fullName); 8793cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8803cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.PREFIX, name.getPrefix()); 8813cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.GIVEN_NAME, name.getGivenNames()); 8823cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.MIDDLE_NAME, name.getMiddleName()); 8833cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.FAMILY_NAME, name.getFamilyName()); 8843cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.SUFFIX, name.getSuffix()); 8853cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8863cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8873cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (TextUtils.isEmpty(fullName)) { 8883cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String givenName = values.getAsString(StructuredName.GIVEN_NAME); 8893cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String familyName = values.getAsString(StructuredName.FAMILY_NAME); 8903cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (TextUtils.isEmpty(givenName)) { 8913cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov fullName = familyName; 8923cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else if (TextUtils.isEmpty(familyName)) { 8933cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov fullName = givenName; 8943cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else { 8953cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov fullName = givenName + " " + familyName; 8963cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8973cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8983cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (!TextUtils.isEmpty(fullName)) { 8993cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.DISPLAY_NAME, fullName); 9003cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9013cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9023cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9033cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9043cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9053cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public class CommonDataRowHandler extends DataRowHandler { 9063cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9073cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private final String mTypeColumn; 9083cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private final String mLabelColumn; 9093cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9103cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public CommonDataRowHandler(String mimetype, String typeColumn, String labelColumn) { 9113cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov super(mimetype); 9123cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mTypeColumn = typeColumn; 9133cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mLabelColumn = labelColumn; 9143cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9153cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9163cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 9175ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 9183cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov int type; 9193cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String label; 9203cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (values.containsKey(mTypeColumn)) { 9213cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov type = values.getAsInteger(mTypeColumn); 9223cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else { 9233cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov type = BaseTypes.TYPE_CUSTOM; 9243cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9253cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (values.containsKey(mLabelColumn)) { 9263cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov label = values.getAsString(mLabelColumn); 9273cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else { 9283cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov label = null; 9293cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9303cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9313cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (type != BaseTypes.TYPE_CUSTOM && label != null) { 9327a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana throw new IllegalArgumentException(mLabelColumn + " value can only be specified with " 9333cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov + mTypeColumn + "=" + BaseTypes.TYPE_CUSTOM + "(custom)"); 9343cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9353cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9363cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (type == BaseTypes.TYPE_CUSTOM && label == null) { 9377a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana throw new IllegalArgumentException(mLabelColumn + " value must be specified when " 9383cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov + mTypeColumn + "=" + BaseTypes.TYPE_CUSTOM + "(custom)"); 9393cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9403cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9415ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov return super.insert(db, rawContactId, values); 9423cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9433cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9443cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9453cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public class OrganizationDataRowHandler extends CommonDataRowHandler { 9463cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9473cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public OrganizationDataRowHandler() { 9483cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov super(Organization.CONTENT_ITEM_TYPE, Organization.TYPE, Organization.LABEL); 9493cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9503cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9513cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 9525ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 9535ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long id = super.insert(db, rawContactId, values); 95425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 9553cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov return id; 9563cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9573cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9583cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 95914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor c, 96014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov boolean markRawContactAsDirty) { 96114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 96214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 96314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov super.update(db, values, c, markRawContactAsDirty); 96414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 96525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 96614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 96714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 96814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov @Override 96914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public int delete(SQLiteDatabase db, Cursor c) { 97014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 97114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 97214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov int count = super.delete(db, c); 97325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 97414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov return count; 97514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 97614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 97714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov @Override 9783cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov protected int getTypeRank(int type) { 9793cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov switch (type) { 9803cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Organization.TYPE_WORK: return 0; 9813cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Organization.TYPE_CUSTOM: return 1; 9823cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Organization.TYPE_OTHER: return 2; 9833cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov default: return 1000; 9843cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9853cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 986a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov 987a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov @Override 988a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov public boolean isAggregationRequired() { 989a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov return false; 990a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 9913cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9923cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 993e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public class EmailDataRowHandler extends CommonDataRowHandler { 994e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 995e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public EmailDataRowHandler() { 996e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov super(Email.CONTENT_ITEM_TYPE, Email.TYPE, Email.LABEL); 997e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 998e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 999e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov @Override 10005ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 100114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov String address = values.getAsString(Email.DATA); 100214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 100314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = super.insert(db, rawContactId, values); 100414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 100525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 100614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.insertNameLookupForEmail(rawContactId, dataId, address); 100714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov return dataId; 100814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 100914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 101014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov @Override 101114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor c, 101214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov boolean markRawContactAsDirty) { 101314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataUpdateQuery._ID); 101414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 101514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov String address = values.getAsString(Email.DATA); 101614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 101714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov super.update(db, values, c, markRawContactAsDirty); 101814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 101914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.deleteNameLookup(dataId); 102014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.insertNameLookupForEmail(rawContactId, dataId, address); 102125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 102214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 102314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 102414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov @Override 102514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public int delete(SQLiteDatabase db, Cursor c) { 102614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataDeleteQuery._ID); 102714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 102814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 102914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov int count = super.delete(db, c); 103014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 103114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.deleteNameLookup(dataId); 103225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 103314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov return count; 1034e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 1035e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 1036e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov @Override 1037e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov protected int getTypeRank(int type) { 1038e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov switch (type) { 1039e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov case Email.TYPE_HOME: return 0; 1040e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov case Email.TYPE_WORK: return 1; 1041e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov case Email.TYPE_CUSTOM: return 2; 1042e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov case Email.TYPE_OTHER: return 3; 1043e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov default: return 1000; 1044e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 1045e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 1046e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 1047e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 104814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public class NicknameDataRowHandler extends CommonDataRowHandler { 104914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 105014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public NicknameDataRowHandler() { 105114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov super(Nickname.CONTENT_ITEM_TYPE, Nickname.TYPE, Nickname.LABEL); 105214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 105314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 105414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov @Override 105514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 105614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov String nickname = values.getAsString(Nickname.NAME); 105714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 105814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = super.insert(db, rawContactId, values); 105914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 106025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 106114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.insertNameLookupForNickname(rawContactId, dataId, nickname); 106214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov return dataId; 106314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 106414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 106514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov @Override 106614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor c, 106714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov boolean markRawContactAsDirty) { 106814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataUpdateQuery._ID); 106914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 107014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov String nickname = values.getAsString(Nickname.NAME); 107114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 107214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov super.update(db, values, c, markRawContactAsDirty); 107314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 107414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.deleteNameLookup(dataId); 107514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.insertNameLookupForNickname(rawContactId, dataId, nickname); 107625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 107714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 107814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 107914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov @Override 108014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public int delete(SQLiteDatabase db, Cursor c) { 108114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataDeleteQuery._ID); 108214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 108314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 108414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov int count = super.delete(db, c); 108514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 108614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mOpenHelper.deleteNameLookup(dataId); 108725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 108814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov return count; 108914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 109014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 109114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 10923cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public class PhoneDataRowHandler extends CommonDataRowHandler { 10933cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 10943cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public PhoneDataRowHandler() { 10953cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov super(Phone.CONTENT_ITEM_TYPE, Phone.TYPE, Phone.LABEL); 10963cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 10973cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 10983cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 10995ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 11000b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov long dataId; 11010b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov if (values.containsKey(Phone.NUMBER)) { 11020b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov String number = values.getAsString(Phone.NUMBER); 11030b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov String normalizedNumber = computeNormalizedNumber(number, values); 1104653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 11050b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov dataId = super.insert(db, rawContactId, values); 1106653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 11070b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov updatePhoneLookup(db, rawContactId, dataId, number, normalizedNumber); 1108285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov mContactAggregator.updateHasPhoneNumber(db, rawContactId); 110925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 11100b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov } else { 11110b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov dataId = super.insert(db, rawContactId, values); 11120b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov } 1113653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov return dataId; 1114653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1115653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1116653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov @Override 1117653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor c, 1118653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov boolean markRawContactAsDirty) { 111914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataUpdateQuery._ID); 112014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 11210b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov if (values.containsKey(Phone.NUMBER)) { 11220b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov String number = values.getAsString(Phone.NUMBER); 11230b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov String normalizedNumber = computeNormalizedNumber(number, values); 1124653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 11250b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov super.update(db, values, c, markRawContactAsDirty); 1126653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 11270b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov updatePhoneLookup(db, rawContactId, dataId, number, normalizedNumber); 1128285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov mContactAggregator.updateHasPhoneNumber(db, rawContactId); 112925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 11300b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov } else { 11310b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov super.update(db, values, c, markRawContactAsDirty); 11320b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov } 113314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov } 113414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 113514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov @Override 113614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public int delete(SQLiteDatabase db, Cursor c) { 113714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long dataId = c.getLong(DataDeleteQuery._ID); 113814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 113914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 114014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov int count = super.delete(db, c); 114114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 114214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov updatePhoneLookup(db, rawContactId, dataId, null, null); 1143285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov mContactAggregator.updateHasPhoneNumber(db, rawContactId); 114425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov fixRawContactDisplayName(db, rawContactId); 114514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov return count; 1146653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1147653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1148653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov private String computeNormalizedNumber(String number, ContentValues values) { 1149e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov String normalizedNumber = null; 1150e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov if (number != null) { 1151e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov normalizedNumber = PhoneNumberUtils.getStrippedReversed(number); 1152e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 1153653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov values.put(PhoneColumns.NORMALIZED_NUMBER, normalizedNumber); 1154653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov return normalizedNumber; 1155653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1156e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 1157653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov private void updatePhoneLookup(SQLiteDatabase db, long rawContactId, long dataId, 1158653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov String number, String normalizedNumber) { 1159e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov if (number != null) { 1160653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov ContentValues phoneValues = new ContentValues(); 11615ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactId); 1162653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.DATA_ID, dataId); 1163e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber); 1164653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov db.replace(Tables.PHONE_LOOKUP, null, phoneValues); 1165653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } else { 1166653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov db.delete(Tables.PHONE_LOOKUP, PhoneLookupColumns.DATA_ID + "=" + dataId, null); 1167e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 11683cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 11693cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 11703cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 11713cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov protected int getTypeRank(int type) { 11723cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov switch (type) { 11733cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_MOBILE: return 0; 11743cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_WORK: return 1; 11753cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_HOME: return 2; 11763cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_PAGER: return 3; 11773cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_CUSTOM: return 4; 11783cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_OTHER: return 5; 11793cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_FAX_WORK: return 6; 11803cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_FAX_HOME: return 7; 11813cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov default: return 1000; 11823cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 11833cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 11843cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 11853cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 1186653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov public class GroupMembershipRowHandler extends DataRowHandler { 1187653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1188653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov public GroupMembershipRowHandler() { 1189653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov super(GroupMembership.CONTENT_ITEM_TYPE); 1190653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1191653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1192653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov @Override 1193653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 1194653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov resolveGroupSourceIdInValues(rawContactId, db, values, true); 1195653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov return super.insert(db, rawContactId, values); 1196653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1197653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1198653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov @Override 1199653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor c, 1200653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov boolean markRawContactAsDirty) { 120114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 1202653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov resolveGroupSourceIdInValues(rawContactId, db, values, false); 1203653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov super.update(db, values, c, markRawContactAsDirty); 1204653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1205653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1206653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov private void resolveGroupSourceIdInValues(long rawContactId, SQLiteDatabase db, 1207653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov ContentValues values, boolean isInsert) { 1208653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov boolean containsGroupSourceId = values.containsKey(GroupMembership.GROUP_SOURCE_ID); 1209653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov boolean containsGroupId = values.containsKey(GroupMembership.GROUP_ROW_ID); 1210653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov if (containsGroupSourceId && containsGroupId) { 1211653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov throw new IllegalArgumentException( 1212653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov "you are not allowed to set both the GroupMembership.GROUP_SOURCE_ID " 1213653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov + "and GroupMembership.GROUP_ROW_ID"); 1214653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1215653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1216653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov if (!containsGroupSourceId && !containsGroupId) { 1217653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov if (isInsert) { 1218653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov throw new IllegalArgumentException( 1219653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov "you must set exactly one of GroupMembership.GROUP_SOURCE_ID " 1220653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov + "and GroupMembership.GROUP_ROW_ID"); 1221653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } else { 1222653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov return; 1223653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1224653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1225653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1226653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov if (containsGroupSourceId) { 1227653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov final String sourceId = values.getAsString(GroupMembership.GROUP_SOURCE_ID); 1228653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov final long groupId = getOrMakeGroup(db, rawContactId, sourceId); 1229653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov values.remove(GroupMembership.GROUP_SOURCE_ID); 1230653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov values.put(GroupMembership.GROUP_ROW_ID, groupId); 1231653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1232653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1233a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov 1234a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov @Override 1235a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov public boolean isAggregationRequired() { 1236a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov return false; 1237a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 1238653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } 1239653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1240a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov public class PhotoDataRowHandler extends DataRowHandler { 1241a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov 1242a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov public PhotoDataRowHandler() { 1243a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov super(Photo.CONTENT_ITEM_TYPE); 1244a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 1245a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov 1246a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov @Override 1247a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 1248a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov long dataId = super.insert(db, rawContactId, values); 1249285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov if (!isNewRawContact(rawContactId)) { 1250285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov mContactAggregator.updatePhotoId(db, rawContactId); 1251285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov } 1252a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov return dataId; 1253a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 1254a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov 1255a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov @Override 1256a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor c, 1257a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov boolean markRawContactAsDirty) { 1258a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 1259a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov super.update(db, values, c, markRawContactAsDirty); 1260a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov mContactAggregator.updatePhotoId(db, rawContactId); 1261a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 1262a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov 1263a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov @Override 1264a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov public int delete(SQLiteDatabase db, Cursor c) { 1265a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 1266a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov int count = super.delete(db, c); 1267a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov mContactAggregator.updatePhotoId(db, rawContactId); 1268a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov return count; 1269a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 1270a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov 1271a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov @Override 1272a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov public boolean isAggregationRequired() { 1273a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov return false; 1274a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 1275a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 1276a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov 1277a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov 12783cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private HashMap<String, DataRowHandler> mDataRowHandlers; 127953056d49d8adf5d1fe2d18cb60c3c26f281e7a6cDmitri Plotnikov private final ContactAggregationScheduler mAggregationScheduler; 12804f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton private OpenHelper mOpenHelper; 128131b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 1282a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov private ContactAggregator mContactAggregator; 12834097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov private NameSplitter mNameSplitter; 1284f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov private LegacyApiSupport mLegacyApiSupport; 1285a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov private GlobalSearchSupport mGlobalSearchSupport; 1286a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 128720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov private ContentValues mValues = new ContentValues(); 128820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 1289ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov private volatile CountDownLatch mAccessLatch; 129073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private boolean mImportMode; 129173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 1292de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov private boolean mScheduleAggregation; 1293285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov private ArrayList<Long> mInsertedRawContacts = new ArrayList<Long>(); 1294de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov 1295a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public ContactsProvider2() { 129653056d49d8adf5d1fe2d18cb60c3c26f281e7a6cDmitri Plotnikov this(new ContactAggregationScheduler()); 1297a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 1298a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1299a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 1300a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov * Constructor for testing. 1301a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov */ 130253056d49d8adf5d1fe2d18cb60c3c26f281e7a6cDmitri Plotnikov /* package */ ContactsProvider2(ContactAggregationScheduler scheduler) { 130353056d49d8adf5d1fe2d18cb60c3c26f281e7a6cDmitri Plotnikov mAggregationScheduler = scheduler; 1304a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 13054f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 13064f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 13074f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton public boolean onCreate() { 1308de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov super.onCreate(); 130935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 1310de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov final Context context = getContext(); 1311de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mOpenHelper = (OpenHelper)getOpenHelper(); 1312a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov mGlobalSearchSupport = new GlobalSearchSupport(this); 1313a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov mLegacyApiSupport = new LegacyApiSupport(context, mOpenHelper, this, mGlobalSearchSupport); 1314cdbd854decda3f493b395c8867f2cd131d95d09fDmitri Plotnikov mContactAggregator = new ContactAggregator(this, mOpenHelper, mAggregationScheduler); 1315a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1316d51a83ac4f8032b62d9a23b90a8f43d6b7eb2dbbDmitri Plotnikov final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 1317653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1318c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetPrimaryStatement = db.compileStatement( 1319653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov "UPDATE " + Tables.DATA + 1320653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov " SET " + Data.IS_PRIMARY + "=(_id=?)" + 1321653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=?" + 1322653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov " AND " + Data.RAW_CONTACT_ID + "=?"); 1323653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 1324c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetSuperPrimaryStatement = db.compileStatement( 1325653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov "UPDATE " + Tables.DATA + 1326653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov " SET " + Data.IS_SUPER_PRIMARY + "=(" + Data._ID + "=?)" + 1327653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=?" + 1328653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov " AND " + Data.RAW_CONTACT_ID + " IN (" + 1329653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov "SELECT " + RawContacts._ID + 1330653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1331653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + " =(" + 1332653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov "SELECT " + RawContacts.CONTACT_ID + 1333653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1334653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?))"); 1335653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 13365ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov mLastTimeContactedUpdate = db.compileStatement("UPDATE " + Tables.RAW_CONTACTS + " SET " 13376cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov + RawContacts.TIMES_CONTACTED + "=" + RawContacts.TIMES_CONTACTED + "+1," 1338d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + RawContacts.LAST_TIME_CONTACTED + "=? WHERE " + RawContacts.CONTACT_ID + "=?"); 1339a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 134025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov mRawContactDisplayNameUpdate = db.compileStatement( 134125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 134225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov " SET " + RawContactsColumns.DISPLAY_NAME + "=?," 134325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov + RawContactsColumns.DISPLAY_NAME_SOURCE + "=?" + 134425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov " WHERE " + RawContacts._ID + "=?"); 13453cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 134673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mRawContactDirtyUpdate = db.compileStatement("UPDATE " + Tables.RAW_CONTACTS + " SET " 134773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov + RawContacts.DIRTY + "=1 WHERE " + RawContacts._ID + "=?"); 134873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 1349e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov mAggregatedPresenceReplace = db.compileStatement( 1350e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov "INSERT OR REPLACE INTO " + Tables.AGGREGATED_PRESENCE + "(" 1351e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + AggregatedPresenceColumns.CONTACT_ID + ", " 1352e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + Presence.PRESENCE_STATUS 1353e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + ") VALUES (?, (SELECT MAX(" + Presence.PRESENCE_STATUS + ")" 1354e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " FROM " + Tables.PRESENCE + "," + Tables.RAW_CONTACTS 1355a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov + " WHERE " + PresenceColumns.RAW_CONTACT_ID + "=" 1356e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID 1357e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " AND " + RawContacts.CONTACT_ID + "=?))"); 1358e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 1359e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov mAggregatedPresenceStatusUpdate = db.compileStatement( 1360e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov "UPDATE " + Tables.AGGREGATED_PRESENCE 1361e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " SET " + Presence.PRESENCE_CUSTOM_STATUS + "=? " 1362e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " WHERE " + AggregatedPresenceColumns.CONTACT_ID + "=?"); 1363e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 136428f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar mNameSplitter = new NameSplitter( 136528f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar context.getString(com.android.internal.R.string.common_name_prefixes), 136628f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar context.getString(com.android.internal.R.string.common_last_name_prefixes), 136728f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar context.getString(com.android.internal.R.string.common_name_suffixes), 136828f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar context.getString(com.android.internal.R.string.common_name_conjunctions)); 13694097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov 13703cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers = new HashMap<String, DataRowHandler>(); 13713cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 1372e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov mDataRowHandlers.put(Email.CONTENT_ITEM_TYPE, new EmailDataRowHandler()); 13733cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers.put(Im.CONTENT_ITEM_TYPE, 13743cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov new CommonDataRowHandler(Im.CONTENT_ITEM_TYPE, Im.TYPE, Im.LABEL)); 137567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey mDataRowHandlers.put(Nickname.CONTENT_ITEM_TYPE, new CommonDataRowHandler( 137667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey StructuredPostal.CONTENT_ITEM_TYPE, StructuredPostal.TYPE, StructuredPostal.LABEL)); 13773cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers.put(Organization.CONTENT_ITEM_TYPE, new OrganizationDataRowHandler()); 13783cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers.put(Phone.CONTENT_ITEM_TYPE, new PhoneDataRowHandler()); 137914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mDataRowHandlers.put(Nickname.CONTENT_ITEM_TYPE, new NicknameDataRowHandler()); 13803cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers.put(StructuredName.CONTENT_ITEM_TYPE, 13813cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov new StructuredNameRowHandler(mNameSplitter)); 1382a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov mDataRowHandlers.put(GroupMembership.CONTENT_ITEM_TYPE, new GroupMembershipRowHandler()); 1383a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov mDataRowHandlers.put(Photo.CONTENT_ITEM_TYPE, new PhotoDataRowHandler()); 13843cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 13853d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov if (isLegacyContactImportNeeded()) { 1386568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov importLegacyContactsAsync(); 13873d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 1388568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 13891f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey return (db != null); 13904f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 13914f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 139231b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov /* Visible for testing */ 1393de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov @Override 139431b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov protected OpenHelper getOpenHelper(final Context context) { 139531b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov return OpenHelper.getInstance(context); 139631b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov } 139731b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 1398285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov /* package */ ContactAggregationScheduler getContactAggregationScheduler() { 1399285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov return mAggregationScheduler; 1400285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov } 1401285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov 1402013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov /* package */ NameSplitter getNameSplitter() { 1403013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov return mNameSplitter; 1404013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov } 1405013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov 14063d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov protected boolean isLegacyContactImportNeeded() { 14073d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); 14083d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return prefs.getInt(PREF_CONTACTS_IMPORTED, 0) < PREF_CONTACTS_IMPORT_VERSION; 14093d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 14103d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 1411568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov protected LegacyContactImporter getLegacyContactImporter() { 1412568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov return new LegacyContactImporter(getContext(), this); 1413568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1414568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 1415568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov /** 1416568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov * Imports legacy contacts in a separate thread. As long as the import process is running 1417568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov * all other access to the contacts is blocked. 1418568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov */ 1419568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov private void importLegacyContactsAsync() { 1420ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov mAccessLatch = new CountDownLatch(1); 1421568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 1422568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov Thread importThread = new Thread("LegacyContactImport") { 1423568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov @Override 1424568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov public void run() { 1425568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov if (importLegacyContacts()) { 1426568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 1427568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov /* 1428568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov * When the import process is done, we can unlock the provider and 1429568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov * start aggregating the imported contacts asynchronously. 1430568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov */ 1431ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov mAccessLatch.countDown(); 1432ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov mAccessLatch = null; 1433568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov scheduleContactAggregation(); 1434568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1435568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1436568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov }; 1437568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 1438568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov importThread.start(); 1439568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1440568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 14413d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov private boolean importLegacyContacts() { 1442568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov LegacyContactImporter importer = getLegacyContactImporter(); 1443568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov if (importLegacyContacts(importer)) { 14443d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); 14453d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov Editor editor = prefs.edit(); 14463d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov editor.putInt(PREF_CONTACTS_IMPORTED, PREF_CONTACTS_IMPORT_VERSION); 14473d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov editor.commit(); 14483d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return true; 14493d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } else { 14503d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return false; 14513d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 14523d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 14533d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 14543d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov /* Visible for testing */ 1455568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov /* package */ boolean importLegacyContacts(LegacyContactImporter importer) { 14563d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov mContactAggregator.setEnabled(false); 145773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mImportMode = true; 14583d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov try { 14593d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov importer.importContacts(); 14603d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov mContactAggregator.setEnabled(true); 14613d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return true; 14623d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } catch (Throwable e) { 14633d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov Log.e(TAG, "Legacy contact import failed", e); 14643d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return false; 146573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } finally { 146673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mImportMode = false; 14673d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 14683d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 14693d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 1470a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov @Override 1471a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov protected void finalize() throws Throwable { 1472a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov if (mContactAggregator != null) { 1473a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov mContactAggregator.quit(); 1474a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 1475a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1476a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov super.finalize(); 1477a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 1478a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1479a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 1480a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov * Wipes all data from the contacts database. 1481a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov */ 1482a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /* package */ void wipeData() { 1483a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov mOpenHelper.wipeData(); 1484a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 1485a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1486568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov /** 1487568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov * While importing and aggregating contacts, this content provider will 1488568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov * block all attempts to change contacts data. In particular, it will hold 1489568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov * up all contact syncs. As soon as the import process is complete, all 1490568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov * processes waiting to write to the provider are unblocked and can proceed 1491568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov * to compete for the database transaction monitor. 1492568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov */ 1493568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov private void waitForAccess() { 1494ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov CountDownLatch latch = mAccessLatch; 1495ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov if (latch != null) { 1496ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov while (true) { 1497ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov try { 1498ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov latch.await(); 1499ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov mAccessLatch = null; 1500ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov return; 1501ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov } catch (InterruptedException e) { 1502ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov } 1503ff065d085b794a0bf4be4cf6e87a67bf060e0319Dmitri Plotnikov } 1504568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1505568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1506568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 1507568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov @Override 1508568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov public Uri insert(Uri uri, ContentValues values) { 1509568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov waitForAccess(); 1510568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov return super.insert(uri, values); 1511568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1512568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 1513568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov @Override 1514568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 1515568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov waitForAccess(); 1516568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov return super.update(uri, values, selection, selectionArgs); 1517568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1518568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 1519568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov @Override 1520568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov public int delete(Uri uri, String selection, String[] selectionArgs) { 1521568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov waitForAccess(); 1522568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov return super.delete(uri, selection, selectionArgs); 1523568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1524568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 1525568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov @Override 1526568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) 1527568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov throws OperationApplicationException { 1528568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov waitForAccess(); 1529568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov return super.applyBatch(operations); 1530568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1531568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 15324f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 1533285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov protected void onBeginTransaction() { 1534285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov super.onBeginTransaction(); 1535285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov mInsertedRawContacts.clear(); 1536285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov } 1537285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov 1538285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov @Override 1539285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov protected void beforeTransactionCommit() { 1540285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov super.beforeTransactionCommit(); 1541285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov int count = mInsertedRawContacts.size(); 1542285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov for (int i = 0; i < count; i++) { 1543285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov mContactAggregator.insertContact(mDb, mInsertedRawContacts.get(i)); 1544285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov } 1545285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov } 1546285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov 1547285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov @Override 1548285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov protected void onEndTransaction() { 1549de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov if (mScheduleAggregation) { 1550de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mScheduleAggregation = false; 1551568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov scheduleContactAggregation(); 1552de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov } 1553285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov super.onEndTransaction(); 15544f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 15554f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 1556cdbd854decda3f493b395c8867f2cd131d95d09fDmitri Plotnikov @Override 1557cdbd854decda3f493b395c8867f2cd131d95d09fDmitri Plotnikov protected void notifyChange() { 1558cdbd854decda3f493b395c8867f2cd131d95d09fDmitri Plotnikov getContext().getContentResolver().notifyChange(ContactsContract.AUTHORITY_URI, null); 1559cdbd854decda3f493b395c8867f2cd131d95d09fDmitri Plotnikov } 1560568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 1561568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov protected void scheduleContactAggregation() { 1562568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov mContactAggregator.schedule(); 1563568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov } 1564568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 1565285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov private boolean isNewRawContact(long rawContactId) { 1566285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov return mInsertedRawContacts.contains(rawContactId); 1567285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov } 1568285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov 15693cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private DataRowHandler getDataRowHandler(final String mimeType) { 15703cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DataRowHandler handler = mDataRowHandlers.get(mimeType); 15713cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (handler == null) { 15723cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov handler = new CustomDataRowHandler(mimeType); 15733cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers.put(mimeType, handler); 15743cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 15753cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov return handler; 15763cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 15773cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 15784f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 1579de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov protected Uri insertInTransaction(Uri uri, ContentValues values) { 1580a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton final int match = sUriMatcher.match(uri); 1581a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton long id = 0; 158235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 1583a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton switch (match) { 158435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana case SYNCSTATE: 1585de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov id = mOpenHelper.getSyncState().insert(mDb, values); 158635ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana break; 158735ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 1588d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS: { 1589d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov insertContact(values); 15906bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov break; 15916bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov } 15926bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 15935ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS: { 1594f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana final Account account = readAccountFromQueryParams(uri); 1595d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov id = insertRawContact(values, account); 1596a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton break; 1597a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1598a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 15995ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_DATA: { 16005ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov values.put(Data.RAW_CONTACT_ID, uri.getPathSegments().get(1)); 160173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov id = insertData(values, shouldMarkRawContactAsDirty(uri)); 1602a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton break; 1603a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1604a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 1605a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton case DATA: { 160673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov id = insertData(values, shouldMarkRawContactAsDirty(uri)); 1607a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton break; 1608a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1609a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 1610ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS: { 1611ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final Account account = readAccountFromQueryParams(uri); 161273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov id = insertGroup(values, account, shouldMarkGroupAsDirty(uri)); 1613ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 1614ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 1615ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1616eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey case SETTINGS: { 1617e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey id = insertSettings(values); 1618eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey break; 1619eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey } 1620eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 16211f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey case PRESENCE: { 16221f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey id = insertPresence(values); 16231f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey break; 16241f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 16251f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 1626a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton default: 1627f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return mLegacyApiSupport.insert(uri, values); 1628a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1629a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 16307e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (id < 0) { 16317e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana return null; 16327e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 16337e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 1634de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return ContentUris.withAppendedId(uri, id); 1635a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1636a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 1637a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton /** 1638035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana * If account is non-null then store it in the values. If the account is already 1639035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana * specified in the values then it must be consistent with the account, if it is non-null. 1640035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana * @param values the ContentValues to read from and update 1641035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana * @param account the explicitly provided Account 1642035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana * @return false if the accounts are inconsistent 16437e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana */ 1644035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private boolean resolveAccount(ContentValues values, Account account) { 1645035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana // If either is specified then both must be specified. 16466cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String accountName = values.getAsString(RawContacts.ACCOUNT_NAME); 16476cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE); 1648035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana if (!TextUtils.isEmpty(accountName) || !TextUtils.isEmpty(accountType)) { 1649035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana final Account valuesAccount = new Account(accountName, accountType); 1650035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana if (account != null && !valuesAccount.equals(account)) { 1651035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana return false; 1652035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana } 1653035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana account = valuesAccount; 1654035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana } 1655035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana if (account != null) { 1656df9fd6b239de5829b04cb413e4dfa3e6da649c38Fred Quintana values.put(RawContacts.ACCOUNT_NAME, account.name); 1657df9fd6b239de5829b04cb413e4dfa3e6da649c38Fred Quintana values.put(RawContacts.ACCOUNT_TYPE, account.type); 1658035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana } 1659035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana return true; 16607e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 16617e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 16627e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana /** 1663d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Inserts an item in the contacts table 16646bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov * 16656bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov * @param values the values for the new row 16666bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov * @return the row ID of the newly created row 16676bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov */ 1668d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private long insertContact(ContentValues values) { 1669de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov throw new UnsupportedOperationException("Aggregate contacts are created automatically"); 16706bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov } 16716bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 16726bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov /** 1673a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * Inserts an item in the contacts table 1674a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * 1675a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * @param values the values for the new row 1676f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana * @param account the account this contact should be associated with. may be null. 1677a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * @return the row ID of the newly created row 1678a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton */ 1679d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private long insertRawContact(ContentValues values, Account account) { 1680a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov ContentValues overriddenValues = new ContentValues(values); 1681d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov overriddenValues.putNull(RawContacts.CONTACT_ID); 1682f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana if (!resolveAccount(overriddenValues, account)) { 16837e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana return -1; 16847e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 16857e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 16863d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov if (values.containsKey(RawContacts.DELETED) 16873d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov && values.getAsInteger(RawContacts.DELETED) != 0) { 16883d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov overriddenValues.put(RawContacts.AGGREGATION_MODE, 16893d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov RawContacts.AGGREGATION_MODE_DISABLED); 16903d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 16913d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 1692023b9437a3644e59309b8cfd12c6d84b98433f95Dmitri Plotnikov long rawContactId = 1693023b9437a3644e59309b8cfd12c6d84b98433f95Dmitri Plotnikov mDb.insert(Tables.RAW_CONTACTS, RawContacts.CONTACT_ID, overriddenValues); 1694023b9437a3644e59309b8cfd12c6d84b98433f95Dmitri Plotnikov mContactAggregator.markNewForAggregation(rawContactId); 1695285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov 1696285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov // Trigger creation of a Contact based on this RawContact at the end of transaction 1697285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov mInsertedRawContacts.add(rawContactId); 1698023b9437a3644e59309b8cfd12c6d84b98433f95Dmitri Plotnikov return rawContactId; 1699a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1700a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 1701a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton /** 1702a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * Inserts an item in the data table 1703a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * 1704a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * @param values the values for the new row 1705a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * @return the row ID of the newly created row 1706a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton */ 170773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private long insertData(ContentValues values, boolean markRawContactAsDirty) { 1708a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton long id = 0; 1709de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.clear(); 1710de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.putAll(values); 171167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 1712de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov long rawContactId = mValues.getAsLong(Data.RAW_CONTACT_ID); 171320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 1714de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // Replace package with internal mapping 1715de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov final String packageName = mValues.getAsString(Data.RES_PACKAGE); 1716de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov if (packageName != null) { 1717de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.put(DataColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName)); 1718de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov } 1719de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.remove(Data.RES_PACKAGE); 1720508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey 1721de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // Replace mimetype with internal mapping 1722de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov final String mimeType = mValues.getAsString(Data.MIMETYPE); 1723de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov if (TextUtils.isEmpty(mimeType)) { 1724de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov throw new IllegalArgumentException(Data.MIMETYPE + " is required"); 1725de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov } 17264097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov 1727de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.put(DataColumns.MIMETYPE_ID, mOpenHelper.getMimeTypeId(mimeType)); 1728de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.remove(Data.MIMETYPE); 1729a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1730a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov DataRowHandler rowHandler = getDataRowHandler(mimeType); 1731a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov id = rowHandler.insert(mDb, rawContactId, mValues); 1732de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov if (markRawContactAsDirty) { 1733de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov setRawContactDirty(rawContactId); 1734a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1735a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1736a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov if (rowHandler.isAggregationRequired()) { 1737a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov triggerAggregation(rawContactId); 1738a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 1739a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton return id; 17404f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 17414f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 17428e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov private void triggerAggregation(long rawContactId) { 17438e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov if (!mContactAggregator.isEnabled()) { 17448e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov return; 17458e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov } 17468e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 17478e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov int aggregationMode = mOpenHelper.getAggregationMode(rawContactId); 1748f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov switch (aggregationMode) { 17498e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov case RawContacts.AGGREGATION_MODE_DISABLED: 17508e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov break; 17518e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 17528e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov case RawContacts.AGGREGATION_MODE_DEFAULT: { 1753421782cb554e5050cf62a86b98df6520038dcd15Dmitri Plotnikov mContactAggregator.markForAggregation(rawContactId); 1754de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mScheduleAggregation = true; 1755f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov break; 17568e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov } 17578e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 17588e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov case RawContacts.AGGREGATION_MODE_SUSPENDED: { 17598e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov long contactId = mOpenHelper.getContactId(rawContactId); 1760f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 17618e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov if (contactId != 0) { 17628e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov mContactAggregator.updateAggregateData(contactId); 17638e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov } 1764f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov break; 17658e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov } 1766f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 17678e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov case RawContacts.AGGREGATION_MODE_IMMEDITATE: { 17688e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov long contactId = mOpenHelper.getContactId(rawContactId); 1769421782cb554e5050cf62a86b98df6520038dcd15Dmitri Plotnikov mContactAggregator.markForAggregation(rawContactId); 17708e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov mContactAggregator.aggregateContact(mDb, rawContactId, contactId); 1771f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov break; 17728e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov } 1773f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1774f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1775f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 1776a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 17775ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov * Returns the group id of the group with sourceId and the same account as rawContactId. 17789261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * If the group doesn't already exist then it is first created, 17799261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * @param db SQLiteDatabase to use for this operation 17805ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov * @param rawContactId the contact this group is associated with 17819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * @param sourceId the sourceIf of the group to query or create 17829261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * @return the group id of the existing or created group 17839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * @throws IllegalArgumentException if the contact is not associated with an account 17849261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * @throws IllegalStateException if a group needs to be created but the creation failed 17859261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana */ 17865ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private long getOrMakeGroup(SQLiteDatabase db, long rawContactId, String sourceId) { 17879261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Account account = null; 17886cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov Cursor c = db.query(ContactsQuery.TABLE, ContactsQuery.PROJECTION, RawContacts._ID + "=" 17895ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + rawContactId, null, null, null, null); 17909261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana try { 17919261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (c.moveToNext()) { 179267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey final String accountName = c.getString(ContactsQuery.ACCOUNT_NAME); 179367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey final String accountType = c.getString(ContactsQuery.ACCOUNT_TYPE); 17949261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { 17959261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana account = new Account(accountName, accountType); 17969261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 17979261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 17989261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } finally { 17999261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana c.close(); 18009261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 18019261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (account == null) { 18029261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana throw new IllegalArgumentException("if the groupmembership only " 18039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "has a sourceid the the contact must be associate with " 18049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "an account"); 18059261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 18069261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 18079261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana // look up the group that contains this sourceId and has the same account name and type 18085ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov // as the contact refered to by rawContactId 18096cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov c = db.query(Tables.GROUPS, new String[]{RawContacts._ID}, 18109261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Clauses.GROUP_HAS_ACCOUNT_AND_SOURCE_ID, 1811df9fd6b239de5829b04cb413e4dfa3e6da649c38Fred Quintana new String[]{sourceId, account.name, account.type}, null, null, null); 18129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana try { 18139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (c.moveToNext()) { 18149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana return c.getLong(0); 18159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } else { 18169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana ContentValues groupValues = new ContentValues(); 1817df9fd6b239de5829b04cb413e4dfa3e6da649c38Fred Quintana groupValues.put(Groups.ACCOUNT_NAME, account.name); 1818df9fd6b239de5829b04cb413e4dfa3e6da649c38Fred Quintana groupValues.put(Groups.ACCOUNT_TYPE, account.type); 18199261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana groupValues.put(Groups.SOURCE_ID, sourceId); 18209261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana long groupId = db.insert(Tables.GROUPS, Groups.ACCOUNT_NAME, groupValues); 18219261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (groupId < 0) { 18229261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana throw new IllegalStateException("unable to create a new group with " 18239261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "this sourceid: " + groupValues); 18249261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 18259261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana return groupId; 18269261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 18279261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } finally { 18289261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana c.close(); 18299261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 18309261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 18319261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 18329261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana /** 183320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov * Delete data row by row so that fixing of primaries etc work correctly. 183420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov */ 183573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private int deleteData(String selection, String[] selectionArgs, 183673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov boolean markRawContactAsDirty) { 183720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov int count = 0; 183820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 1839de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // Note that the query will return data according to the access restrictions, 1840de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // so we don't need to worry about deleting data we don't have permission to read. 184114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov Cursor c = query(Data.CONTENT_URI, DataDeleteQuery.COLUMNS, selection, selectionArgs, null); 1842de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov try { 1843de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov while(c.moveToNext()) { 184414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 184514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov String mimeType = c.getString(DataDeleteQuery.MIMETYPE); 1846a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov DataRowHandler rowHandler = getDataRowHandler(mimeType); 1847a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov count += rowHandler.delete(mDb, c); 184888e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov if (markRawContactAsDirty) { 184988e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov setRawContactDirty(rawContactId); 1850a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov if (rowHandler.isAggregationRequired()) { 1851a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov triggerAggregation(rawContactId); 1852a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 185388e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov } 185420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 185520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } finally { 1856de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov c.close(); 185720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 185820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 185920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov return count; 186020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 186120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 186288e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov /** 186388e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov * Delete a data row provided that it is one of the allowed mime types. 186488e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov */ 186520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov public int deleteData(long dataId, String[] allowedMimeTypes) { 1866f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov 186788e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov // Note that the query will return data according to the access restrictions, 186888e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov // so we don't need to worry about deleting data we don't have permission to read. 186914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov Cursor c = query(Data.CONTENT_URI, DataDeleteQuery.COLUMNS, Data._ID + "=" + dataId, null, 187014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov null); 1871f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov 187220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov try { 187320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov if (!c.moveToFirst()) { 187420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov return 0; 187520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 187620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 187714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov String mimeType = c.getString(DataDeleteQuery.MIMETYPE); 187820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov boolean valid = false; 187920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov for (int i = 0; i < allowedMimeTypes.length; i++) { 188020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov if (TextUtils.equals(mimeType, allowedMimeTypes[i])) { 188120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov valid = true; 188220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov break; 188320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 188420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 188520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 188620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov if (!valid) { 18877a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana throw new IllegalArgumentException("Data type mismatch: expected " 188820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov + Lists.newArrayList(allowedMimeTypes)); 188920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 189020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 1891a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov DataRowHandler rowHandler = getDataRowHandler(mimeType); 1892a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov int count = rowHandler.delete(mDb, c); 18938e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 1894a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov if (rowHandler.isAggregationRequired()) { 1895a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov triggerAggregation(rawContactId); 1896a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 18978e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov return count; 189820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } finally { 189920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov c.close(); 190020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 190120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 190220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 190320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov /** 1904ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Inserts an item in the groups table 1905ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 190673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private long insertGroup(ContentValues values, Account account, boolean markAsDirty) { 1907ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey ContentValues overriddenValues = new ContentValues(values); 1908ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey if (!resolveAccount(overriddenValues, account)) { 1909ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey return -1; 1910ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 1911ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1912ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Replace package with internal mapping 191367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey final String packageName = overriddenValues.getAsString(Groups.RES_PACKAGE); 191467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey if (packageName != null) { 191567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey overriddenValues.put(GroupsColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName)); 191667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey } 191767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey overriddenValues.remove(Groups.RES_PACKAGE); 1918ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 191973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (markAsDirty) { 192073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov overriddenValues.put(Groups.DIRTY, 1); 192173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 192273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 1923ac004680e3cc127b6ebf32b78d2813654b9c56fbJeff Sharkey long result = mDb.insert(Tables.GROUPS, Groups.TITLE, overriddenValues); 1924ac004680e3cc127b6ebf32b78d2813654b9c56fbJeff Sharkey 1925ac004680e3cc127b6ebf32b78d2813654b9c56fbJeff Sharkey if (overriddenValues.containsKey(Groups.GROUP_VISIBLE)) { 1926ac004680e3cc127b6ebf32b78d2813654b9c56fbJeff Sharkey mOpenHelper.updateAllVisible(); 1927ac004680e3cc127b6ebf32b78d2813654b9c56fbJeff Sharkey } 1928ac004680e3cc127b6ebf32b78d2813654b9c56fbJeff Sharkey 1929ac004680e3cc127b6ebf32b78d2813654b9c56fbJeff Sharkey return result; 1930ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 1931ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1932e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey private long insertSettings(ContentValues values) { 1933e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final long id = mDb.insert(Tables.SETTINGS, null, values); 1934e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey if (values.containsKey(Settings.UNGROUPED_VISIBLE)) { 1935e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey mOpenHelper.updateAllVisible(); 1936e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 1937e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey return id; 1938e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 1939e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 1940ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 19411f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey * Inserts a presence update. 19421f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey */ 194370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov public long insertPresence(ContentValues values) { 19441f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey final String handle = values.getAsString(Presence.IM_HANDLE); 19454dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov if (TextUtils.isEmpty(handle) || !values.containsKey(Presence.PROTOCOL)) { 19464dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov throw new IllegalArgumentException("PROTOCOL and IM_HANDLE are required"); 19474dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov } 19484dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov 19494dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov final long protocol = values.getAsLong(Presence.PROTOCOL); 19504dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov String customProtocol = null; 19514dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov 19524dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov if (protocol == Im.PROTOCOL_CUSTOM) { 19534dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov customProtocol = values.getAsString(Presence.CUSTOM_PROTOCOL); 19544dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov if (TextUtils.isEmpty(customProtocol)) { 19554dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov throw new IllegalArgumentException( 19564dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov "CUSTOM_PROTOCOL is required when PROTOCOL=PROTOCOL_CUSTOM"); 19574dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov } 19581f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 19591f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 19601f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey // TODO: generalize to allow other providers to match against email 19614dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov boolean matchEmail = Im.PROTOCOL_GOOGLE_TALK == protocol; 19621f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 196370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov StringBuilder selection = new StringBuilder(); 19641f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey String[] selectionArgs; 19651f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey if (matchEmail) { 19664dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov selection.append( 19674dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov "((" + MimetypesColumns.MIMETYPE + "='" + Im.CONTENT_ITEM_TYPE + "'" 19684dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + " AND " + Im.PROTOCOL + "=?" 19694dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + " AND " + Im.DATA + "=?"); 19704dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov if (customProtocol != null) { 19714dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov selection.append(" AND " + Im.CUSTOM_PROTOCOL + "="); 19724dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov DatabaseUtils.appendEscapedSQLString(selection, customProtocol); 19734dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov } 19744dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov selection.append(") OR (" 19754dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + MimetypesColumns.MIMETYPE + "='" + Email.CONTENT_ITEM_TYPE + "'" 19764dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + " AND " + Email.DATA + "=?" 19774dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + "))"); 19784dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov selectionArgs = new String[] { String.valueOf(protocol), handle, handle }; 19791f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } else { 19804dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov selection.append( 19814dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov MimetypesColumns.MIMETYPE + "='" + Im.CONTENT_ITEM_TYPE + "'" 19824dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + " AND " + Im.PROTOCOL + "=?" 19834dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + " AND " + Im.DATA + "=?"); 19844dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov if (customProtocol != null) { 19854dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov selection.append(" AND " + Im.CUSTOM_PROTOCOL + "="); 19864dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov DatabaseUtils.appendEscapedSQLString(selection, customProtocol); 19874dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov } 19884dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov 19894dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov selectionArgs = new String[] { String.valueOf(protocol), handle }; 19901f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 19911f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 199270b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov if (values.containsKey(Presence.DATA_ID)) { 199370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov selection.append(" AND " + DataColumns.CONCRETE_ID + "=") 199470b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov .append(values.getAsLong(Presence.DATA_ID)); 199570b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov } 199670b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov 199700ec508630251d6c6e3746469c9428f5a8cd5996Jeff Sharkey selection.append(" AND ").append(getContactsRestrictions()); 199870b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov 19991f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey long dataId = -1; 20005ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long rawContactId = -1; 2001e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov long contactId = -1; 200270b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov 20031f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey Cursor cursor = null; 20041f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey try { 2005de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov cursor = mDb.query(DataContactsQuery.TABLE, DataContactsQuery.PROJECTION, 200670b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov selection.toString(), selectionArgs, null, null, null); 20071f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey if (cursor.moveToFirst()) { 200867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey dataId = cursor.getLong(DataContactsQuery.DATA_ID); 20095ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov rawContactId = cursor.getLong(DataContactsQuery.RAW_CONTACT_ID); 2010e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov contactId = cursor.getLong(DataContactsQuery.CONTACT_ID); 20111f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } else { 20121f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey // No contact found, return a null URI 20131f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey return -1; 20141f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 20151f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } finally { 201631b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov if (cursor != null) { 201731b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov cursor.close(); 201831b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov } 20191f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 20201f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 20211f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey values.put(Presence.DATA_ID, dataId); 20224dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov values.put(PresenceColumns.RAW_CONTACT_ID, rawContactId); 20231f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 20241f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey // Insert the presence update 2025de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov long presenceId = mDb.replace(Tables.PRESENCE, null, values); 2026e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 2027e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov if (contactId != -1) { 2028e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov if (values.containsKey(Presence.PRESENCE_STATUS)) { 2029e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov mAggregatedPresenceReplace.bindLong(1, contactId); 2030e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov mAggregatedPresenceReplace.bindLong(2, contactId); 2031e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov mAggregatedPresenceReplace.execute(); 2032e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov } 2033e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov String status = values.getAsString(Presence.PRESENCE_CUSTOM_STATUS); 2034e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov if (status != null) { 2035e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov mAggregatedPresenceStatusUpdate.bindString(1, status); 2036e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov mAggregatedPresenceStatusUpdate.bindLong(2, contactId); 2037e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov mAggregatedPresenceStatusUpdate.execute(); 2038e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov } 2039e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov } 20401f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey return presenceId; 20411f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 20421f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 20434f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 2044de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov protected int deleteInTransaction(Uri uri, String selection, String[] selectionArgs) { 2045508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey final int match = sUriMatcher.match(uri); 2046508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey switch (match) { 204735ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana case SYNCSTATE: 2048de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mOpenHelper.getSyncState().delete(mDb, selection, selectionArgs); 204935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 2050d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_ID: { 2051d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov long contactId = ContentUris.parseId(uri); 20526bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 2053d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov // Remove references to the contact first 20546bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov ContentValues values = new ContentValues(); 2055d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values.putNull(RawContacts.CONTACT_ID); 2056de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mDb.update(Tables.RAW_CONTACTS, values, 2057d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov RawContacts.CONTACT_ID + "=" + contactId, null); 20586bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 2059de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.delete(Tables.CONTACTS, BaseColumns._ID + "=" + contactId, null); 20606bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov } 20616bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 20622971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana case RAW_CONTACTS: { 20632971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana final boolean permanently = 20642971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana readBooleanQueryParameter(uri, RawContacts.DELETE_PERMANENTLY, false); 20652971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana int numDeletes = 0; 20662971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana Cursor c = mDb.query(Tables.RAW_CONTACTS, new String[]{RawContacts._ID}, 2067e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong appendAccountToSelection(uri, selection), selectionArgs, null, null, null); 20682971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana try { 20692971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana while (c.moveToNext()) { 20702971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana final long rawContactId = c.getLong(0); 20712971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana numDeletes += deleteRawContact(rawContactId, permanently); 20722971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana } 20732971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana } finally { 20742971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana c.close(); 20752971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana } 20762971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana return numDeletes; 20772971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana } 20782971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana 20795ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_ID: { 20802971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana final boolean permanently = 20812971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana readBooleanQueryParameter(uri, RawContacts.DELETE_PERMANENTLY, false); 20822971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana final long rawContactId = ContentUris.parseId(uri); 20832971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana return deleteRawContact(rawContactId, permanently); 2084508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey } 2085508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey 208620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov case DATA: { 2087944abb09aa47fc08db668be8909fc4045a681117Cynthia Wong return deleteData(appendAccountToSelection(uri, selection), selectionArgs, 2088944abb09aa47fc08db668be8909fc4045a681117Cynthia Wong shouldMarkRawContactAsDirty(uri)); 208920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 209020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 2091508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey case DATA_ID: { 2092508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey long dataId = ContentUris.parseId(uri); 2093f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov return deleteData(Data._ID + "=" + dataId, null, shouldMarkRawContactAsDirty(uri)); 2094ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2095ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2096ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS_ID: { 20972971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana boolean markAsDirty = shouldMarkGroupAsDirty(uri); 20982971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana final boolean deletePermanently = 20992971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana readBooleanQueryParameter(uri, Groups.DELETE_PERMANENTLY, false); 21002971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana return deleteGroup(ContentUris.parseId(uri), markAsDirty, deletePermanently); 21012971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana } 21022971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana 21032971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana case GROUPS: { 21042971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana boolean markAsDirty = shouldMarkGroupAsDirty(uri); 21056f7446a25ecb55ee213eaa7702837cdf32e68777Dmitri Plotnikov final boolean permanently = 21062971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana readBooleanQueryParameter(uri, RawContacts.DELETE_PERMANENTLY, false); 21072971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana int numDeletes = 0; 21082971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana Cursor c = mDb.query(Tables.GROUPS, new String[]{Groups._ID}, 2109e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong appendAccountToSelection(uri, selection), selectionArgs, null, null, null); 21102971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana try { 21112971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana while (c.moveToNext()) { 21122971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana numDeletes += deleteGroup(c.getLong(0), markAsDirty, permanently); 21132971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana } 21142971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana } finally { 21152971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana c.close(); 21162971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana } 21172971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana return numDeletes; 2118508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey } 2119508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey 2120eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey case SETTINGS: { 2121e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey return deleteSettings(selection, selectionArgs); 2122eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey } 2123eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 21241f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey case PRESENCE: { 2125eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey return mDb.delete(Tables.PRESENCE, selection, selectionArgs); 21261f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 21271f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 2128508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey default: 21293cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov return mLegacyApiSupport.delete(uri, selection, selectionArgs); 2130508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey } 21314f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 21324f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 21332971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana private boolean readBooleanQueryParameter(Uri uri, String name, boolean defaultValue) { 21342971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana final String flag = uri.getQueryParameter(name); 21352971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana return flag == null 21362971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana ? defaultValue 21372971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana : (!"false".equals(flag.toLowerCase()) && !"0".equals(flag.toLowerCase())); 213894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 213994021b213e4db367f60b30fcbfe9019e28571784Fred Quintana 214073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private int deleteGroup(long groupId, boolean markAsDirty, boolean permanently) { 214194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana final long groupMembershipMimetypeId = mOpenHelper 214294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana .getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 2143de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mDb.delete(Tables.DATA, DataColumns.MIMETYPE_ID + "=" 214494021b213e4db367f60b30fcbfe9019e28571784Fred Quintana + groupMembershipMimetypeId + " AND " + GroupMembership.GROUP_ROW_ID + "=" 214594021b213e4db367f60b30fcbfe9019e28571784Fred Quintana + groupId, null); 214694021b213e4db367f60b30fcbfe9019e28571784Fred Quintana 214794021b213e4db367f60b30fcbfe9019e28571784Fred Quintana try { 214894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana if (permanently) { 2149de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.delete(Tables.GROUPS, Groups._ID + "=" + groupId, null); 215094021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } else { 215194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana mValues.clear(); 215294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana mValues.put(Groups.DELETED, 1); 215373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (markAsDirty) { 215473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mValues.put(Groups.DIRTY, 1); 215573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 2156de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.update(Tables.GROUPS, mValues, Groups._ID + "=" + groupId, null); 215794021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 215894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } finally { 215994021b213e4db367f60b30fcbfe9019e28571784Fred Quintana mOpenHelper.updateAllVisible(); 216094021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 216194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 216294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana 2163e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey private int deleteSettings(String selection, String[] selectionArgs) { 2164e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final int count = mDb.delete(Tables.SETTINGS, selection, selectionArgs); 2165e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey if (count > 0) { 2166e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey mOpenHelper.updateAllVisible(); 2167e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 2168e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey return count; 2169e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 2170e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 21715ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public int deleteRawContact(long rawContactId, boolean permanently) { 2172c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // TODO delete aggregation exceptions 2173c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov mOpenHelper.removeContactIfSingleton(rawContactId); 217433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov if (permanently) { 217514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov mDb.delete(Tables.PRESENCE, PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null); 2176de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.delete(Tables.RAW_CONTACTS, RawContacts._ID + "=" + rawContactId, null); 217733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov } else { 217811944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 217911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov // Clear out data used for aggregation - this deleted contact should not be aggregated 218011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov mDb.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + " WHERE " 218111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.RAW_CONTACT_ID + "=" + rawContactId); 218211944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 218333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov mValues.clear(); 218494021b213e4db367f60b30fcbfe9019e28571784Fred Quintana mValues.put(RawContacts.DELETED, 1); 2185c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov mValues.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED); 2186c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov mValues.putNull(RawContacts.CONTACT_ID); 218773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mValues.put(RawContacts.DIRTY, 1); 21885ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov return updateRawContact(rawContactId, mValues, null, null); 218933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov } 219033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov } 219133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov 2192f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana private static Account readAccountFromQueryParams(Uri uri) { 21936cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String name = uri.getQueryParameter(RawContacts.ACCOUNT_NAME); 21946cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String type = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE); 2195f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana if (TextUtils.isEmpty(name) || TextUtils.isEmpty(type)) { 2196f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana return null; 2197f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana } 2198f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana return new Account(name, type); 2199f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana } 2200f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana 22014f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 2202de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov protected int updateInTransaction(Uri uri, ContentValues values, String selection, 2203de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov String[] selectionArgs) { 220435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana int count = 0; 220500d71133c63c882fb41729ddc3a52f66fb155374Evan Millar 220600d71133c63c882fb41729ddc3a52f66fb155374Evan Millar final int match = sUriMatcher.match(uri); 220700d71133c63c882fb41729ddc3a52f66fb155374Evan Millar switch(match) { 220835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana case SYNCSTATE: 2209de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mOpenHelper.getSyncState().update(mDb, values, selection, selectionArgs); 221035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 2211d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov // TODO(emillar): We will want to disallow editing the contacts table at some point. 2212d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS: { 2213944abb09aa47fc08db668be8909fc4045a681117Cynthia Wong count = mDb.update(Tables.CONTACTS, values, 2214944abb09aa47fc08db668be8909fc4045a681117Cynthia Wong appendAccountToSelection(uri, selection), selectionArgs); 221500d71133c63c882fb41729ddc3a52f66fb155374Evan Millar break; 221600d71133c63c882fb41729ddc3a52f66fb155374Evan Millar } 221700d71133c63c882fb41729ddc3a52f66fb155374Evan Millar 2218d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_ID: { 2219de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov count = updateContactData(ContentUris.parseId(uri), values); 2220c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar break; 2221c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar } 2222c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar 222320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov case DATA: { 2224944abb09aa47fc08db668be8909fc4045a681117Cynthia Wong count = updateData(uri, values, appendAccountToSelection(uri, selection), 2225944abb09aa47fc08db668be8909fc4045a681117Cynthia Wong selectionArgs, shouldMarkRawContactAsDirty(uri)); 222620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov break; 222720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 2228c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar 222920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov case DATA_ID: { 223073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov count = updateData(uri, values, selection, selectionArgs, 223173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov shouldMarkRawContactAsDirty(uri)); 223200d71133c63c882fb41729ddc3a52f66fb155374Evan Millar break; 223300d71133c63c882fb41729ddc3a52f66fb155374Evan Millar } 22347e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 22355ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS: { 223673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov // TODO: security checks 2237e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong count = mDb.update(Tables.RAW_CONTACTS, values, 2238e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong appendAccountToSelection(uri, selection), selectionArgs); 2239433a3a08a4726952c080e22e3969ac6c4f28e8dfJeff Sharkey 2240433a3a08a4726952c080e22e3969ac6c4f28e8dfJeff Sharkey if (values.containsKey(RawContacts.STARRED)) { 2241433a3a08a4726952c080e22e3969ac6c4f28e8dfJeff Sharkey mContactAggregator.updateStarred(mDb, selection, selectionArgs); 2242433a3a08a4726952c080e22e3969ac6c4f28e8dfJeff Sharkey } 22437e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana break; 22447e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 22457e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 22465ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_ID: { 224733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov long rawContactId = ContentUris.parseId(uri); 224833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov count = updateRawContact(rawContactId, values, selection, selectionArgs); 22497e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana break; 22507e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 22517e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 2252ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS: { 2253e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong count = updateGroups(values, appendAccountToSelection(uri, selection), 2254e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong selectionArgs, shouldMarkGroupAsDirty(uri)); 2255ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 2256ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2257ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2258ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS_ID: { 2259ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey long groupId = ContentUris.parseId(uri); 226073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov String selectionWithId = (Groups._ID + "=" + groupId + " ") 226173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov + (selection == null ? "" : " AND " + selection); 2262de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov count = updateGroups(values, selectionWithId, selectionArgs, 226373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov shouldMarkGroupAsDirty(uri)); 2264ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 2265ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2266ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2267127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov case AGGREGATION_EXCEPTIONS: { 2268de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov count = updateAggregationException(mDb, values); 2269b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov break; 2270b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 2271b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 2272eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey case SETTINGS: { 2273e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey count = updateSettings(values, selection, selectionArgs); 2274eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey break; 2275eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey } 2276eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 22777e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana default: 2278f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return mLegacyApiSupport.update(uri, values, selection, selectionArgs); 227900d71133c63c882fb41729ddc3a52f66fb155374Evan Millar } 228000d71133c63c882fb41729ddc3a52f66fb155374Evan Millar 228100d71133c63c882fb41729ddc3a52f66fb155374Evan Millar return count; 22824f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 22834f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 2284de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov private int updateGroups(ContentValues values, String selectionWithId, 228573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov String[] selectionArgs, boolean markAsDirty) { 228673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 228773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov ContentValues updatedValues; 228873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (markAsDirty) { 228973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov updatedValues = mValues; 229073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov updatedValues.clear(); 229173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov updatedValues.putAll(values); 229273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov updatedValues.put(Groups.DIRTY, 1); 229373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } else { 229473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov updatedValues = values; 229573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 229673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 2297ac004680e3cc127b6ebf32b78d2813654b9c56fbJeff Sharkey int count = mDb.update(Tables.GROUPS, updatedValues, selectionWithId, selectionArgs); 229894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana 229994021b213e4db367f60b30fcbfe9019e28571784Fred Quintana // If changing visibility, then update contacts 2300ac004680e3cc127b6ebf32b78d2813654b9c56fbJeff Sharkey if (updatedValues.containsKey(Groups.GROUP_VISIBLE)) { 230194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana mOpenHelper.updateAllVisible(); 230294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 230394021b213e4db367f60b30fcbfe9019e28571784Fred Quintana return count; 230494021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 230594021b213e4db367f60b30fcbfe9019e28571784Fred Quintana 2306e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey private int updateSettings(ContentValues values, String selection, String[] selectionArgs) { 2307e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final int count = mDb.update(Tables.SETTINGS, values, selection, selectionArgs); 2308e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey if (values.containsKey(Settings.UNGROUPED_VISIBLE)) { 2309e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey mOpenHelper.updateAllVisible(); 2310e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 2311e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey return count; 2312e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 2313e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 23145ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private int updateRawContact(long rawContactId, ContentValues values, String selection, 231533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov String[] selectionArgs) { 231673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 231773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov // TODO: security checks 23185ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov String selectionWithId = (RawContacts._ID + " = " + rawContactId + " ") 231933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov + (selection == null ? "" : " AND " + selection); 23205870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int count = mDb.update(Tables.RAW_CONTACTS, values, selectionWithId, selectionArgs); 23215870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (count != 0) { 23225870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (values.containsKey(RawContacts.ACCOUNT_TYPE) 23235870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov || values.containsKey(RawContacts.ACCOUNT_NAME) 23245870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov || values.containsKey(RawContacts.SOURCE_ID)) { 23255870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov triggerAggregation(rawContactId); 23265870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 2327433a3a08a4726952c080e22e3969ac6c4f28e8dfJeff Sharkey 2328433a3a08a4726952c080e22e3969ac6c4f28e8dfJeff Sharkey if (values.containsKey(RawContacts.STARRED)) { 2329433a3a08a4726952c080e22e3969ac6c4f28e8dfJeff Sharkey mContactAggregator.updateStarred(mDb, selectionWithId, selectionArgs); 2330433a3a08a4726952c080e22e3969ac6c4f28e8dfJeff Sharkey } 2331285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov if (values.containsKey(RawContacts.SOURCE_ID)) { 2332285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov mContactAggregator.updateLookupKey(mDb, rawContactId); 2333285b771bc955305fa6d49ca23f808cecc8a13d5eDmitri Plotnikov } 23345870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 23355870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return count; 233633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov } 233733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov 2338321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana private int updateData(Uri uri, ContentValues values, String selection, 233973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov String[] selectionArgs, boolean markRawContactAsDirty) { 234020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.clear(); 234120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.putAll(values); 234220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.remove(Data._ID); 23435ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov mValues.remove(Data.RAW_CONTACT_ID); 234420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.remove(Data.MIMETYPE); 234520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 234620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov String packageName = values.getAsString(Data.RES_PACKAGE); 234720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov if (packageName != null) { 234820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.remove(Data.RES_PACKAGE); 234920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.put(DataColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName)); 235020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 235120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 235270b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov boolean containsIsSuperPrimary = mValues.containsKey(Data.IS_SUPER_PRIMARY); 235370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov boolean containsIsPrimary = mValues.containsKey(Data.IS_PRIMARY); 235420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 235520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov // Remove primary or super primary values being set to 0. This is disallowed by the 235620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov // content provider. 235770b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov if (containsIsSuperPrimary && mValues.getAsInteger(Data.IS_SUPER_PRIMARY) == 0) { 235820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov containsIsSuperPrimary = false; 235970b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov mValues.remove(Data.IS_SUPER_PRIMARY); 236020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 236170b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov if (containsIsPrimary && mValues.getAsInteger(Data.IS_PRIMARY) == 0) { 236220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov containsIsPrimary = false; 236370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov mValues.remove(Data.IS_PRIMARY); 236420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 236520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 2366653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov int count = 0; 236720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 2368653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov // Note that the query will return data according to the access restrictions, 2369653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov // so we don't need to worry about updating data we don't have permission to read. 237014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov Cursor c = query(uri, DataUpdateQuery.COLUMNS, selection, selectionArgs, null); 2371653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov try { 2372653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov while(c.moveToNext()) { 2373653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov count += updateData(mValues, c, markRawContactAsDirty); 237420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 2375653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov } finally { 2376653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov c.close(); 237720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 237820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 2379653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov return count; 238020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 238120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 2382653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov private int updateData(ContentValues values, Cursor c, boolean markRawContactAsDirty) { 2383653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov if (values.size() == 0) { 2384653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov return 0; 2385321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana } 2386653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov 238714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov final String mimeType = c.getString(DataUpdateQuery.MIMETYPE); 2388a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov DataRowHandler rowHandler = getDataRowHandler(mimeType); 2389a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov rowHandler.update(mDb, values, c, markRawContactAsDirty); 23908e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 2391a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov if (rowHandler.isAggregationRequired()) { 2392a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov triggerAggregation(rawContactId); 2393a6733943584294492aa0118fc32bf4e58dabb028Dmitri Plotnikov } 23948e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 2395653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov return 1; 2396321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana } 2397321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana 2398de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov private int updateContactData(long contactId, ContentValues values) { 2399d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov 2400d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov // First update all constituent contacts 2401f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues optionValues = new ContentValues(5); 24026cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov OpenHelper.copyStringValue(optionValues, RawContacts.CUSTOM_RINGTONE, 2403d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values, Contacts.CUSTOM_RINGTONE); 24046cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov OpenHelper.copyLongValue(optionValues, RawContacts.SEND_TO_VOICEMAIL, 2405d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values, Contacts.SEND_TO_VOICEMAIL); 24066cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov OpenHelper.copyLongValue(optionValues, RawContacts.LAST_TIME_CONTACTED, 2407d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values, Contacts.LAST_TIME_CONTACTED); 24086cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov OpenHelper.copyLongValue(optionValues, RawContacts.TIMES_CONTACTED, 2409d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values, Contacts.TIMES_CONTACTED); 24106cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov OpenHelper.copyLongValue(optionValues, RawContacts.STARRED, 2411d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values, Contacts.STARRED); 2412d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov 2413d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov // Nothing to update - just return 2414d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov if (optionValues.size() == 0) { 2415d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov return 0; 2416d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov } 2417d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov 2418c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey if (optionValues.containsKey(RawContacts.STARRED)) { 2419c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey // Mark dirty when changing starred to trigger sync 2420c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey optionValues.put(RawContacts.DIRTY, 1); 2421c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey } 2422c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey 2423de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mDb.update(Tables.RAW_CONTACTS, optionValues, 2424d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov RawContacts.CONTACT_ID + "=" + contactId, null); 2425de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.update(Tables.CONTACTS, values, Contacts._ID + "=" + contactId, null); 2426f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2427d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov 2428d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public void updateContactTime(long contactId, long lastTimeContacted) { 2429f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov mLastTimeContactedUpdate.bindLong(1, lastTimeContacted); 2430d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov mLastTimeContactedUpdate.bindLong(2, contactId); 2431f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov mLastTimeContactedUpdate.execute(); 2432d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov } 2433d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov 24345ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private static class RawContactPair { 24355ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov final long rawContactId1; 24365ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov final long rawContactId2; 2437127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov 2438127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov /** 24395ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov * Constructor that ensures that this.rawContactId1 < this.rawContactId2 2440127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov */ 24415ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public RawContactPair(long rawContactId1, long rawContactId2) { 24425ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov if (rawContactId1 < rawContactId2) { 24435ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov this.rawContactId1 = rawContactId1; 24445ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov this.rawContactId2 = rawContactId2; 2445127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } else { 24465ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov this.rawContactId2 = rawContactId1; 24475ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov this.rawContactId1 = rawContactId2; 2448127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } 2449127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } 2450127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } 245180c457131bd22afe34828d1a5d15e90bb5f43375Dmitri Plotnikov 2452127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov private int updateAggregationException(SQLiteDatabase db, ContentValues values) { 2453127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov int exceptionType = values.getAsInteger(AggregationExceptions.TYPE); 2454d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov long contactId = values.getAsInteger(AggregationExceptions.CONTACT_ID); 24555ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long rawContactId = values.getAsInteger(AggregationExceptions.RAW_CONTACT_ID); 245680c457131bd22afe34828d1a5d15e90bb5f43375Dmitri Plotnikov 24573cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov // First, we build a list of rawContactID-rawContactID pairs for the given contact. 24585ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov ArrayList<RawContactPair> pairs = new ArrayList<RawContactPair>(); 2459d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Cursor c = db.query(ContactsQuery.TABLE, ContactsQuery.PROJECTION, RawContacts.CONTACT_ID 2460d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + "=" + contactId, null, null, null, null); 2461127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov try { 2462127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov while (c.moveToNext()) { 24635ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long aggregatedContactId = c.getLong(ContactsQuery.RAW_CONTACT_ID); 24645ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov if (aggregatedContactId != rawContactId) { 24655ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov pairs.add(new RawContactPair(aggregatedContactId, rawContactId)); 2466e2e0ba75ce239f0f5481cdef9082daebf8fc2d35Dmitri Plotnikov } 2467b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 2468b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } finally { 2469b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov c.close(); 2470b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 2471127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov 2472127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov // Now we iterate through all contact pairs to see if we need to insert/delete/update 2473127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov // the corresponding exception 2474127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov ContentValues exceptionValues = new ContentValues(3); 2475127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov exceptionValues.put(AggregationExceptions.TYPE, exceptionType); 24765ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov for (RawContactPair pair : pairs) { 2477127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov final String whereClause = 24785ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov AggregationExceptionColumns.RAW_CONTACT_ID1 + "=" + pair.rawContactId1 + " AND " 24795ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + AggregationExceptionColumns.RAW_CONTACT_ID2 + "=" + pair.rawContactId2; 2480127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov if (exceptionType == AggregationExceptions.TYPE_AUTOMATIC) { 2481127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov db.delete(Tables.AGGREGATION_EXCEPTIONS, whereClause, null); 2482127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } else { 24835ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov exceptionValues.put(AggregationExceptionColumns.RAW_CONTACT_ID1, pair.rawContactId1); 24845ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov exceptionValues.put(AggregationExceptionColumns.RAW_CONTACT_ID2, pair.rawContactId2); 2485127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov db.replace(Tables.AGGREGATION_EXCEPTIONS, AggregationExceptions._ID, 2486127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov exceptionValues); 2487127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } 2488127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } 2489127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov 2490421782cb554e5050cf62a86b98df6520038dcd15Dmitri Plotnikov mContactAggregator.markForAggregation(rawContactId); 24918e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov mContactAggregator.aggregateContact(db, rawContactId, 24928e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov mOpenHelper.getContactId(rawContactId)); 24938e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov if (exceptionType == AggregationExceptions.TYPE_AUTOMATIC 24948e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov || exceptionType == AggregationExceptions.TYPE_KEEP_OUT) { 24958e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov mContactAggregator.updateAggregateData(contactId); 24967a39bf269294a8130ddd463460b9b36cf4ff74a8Dmitri Plotnikov } 2497127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov 2498127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov // The return value is fake - we just confirm that we made a change, not count actual 2499127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov // rows changed. 2500127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov return 1; 2501b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 2502b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 2503619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2504619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 2505619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Test if a {@link String} value appears in the given list, and add to the 2506619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * array if the value doesn't already appear. 2507619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */ 2508619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey private String[] assertContained(String[] array, String value) { 2509ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov if (array != null && !mOpenHelper.isInProjection(array, value)) { 2510619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey String[] newArray = new String[array.length + 1]; 2511619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey System.arraycopy(array, 0, newArray, 0, array.length); 2512619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey newArray[array.length] = value; 2513619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey array = newArray; 2514619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2515619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey return array; 2516619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2517619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 25184f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 25194f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 25204f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton String sortOrder) { 25210b30cac29514b3978896731ba1df6a54fc94e9e4Dmitri Plotnikov 25224f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 252335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 2524d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 25251f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey String groupBy = null; 2526c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String limit = getLimit(uri); 2527c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2528619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // TODO: Consider writing a test case for RestrictionExceptions when you 2529619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // write a new query() block to make sure it protects restricted data. 2530a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton final int match = sUriMatcher.match(uri); 25314f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton switch (match) { 253235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana case SYNCSTATE: 253335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana return mOpenHelper.getSyncState().query(db, projection, selection, selectionArgs, 253435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana sortOrder); 253535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 2536d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS: { 2537ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov setTablesAndProjectionMapForContacts(qb, projection); 2538619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey break; 2539619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2540619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2541d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_ID: { 25424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov long contactId = ContentUris.parseId(uri); 2543ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov setTablesAndProjectionMapForContacts(qb, projection); 25444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Contacts._ID + "=" + contactId); 25456bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov break; 25466bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov } 25476bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 25485870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov case CONTACTS_LOOKUP: 25495870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov case CONTACTS_LOOKUP_ID: { 25505870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov List<String> pathSegments = uri.getPathSegments(); 25515870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int segmentCount = pathSegments.size(); 25525870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (segmentCount < 3) { 25535870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov throw new IllegalArgumentException("URI " + uri + " is missing a lookup key"); 25545870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 25555870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String lookupKey = pathSegments.get(2); 25565870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (segmentCount == 4) { 25575870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov long contactId = Long.parseLong(pathSegments.get(3)); 25585870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov SQLiteQueryBuilder lookupQb = new SQLiteQueryBuilder(); 25595870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov setTablesAndProjectionMapForContacts(lookupQb, projection); 25605870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov lookupQb.appendWhere(Contacts._ID + "=" + contactId + " AND " + 25615870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov Contacts.LOOKUP_KEY + "="); 25625870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov lookupQb.appendWhereEscapeString(lookupKey); 25635870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov Cursor c = query(db, lookupQb, projection, selection, selectionArgs, sortOrder, 25645870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov groupBy, limit); 25655870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (c.getCount() != 0) { 25665870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return c; 25675870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 25685870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 25695870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov c.close(); 25705870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 25715870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 25725870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov setTablesAndProjectionMapForContacts(qb, projection); 25735870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov qb.appendWhere(Contacts._ID + "=" + lookupContactIdByLookupKey(db, lookupKey)); 25745870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov break; 25755870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 25765870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 2577ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov case CONTACTS_FILTER: { 2578ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov setTablesAndProjectionMapForContacts(qb, projection); 2579ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar if (uri.getPathSegments().size() > 2) { 25804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String filterParam = uri.getLastPathSegment(); 25814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 2582e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov sb.append(Contacts._ID + " IN "); 2583e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov appendContactByFilterAsNestedQuery(sb, filterParam); 25844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(sb.toString()); 2585ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2586ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar break; 2587ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2588ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar 2589ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov case CONTACTS_STREQUENT_FILTER: 2590ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov case CONTACTS_STREQUENT: { 25914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String filterSql = null; 2592ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov if (match == CONTACTS_STREQUENT_FILTER 2593d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar && uri.getPathSegments().size() > 3) { 25944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String filterParam = uri.getLastPathSegment(); 25954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 2596e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov sb.append(Contacts._ID + " IN "); 2597e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov appendContactByFilterAsNestedQuery(sb, filterParam); 25984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov filterSql = sb.toString(); 25994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 26004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2601ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov setTablesAndProjectionMapForContacts(qb, projection); 2602ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov 26034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov // Build the first query for starred 26044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (filterSql != null) { 26054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(filterSql); 2606d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar } 2607d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov final String starredQuery = qb.buildQuery(projection, Contacts.STARRED + "=1", 26084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov null, Contacts._ID, null, null, null); 2609d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar 2610d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar // Build the second query for frequent 2611d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar qb = new SQLiteQueryBuilder(); 2612ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov setTablesAndProjectionMapForContacts(qb, projection); 26134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (filterSql != null) { 26144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(filterSql); 2615d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar } 2616d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar final String frequentQuery = qb.buildQuery(projection, 2617d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.TIMES_CONTACTED + " > 0 AND (" + Contacts.STARRED 2618d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + " = 0 OR " + Contacts.STARRED + " IS NULL)", 26194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov null, Contacts._ID, null, null, null); 2620d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar 2621d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar // Put them together 2622d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar final String query = qb.buildUnionQuery(new String[] {starredQuery, frequentQuery}, 2623d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar STREQUENT_ORDER_BY, STREQUENT_LIMIT); 26244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov Cursor c = db.rawQuery(query, null); 26254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (c != null) { 2626d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar c.setNotificationUri(getContext().getContentResolver(), 2627d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar ContactsContract.AUTHORITY_URI); 2628d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar } 2629d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar return c; 2630d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar } 2631d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar 2632ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov case CONTACTS_GROUP: { 2633ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov setTablesAndProjectionMapForContacts(qb, projection); 2634b67163a1088f09c59f324350662eb18772fac6b6Evan Millar if (uri.getPathSegments().size() > 2) { 26354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(sContactsInGroupSelect); 26364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov selectionArgs = insertSelectionArg(selectionArgs, uri.getLastPathSegment()); 2637b67163a1088f09c59f324350662eb18772fac6b6Evan Millar } 2638b67163a1088f09c59f324350662eb18772fac6b6Evan Millar break; 2639b67163a1088f09c59f324350662eb18772fac6b6Evan Millar } 2640b67163a1088f09c59f324350662eb18772fac6b6Evan Millar 2641d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_DATA: { 26424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov long contactId = Long.parseLong(uri.getPathSegments().get(1)); 26434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 26444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 26454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 26464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov appendAccountFromParameter(qb, uri); 26474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(" AND " + RawContacts.CONTACT_ID + "=" + contactId); 26486bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov break; 26496bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov } 265000d71133c63c882fb41729ddc3a52f66fb155374Evan Millar 2651ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov case CONTACTS_PHOTO: { 26523653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov long contactId = Long.parseLong(uri.getPathSegments().get(1)); 26533653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov 26543653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 26553653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 26563653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov appendAccountFromParameter(qb, uri); 26573653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov qb.appendWhere(" AND " + RawContacts.CONTACT_ID + "=" + contactId); 26583653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov qb.appendWhere(" AND " + Data._ID + "=" + Contacts.PHOTO_ID); 26593653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov break; 26603653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov } 26613653cf1fa8fb36a96a7e4a6ebd615438877c3183Dmitri Plotnikov 26624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov case PHONES: { 26634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 26644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 26654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data.MIMETYPE + " = '" + Phone.CONTENT_ITEM_TYPE + "'"); 26662815f58f72f109790585931f601a63ddc02536a5Evan Millar break; 26672815f58f72f109790585931f601a63ddc02536a5Evan Millar } 26682815f58f72f109790585931f601a63ddc02536a5Evan Millar 2669ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar case PHONES_FILTER: { 26704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 26714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 2672ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar qb.appendWhere(Data.MIMETYPE + " = '" + Phone.CONTENT_ITEM_TYPE + "'"); 2673ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar if (uri.getPathSegments().size() > 2) { 26744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String filterParam = uri.getLastPathSegment(); 26754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 26764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sb.append(Data.RAW_CONTACT_ID + " IN "); 26774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov appendRawContactsByFilterAsNestedQuery(sb, filterParam, null); 26784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(" AND " + sb); 2679ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2680ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar break; 2681ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2682ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 26834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov case EMAILS: { 26844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 26854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 26864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "'"); 26874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov break; 26884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 26894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 26904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov case EMAILS_FILTER: { 26914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 26924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 26934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "'"); 26944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (uri.getPathSegments().size() > 2) { 26954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(" AND " + CommonDataKinds.Email.DATA + "="); 26964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhereEscapeString(uri.getLastPathSegment()); 26974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 2698ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar break; 2699ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2700ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar 2701ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar case POSTALS: { 27024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 27034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 27044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data.MIMETYPE + " = '" + StructuredPostal.CONTENT_ITEM_TYPE + "'"); 2705ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar break; 2706ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2707ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar 27085ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS: { 27094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getRawContactView()); 2710d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sRawContactsProjectionMap); 27114f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton break; 27124f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 27134f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 27145ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_ID: { 27155ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long rawContactId = ContentUris.parseId(uri); 27164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getRawContactView()); 2717d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sRawContactsProjectionMap); 27184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(RawContacts._ID + "=" + rawContactId); 27194f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton break; 27204f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 27214f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 27225ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_DATA: { 27235ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long rawContactId = Long.parseLong(uri.getPathSegments().get(1)); 27244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 27254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 27264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data.RAW_CONTACT_ID + "=" + rawContactId); 2727e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey break; 2728e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey } 2729e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey 2730e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey case DATA: { 27314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 27324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 27334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov appendAccountFromParameter(qb, uri); 2734e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey break; 2735e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey } 2736e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey 27374f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton case DATA_ID: { 27384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 27394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 27404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data._ID + "=" + ContentUris.parseId(uri)); 27414f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton break; 27424f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 27434f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 2744a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov case DATA_WITH_PRESENCE: { 2745a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov qb.setTables(mOpenHelper.getDataView() + " data" 2746e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.AGGREGATED_PRESENCE 2747e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " ON (" + AggregatedPresenceColumns.CONTACT_ID + "=" 2748e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + RawContacts.CONTACT_ID + ")"); 2749a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov qb.setProjectionMap(sDataWithPresenceProjectionMap); 2750a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov break; 2751a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov } 2752a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov 2753a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton case PHONE_LOOKUP: { 27544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2755a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton if (TextUtils.isEmpty(sortOrder)) { 2756a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton // Default the sort order to something reasonable so we get consistent 2757a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton // results when callers don't request an ordering 2758e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sortOrder = RawContactsColumns.CONCRETE_ID; 2759a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 2760a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 2761e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov String number = uri.getPathSegments().size() > 1 ? uri.getLastPathSegment() : ""; 2762e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov mOpenHelper.buildPhoneLookupAndContactQuery(qb, number); 2763e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.setProjectionMap(sPhoneLookupProjectionMap); 2764e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 2765e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov // Phone lookup cannot be combined with a selection 2766e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov selection = null; 2767e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov selectionArgs = null; 2768a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton break; 2769a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 2770a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 2771ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS: { 2772ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.setTables(Tables.GROUPS_JOIN_PACKAGES); 2773ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.setProjectionMap(sGroupsProjectionMap); 2774ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 2775ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2776ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2777ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS_ID: { 2778ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey long groupId = ContentUris.parseId(uri); 2779ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.setTables(Tables.GROUPS_JOIN_PACKAGES); 2780ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.setProjectionMap(sGroupsProjectionMap); 2781ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.appendWhere(GroupsColumns.CONCRETE_ID + "=" + groupId); 2782ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 2783ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2784ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2785ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS_SUMMARY: { 278699a9b5ec879f6cd6876f7f6b680b82d8304e6b92Dmitri Plotnikov qb.setTables(Tables.GROUPS_JOIN_PACKAGES); 2787ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.setProjectionMap(sGroupsSummaryProjectionMap); 2788ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey groupBy = GroupsColumns.CONCRETE_ID; 2789ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 2790ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2791ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2792b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov case AGGREGATION_EXCEPTIONS: { 27935ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov qb.setTables(Tables.AGGREGATION_EXCEPTIONS_JOIN_RAW_CONTACTS); 2794b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov qb.setProjectionMap(sAggregationExceptionsProjectionMap); 2795b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov break; 2796b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 2797b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 279831b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov case AGGREGATION_SUGGESTIONS: { 2799d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov long contactId = Long.parseLong(uri.getPathSegments().get(1)); 280031b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov final int maxSuggestions; 2801d659078547c329b58f90d8809910a845d913dbc6Dmitri Plotnikov if (limit != null) { 2802d659078547c329b58f90d8809910a845d913dbc6Dmitri Plotnikov maxSuggestions = Integer.parseInt(limit); 280331b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov } else { 280431b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov maxSuggestions = DEFAULT_MAX_SUGGESTIONS; 280531b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov } 280631b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 2807d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov return mContactAggregator.queryAggregationSuggestions(contactId, projection, 2808d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov sContactsProjectionMap, maxSuggestions); 280931b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov } 281031b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 2811eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey case SETTINGS: { 2812eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey qb.setTables(Tables.SETTINGS); 2813eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey qb.setProjectionMap(sSettingsProjectionMap); 2814e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 2815e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey // When requesting specific columns, this query requires 2816e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey // late-binding of the GroupMembership MIME-type. 2817e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String groupMembershipMimetypeId = Long.toString(mOpenHelper 2818e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey .getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE)); 2819ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov if (mOpenHelper.isInProjection(projection, Settings.UNGROUPED_COUNT)) { 2820e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey selectionArgs = insertSelectionArg(selectionArgs, groupMembershipMimetypeId); 2821e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 2822ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov if (mOpenHelper.isInProjection(projection, Settings.UNGROUPED_WITH_PHONES)) { 2823e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey selectionArgs = insertSelectionArg(selectionArgs, groupMembershipMimetypeId); 2824e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 2825e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 2826eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey break; 2827eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey } 2828eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 28295ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case PRESENCE: { 2830373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov qb.setTables(Tables.PRESENCE); 2831373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov qb.setProjectionMap(sPresenceProjectionMap); 28325ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov break; 28335ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov } 28345ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov 28355ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case PRESENCE_ID: { 2836373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov qb.setTables(Tables.PRESENCE); 2837373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov qb.setProjectionMap(sPresenceProjectionMap); 2838373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov qb.appendWhere(Presence._ID + "=" + ContentUris.parseId(uri)); 28395ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov break; 28405ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov } 28415ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov 2842c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov case SEARCH_SUGGESTIONS: { 2843a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov return mGlobalSearchSupport.handleSearchSuggestionsQuery(db, uri, limit); 2844c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 2845c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2846c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov case SEARCH_SHORTCUT: { 2847b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov long contactId = ContentUris.parseId(uri); 2848b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov return mGlobalSearchSupport.handleSearchShortcutRefresh(db, contactId, projection); 2849c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 2850c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 28511b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov case LIVE_FOLDERS_CONTACTS: 28521b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.setTables(mOpenHelper.getContactView()); 28531b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.setProjectionMap(sLiveFoldersProjectionMap); 28541b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov break; 28551b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov 28561b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov case LIVE_FOLDERS_CONTACTS_WITH_PHONES: 28571b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.setTables(mOpenHelper.getContactView()); 28581b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.setProjectionMap(sLiveFoldersProjectionMap); 28591b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.appendWhere(Contacts.HAS_PHONE_NUMBER + "=1"); 28601b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov break; 28611b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov 28621b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov case LIVE_FOLDERS_CONTACTS_FAVORITES: 28631b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.setTables(mOpenHelper.getContactView()); 28641b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.setProjectionMap(sLiveFoldersProjectionMap); 28651b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.appendWhere(Contacts.STARRED + "=1"); 28661b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov break; 28671b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov 28681b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov case LIVE_FOLDERS_CONTACTS_GROUP_NAME: 28691b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.setTables(mOpenHelper.getContactView()); 28701b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.setProjectionMap(sLiveFoldersProjectionMap); 28711b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov qb.appendWhere(sContactsInGroupSelect); 28721b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov selectionArgs = insertSelectionArg(selectionArgs, uri.getLastPathSegment()); 28731b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov break; 28741b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov 28754f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton default: 2876f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return mLegacyApiSupport.query(uri, projection, selection, selectionArgs, 2877c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sortOrder, limit); 28784f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 28794f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 28805870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return query(db, qb, projection, selection, selectionArgs, sortOrder, groupBy, limit); 28815870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 28825870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 28835870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private Cursor query(final SQLiteDatabase db, SQLiteQueryBuilder qb, String[] projection, 28845870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String selection, String[] selectionArgs, String sortOrder, String groupBy, 28855870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String limit) { 2886038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana if (projection != null && projection.length == 1 2887038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana && BaseColumns._COUNT.equals(projection[0])) { 2888038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana qb.setProjectionMap(sCountProjectionMap); 2889038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana } 28905870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov final Cursor c = qb.query(db, projection, selection, selectionArgs, groupBy, null, 28915870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sortOrder, limit); 28924f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton if (c != null) { 28934f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton c.setNotificationUri(getContext().getContentResolver(), ContactsContract.AUTHORITY_URI); 28944f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 28954f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton return c; 28964f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 28974f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 28985870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private long lookupContactIdByLookupKey(SQLiteDatabase db, String lookupKey) { 28995870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov ContactLookupKey key = new ContactLookupKey(); 29005870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov ArrayList<LookupKeySegment> segments = key.parse(lookupKey); 29015870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29025870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov long contactId = lookupContactIdBySourceIds(db, segments); 29035870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (contactId == -1) { 29045870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov contactId = lookupContactIdByDisplayNames(db, segments); 29055870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29065870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29075870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return contactId; 29085870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29095870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29105870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private interface LookupBySourceIdQuery { 29115870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String TABLE = Tables.RAW_CONTACTS; 29125870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29135870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String COLUMNS[] = { 29145870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov RawContacts.CONTACT_ID, 29155870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov RawContacts.ACCOUNT_TYPE, 29165870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov RawContacts.ACCOUNT_NAME, 29175870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov RawContacts.SOURCE_ID 29185870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov }; 29195870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29205870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int CONTACT_ID = 0; 29215870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int ACCOUNT_TYPE = 1; 29225870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int ACCOUNT_NAME = 2; 29235870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int SOURCE_ID = 3; 29245870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29255870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29265870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private long lookupContactIdBySourceIds(SQLiteDatabase db, 29275870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov ArrayList<LookupKeySegment> segments) { 29285870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int sourceIdCount = 0; 29295870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov for (int i = 0; i < segments.size(); i++) { 29305870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov LookupKeySegment segment = segments.get(i); 29315870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (segment.sourceIdLookup) { 29325870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sourceIdCount++; 29335870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29345870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29355870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29365870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (sourceIdCount == 0) { 29375870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return -1; 29385870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29395870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29405870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov // First try sync ids 29415870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov StringBuilder sb = new StringBuilder(); 29425870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(RawContacts.SOURCE_ID + " IN ("); 29435870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov for (int i = 0; i < segments.size(); i++) { 29445870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov LookupKeySegment segment = segments.get(i); 29455870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (segment.sourceIdLookup) { 29465870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, segment.key); 29475870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(","); 29485870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29495870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29505870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.setLength(sb.length() - 1); // Last comma 29515870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(") AND " + RawContacts.CONTACT_ID + " NOT NULL"); 29525870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29535870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov Cursor c = db.query(LookupBySourceIdQuery.TABLE, LookupBySourceIdQuery.COLUMNS, 29545870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.toString(), null, null, null, null); 29555870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov try { 29565870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov while (c.moveToNext()) { 29575870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String accountType = c.getString(LookupBySourceIdQuery.ACCOUNT_TYPE); 29585870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String accountName = c.getString(LookupBySourceIdQuery.ACCOUNT_NAME); 29595870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int accountHashCode = 29605870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov ContactLookupKey.getAccountHashCode(accountType, accountName); 29615870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String sourceId = c.getString(LookupBySourceIdQuery.SOURCE_ID); 29625870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov for (int i = 0; i < segments.size(); i++) { 29635870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov LookupKeySegment segment = segments.get(i); 29645870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (segment.sourceIdLookup && accountHashCode == segment.accountHashCode 29655870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov && segment.key.equals(sourceId)) { 29665870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov segment.contactId = c.getLong(LookupBySourceIdQuery.CONTACT_ID); 29675870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov break; 29685870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29695870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29705870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29715870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } finally { 29725870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov c.close(); 29735870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29745870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29755870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return getMostReferencedContactId(segments); 29765870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29775870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29785870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private interface LookupByDisplayNameQuery { 29795870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String TABLE = Tables.NAME_LOOKUP_JOIN_RAW_CONTACTS; 29805870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29815870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String COLUMNS[] = { 29825870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov RawContacts.CONTACT_ID, 29835870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov RawContacts.ACCOUNT_TYPE, 29845870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov RawContacts.ACCOUNT_NAME, 29855870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov NameLookupColumns.NORMALIZED_NAME 29865870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov }; 29875870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29885870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int CONTACT_ID = 0; 29895870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int ACCOUNT_TYPE = 1; 29905870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int ACCOUNT_NAME = 2; 29915870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int NORMALIZED_NAME = 3; 29925870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 29935870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 29945870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private long lookupContactIdByDisplayNames(SQLiteDatabase db, 29955870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov ArrayList<LookupKeySegment> segments) { 29965870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int displayNameCount = 0; 29975870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov for (int i = 0; i < segments.size(); i++) { 29985870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov LookupKeySegment segment = segments.get(i); 29995870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (!segment.sourceIdLookup) { 30005870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov displayNameCount++; 30015870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30025870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30035870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 30045870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (displayNameCount == 0) { 30055870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return -1; 30065870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30075870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 30085870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov // First try sync ids 30095870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov StringBuilder sb = new StringBuilder(); 30105870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(NameLookupColumns.NORMALIZED_NAME + " IN ("); 30115870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov for (int i = 0; i < segments.size(); i++) { 30125870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov LookupKeySegment segment = segments.get(i); 30135870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (!segment.sourceIdLookup) { 30145870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, segment.key); 30155870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(","); 30165870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30175870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30185870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.setLength(sb.length() - 1); // Last comma 30195870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.append(") AND " + NameLookupColumns.NAME_TYPE + "=" + NameLookupType.NAME_COLLATION_KEY 30205870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov + " AND " + RawContacts.CONTACT_ID + " NOT NULL"); 30215870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 30225870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov Cursor c = db.query(LookupByDisplayNameQuery.TABLE, LookupByDisplayNameQuery.COLUMNS, 30235870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov sb.toString(), null, null, null, null); 30245870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov try { 30255870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov while (c.moveToNext()) { 30265870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String accountType = c.getString(LookupByDisplayNameQuery.ACCOUNT_TYPE); 30275870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String accountName = c.getString(LookupByDisplayNameQuery.ACCOUNT_NAME); 30285870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int accountHashCode = 30295870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov ContactLookupKey.getAccountHashCode(accountType, accountName); 30305870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov String name = c.getString(LookupByDisplayNameQuery.NORMALIZED_NAME); 30315870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov for (int i = 0; i < segments.size(); i++) { 30325870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov LookupKeySegment segment = segments.get(i); 30335870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (!segment.sourceIdLookup && accountHashCode == segment.accountHashCode 30345870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov && segment.key.equals(name)) { 30355870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov segment.contactId = c.getLong(LookupByDisplayNameQuery.CONTACT_ID); 30365870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov break; 30375870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30385870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30395870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30405870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } finally { 30415870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov c.close(); 30425870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30435870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 30445870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return getMostReferencedContactId(segments); 30455870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30465870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 30475870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov /** 30485870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov * Returns the contact ID that is mentioned the highest number of times. 30495870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov */ 30505870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov private long getMostReferencedContactId(ArrayList<LookupKeySegment> segments) { 30515870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov Collections.sort(segments); 30525870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 30535870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov long bestContactId = -1; 30545870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int bestRefCount = 0; 30555870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 30565870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov long contactId = -1; 30575870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int count = 0; 30585870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 30595870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov int segmentCount = segments.size(); 30605870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov for (int i = 0; i < segmentCount; i++) { 30615870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov LookupKeySegment segment = segments.get(i); 30625870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (segment.contactId != -1) { 30635870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (segment.contactId == contactId) { 30645870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov count++; 30655870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } else { 30665870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (count > bestRefCount) { 30675870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov bestContactId = contactId; 30685870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov bestRefCount = count; 30695870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30705870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov contactId = segment.contactId; 30715870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov count = 1; 30725870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30735870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30745870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30755870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov if (count > bestRefCount) { 30765870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return contactId; 30775870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } else { 30785870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov return bestContactId; 30795870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30805870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov } 30815870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov 3082ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov private void setTablesAndProjectionMapForContacts(SQLiteQueryBuilder qb, String[] projection) { 3083ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov String contactView = mOpenHelper.getContactView(); 3084ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov boolean needsPresence = mOpenHelper.isInProjection(projection, Contacts.PRESENCE_STATUS, 3085ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov Contacts.PRESENCE_CUSTOM_STATUS); 3086ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov if (!needsPresence) { 3087ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov qb.setTables(contactView); 3088ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov qb.setProjectionMap(sContactsProjectionMap); 3089ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } else { 3090ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov qb.setTables(contactView + " LEFT OUTER JOIN " + Tables.AGGREGATED_PRESENCE + " ON (" 3091ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov + Contacts._ID + " = " + AggregatedPresenceColumns.CONTACT_ID + ") "); 3092ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov qb.setProjectionMap(sContactsWithPresenceProjectionMap); 3093ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov 3094ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3095ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3096ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov 30974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private void appendAccountFromParameter(SQLiteQueryBuilder qb, Uri uri) { 30984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME); 30994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final String accountType = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE); 31004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (!TextUtils.isEmpty(accountName)) { 31014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(RawContacts.ACCOUNT_NAME + "=" 31024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DatabaseUtils.sqlEscapeString(accountName) + " AND " 31034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.ACCOUNT_TYPE + "=" 31044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DatabaseUtils.sqlEscapeString(accountType)); 31054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } else { 31064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere("1"); 31074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 31084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 31094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 3110e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong private String appendAccountToSelection(Uri uri, String selection) { 3111e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong final String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME); 3112e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong final String accountType = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE); 3113e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong if (!TextUtils.isEmpty(accountName)) { 3114e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong StringBuilder selectionSb = new StringBuilder(RawContacts.ACCOUNT_NAME + "=" 3115e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong + DatabaseUtils.sqlEscapeString(accountName) + " AND " 3116e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong + RawContacts.ACCOUNT_TYPE + "=" 3117e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong + DatabaseUtils.sqlEscapeString(accountType)); 3118e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong if (!TextUtils.isEmpty(selection)) { 3119e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong selectionSb.append(" AND ("); 3120e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong selectionSb.append(selection); 3121e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong selectionSb.append(')'); 3122e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong } 3123e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong return selectionSb.toString(); 3124e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong } else { 3125e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong return selection; 3126e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong } 3127e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong } 3128e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong 31297e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana /** 3130c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * Gets the value of the "limit" URI query parameter. 3131c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * 3132c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * @return A string containing a non-negative integer, or <code>null</code> if 3133c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * the parameter is not set, or is set to an invalid value. 3134c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov */ 3135c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov private String getLimit(Uri url) { 3136c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String limitParam = url.getQueryParameter("limit"); 3137c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov if (limitParam == null) { 3138c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return null; 3139c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 3140c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // make sure that the limit is a non-negative integer 3141c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov try { 3142c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov int l = Integer.parseInt(limitParam); 3143c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov if (l < 0) { 3144c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov Log.w(TAG, "Invalid limit parameter: " + limitParam); 3145c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return null; 3146c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 3147c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return String.valueOf(l); 3148c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } catch (NumberFormatException ex) { 3149c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov Log.w(TAG, "Invalid limit parameter: " + limitParam); 3150c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return null; 3151c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 3152c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 3153c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 315400ec508630251d6c6e3746469c9428f5a8cd5996Jeff Sharkey String getContactsRestrictions() { 31554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (mOpenHelper.hasRestrictedAccess()) { 315670b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov return "1"; 315770b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov } else { 31586cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov return RawContacts.IS_RESTRICTED + "=0"; 315970b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov } 316070b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov } 316170b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov 316270b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov public String getContactsRestrictionExceptionAsNestedQuery(String contactIdColumn) { 31634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (mOpenHelper.hasRestrictedAccess()) { 316470b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov return "1"; 316567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey } else { 31665ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov return "(SELECT " + RawContacts.IS_RESTRICTED + " FROM " + Tables.RAW_CONTACTS 31675ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " WHERE " + RawContactsColumns.CONCRETE_ID + "=" + contactIdColumn + ")=0"; 3168619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 3169619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 3170619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 3171b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov @Override 3172b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException { 3173b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov int match = sUriMatcher.match(uri); 3174b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov switch (match) { 3175b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov case CONTACTS_PHOTO: 3176b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov if (!"r".equals(mode)) { 3177b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov throw new FileNotFoundException("Mode " + mode + " not supported."); 3178b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov } 3179b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov 3180b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov long contactId = Long.parseLong(uri.getPathSegments().get(1)); 3181b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov 3182b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov String sql = 3183b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov "SELECT " + Photo.PHOTO + " FROM " + mOpenHelper.getDataView() + 3184b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov " WHERE " + Data._ID + "=" + Contacts.PHOTO_ID 3185b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov + " AND " + RawContacts.CONTACT_ID + "=" + contactId; 3186b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 3187b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov return SQLiteContentHelper.getBlobColumnAsAssetFile(db, sql, null); 3188b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov 3189b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov default: 3190b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov throw new FileNotFoundException("No file at: " + uri); 3191b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov } 3192b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov } 3193b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov 3194b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov 3195b3f909fee75cb384fc381ec5ce70dd001669f945Dmitri Plotnikov 3196619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 31977e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana * An implementation of EntityIterator that joins the contacts and data tables 31987e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana * and consumes all the data rows for a contact in order to build the Entity for a contact. 31997e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana */ 32007e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana private static class ContactsEntityIterator implements EntityIterator { 32017e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana private final Cursor mEntityCursor; 32027e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana private volatile boolean mIsClosed; 32037e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 32047e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana private static final String[] DATA_KEYS = new String[]{ 32057a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA1, 32067a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA2, 32077a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA3, 32087a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA4, 32097a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA5, 32107a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA6, 32117a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA7, 32127a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA8, 32137a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA9, 32147a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA10, 32157a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA11, 32167a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA12, 32177a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA13, 32187a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA14, 32197a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA15, 32207a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC1, 32217a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC2, 32227a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC3, 32237a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC4}; 32247e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 32257e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana private static final String[] PROJECTION = new String[]{ 32266cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_NAME, 32276cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_TYPE, 32286cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SOURCE_ID, 32296cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.VERSION, 32306cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.DIRTY, 32317a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data._ID, 32327a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.RES_PACKAGE, 32337a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.MIMETYPE, 32347a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA1, 32357a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA2, 32367a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA3, 32377a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA4, 32387a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA5, 32397a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA6, 32407a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA7, 32417a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA8, 32427a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA9, 32437a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA10, 32447a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA11, 32457a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA12, 32467a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA13, 32477a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA14, 32487a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA15, 32497a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC1, 32507a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC2, 32517a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC3, 32527a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC4, 32537a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.RAW_CONTACT_ID, 32547a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.IS_PRIMARY, 32553cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar Data.IS_SUPER_PRIMARY, 32567a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA_VERSION, 32577a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana GroupMembership.GROUP_SOURCE_ID, 32587a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana RawContacts.SYNC1, 32597a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana RawContacts.SYNC2, 32607a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana RawContacts.SYNC3, 326194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana RawContacts.SYNC4, 326238446bf47c5ee2080df69f5fc8a33ad2fa3e61b5Jeff Sharkey RawContacts.DELETED, 3263c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey RawContacts.CONTACT_ID, 3264c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey RawContacts.STARRED}; 3265035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana 3266035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_ACCOUNT_NAME = 0; 3267035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_ACCOUNT_TYPE = 1; 3268035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_SOURCE_ID = 2; 3269035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_VERSION = 3; 3270035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_DIRTY = 4; 3271035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_DATA_ID = 5; 327267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey private static final int COLUMN_RES_PACKAGE = 6; 327367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey private static final int COLUMN_MIMETYPE = 7; 327467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey private static final int COLUMN_DATA1 = 8; 32757a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_RAW_CONTACT_ID = 27; 32767a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_IS_PRIMARY = 28; 32773cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar private static final int COLUMN_IS_SUPER_PRIMARY = 29; 32783cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar private static final int COLUMN_DATA_VERSION = 30; 32793cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar private static final int COLUMN_GROUP_SOURCE_ID = 31; 32803cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar private static final int COLUMN_SYNC1 = 32; 32813cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar private static final int COLUMN_SYNC2 = 33; 32823cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar private static final int COLUMN_SYNC3 = 34; 32833cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar private static final int COLUMN_SYNC4 = 35; 32843cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar private static final int COLUMN_DELETED = 36; 32853cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar private static final int COLUMN_CONTACT_ID = 37; 32863cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar private static final int COLUMN_STARRED = 38; 32877e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 32887e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public ContactsEntityIterator(ContactsProvider2 provider, String contactsIdString, Uri uri, 32897e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana String selection, String[] selectionArgs, String sortOrder) { 32907e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana mIsClosed = false; 32917e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 32927e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final String updatedSortOrder = (sortOrder == null) 32937a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana ? Data.RAW_CONTACT_ID 32947a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana : (Data.RAW_CONTACT_ID + "," + sortOrder); 32957e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 32967e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final SQLiteDatabase db = provider.mOpenHelper.getReadableDatabase(); 32977e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 3298226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana qb.setTables(Tables.CONTACT_ENTITIES); 32997e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (contactsIdString != null) { 33005ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov qb.appendWhere(Data.RAW_CONTACT_ID + "=" + contactsIdString); 33017e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 33026cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME); 33036cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String accountType = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE); 3304035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana if (!TextUtils.isEmpty(accountName)) { 33056cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov qb.appendWhere(RawContacts.ACCOUNT_NAME + "=" 3306035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana + DatabaseUtils.sqlEscapeString(accountName) + " AND " 33076cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov + RawContacts.ACCOUNT_TYPE + "=" 3308035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana + DatabaseUtils.sqlEscapeString(accountType)); 3309035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana } 33107e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana mEntityCursor = qb.query(db, PROJECTION, selection, selectionArgs, 33117e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana null, null, updatedSortOrder); 33127e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana mEntityCursor.moveToFirst(); 33137e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 33147e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 3315038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana public void reset() throws RemoteException { 3316038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana if (mIsClosed) { 3317038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana throw new IllegalStateException("calling reset() when the iterator is closed"); 3318038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana } 3319038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana mEntityCursor.moveToFirst(); 3320038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana } 3321038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana 33227e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public void close() { 33237e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (mIsClosed) { 33247e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana throw new IllegalStateException("closing when already closed"); 33257e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 33267e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana mIsClosed = true; 33277e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana mEntityCursor.close(); 33287e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 33297e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 33307e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public boolean hasNext() throws RemoteException { 33317e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (mIsClosed) { 33327e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana throw new IllegalStateException("calling hasNext() when the iterator is closed"); 33337e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 33347e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 33357e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana return !mEntityCursor.isAfterLast(); 33367e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 33377e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 33387e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public Entity next() throws RemoteException { 33397e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (mIsClosed) { 33407e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana throw new IllegalStateException("calling next() when the iterator is closed"); 33417e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 33427e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (!hasNext()) { 33437e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana throw new IllegalStateException("you may only call next() if hasNext() is true"); 33447e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 33457e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 33467e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final SQLiteCursor c = (SQLiteCursor) mEntityCursor; 33477e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 33487a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana final long rawContactId = c.getLong(COLUMN_RAW_CONTACT_ID); 33497e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 33507e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana // we expect the cursor is already at the row we need to read from 33517e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana ContentValues contactValues = new ContentValues(); 33526cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov contactValues.put(RawContacts.ACCOUNT_NAME, c.getString(COLUMN_ACCOUNT_NAME)); 33536cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov contactValues.put(RawContacts.ACCOUNT_TYPE, c.getString(COLUMN_ACCOUNT_TYPE)); 33545ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov contactValues.put(RawContacts._ID, rawContactId); 33556cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov contactValues.put(RawContacts.DIRTY, c.getLong(COLUMN_DIRTY)); 33566cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov contactValues.put(RawContacts.VERSION, c.getLong(COLUMN_VERSION)); 33576cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov contactValues.put(RawContacts.SOURCE_ID, c.getString(COLUMN_SOURCE_ID)); 33587a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana contactValues.put(RawContacts.SYNC1, c.getString(COLUMN_SYNC1)); 33597a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana contactValues.put(RawContacts.SYNC2, c.getString(COLUMN_SYNC2)); 33607a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana contactValues.put(RawContacts.SYNC3, c.getString(COLUMN_SYNC3)); 33617a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana contactValues.put(RawContacts.SYNC4, c.getString(COLUMN_SYNC4)); 336294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana contactValues.put(RawContacts.DELETED, c.getLong(COLUMN_DELETED)); 336338446bf47c5ee2080df69f5fc8a33ad2fa3e61b5Jeff Sharkey contactValues.put(RawContacts.CONTACT_ID, c.getLong(COLUMN_CONTACT_ID)); 3364c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey contactValues.put(RawContacts.STARRED, c.getLong(COLUMN_STARRED)); 33657e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana Entity contact = new Entity(contactValues); 33667e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 33677e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana // read data rows until the contact id changes 33687e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana do { 33697a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana if (rawContactId != c.getLong(COLUMN_RAW_CONTACT_ID)) { 33707e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana break; 33717e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 33727e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana // add the data to to the contact 33737e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana ContentValues dataValues = new ContentValues(); 33747a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data._ID, c.getString(COLUMN_DATA_ID)); 33757a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data.RES_PACKAGE, c.getString(COLUMN_RES_PACKAGE)); 33767a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data.MIMETYPE, c.getString(COLUMN_MIMETYPE)); 33777a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data.IS_PRIMARY, c.getString(COLUMN_IS_PRIMARY)); 33783cb415e7b97c3e318d7a16aaf7cc5c6b825d349aEvan Millar dataValues.put(Data.IS_SUPER_PRIMARY, c.getString(COLUMN_IS_SUPER_PRIMARY)); 33797a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data.DATA_VERSION, c.getLong(COLUMN_DATA_VERSION)); 33809261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (!c.isNull(COLUMN_GROUP_SOURCE_ID)) { 33819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana dataValues.put(GroupMembership.GROUP_SOURCE_ID, 33829261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana c.getString(COLUMN_GROUP_SOURCE_ID)); 33839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 33847a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data.DATA_VERSION, c.getLong(COLUMN_DATA_VERSION)); 33857a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana for (int i = 0; i < DATA_KEYS.length; i++) { 33867e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final int columnIndex = i + COLUMN_DATA1; 33877e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana String key = DATA_KEYS[i]; 33887e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (c.isNull(columnIndex)) { 33897e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana // don't put anything 33907e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } else if (c.isLong(columnIndex)) { 33917e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana dataValues.put(key, c.getLong(columnIndex)); 33927e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } else if (c.isFloat(columnIndex)) { 33937e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana dataValues.put(key, c.getFloat(columnIndex)); 33947e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } else if (c.isString(columnIndex)) { 33957e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana dataValues.put(key, c.getString(columnIndex)); 33967e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } else if (c.isBlob(columnIndex)) { 33977e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana dataValues.put(key, c.getBlob(columnIndex)); 33987e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 33997e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 34007e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana contact.addSubValue(Data.CONTENT_URI, dataValues); 34017e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } while (mEntityCursor.moveToNext()); 34027e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 34037e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana return contact; 34047e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 34057e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 34067e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 3407226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana /** 3408226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana * An implementation of EntityIterator that joins the contacts and data tables 3409226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana * and consumes all the data rows for a contact in order to build the Entity for a contact. 3410226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana */ 3411226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static class GroupsEntityIterator implements EntityIterator { 3412226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private final Cursor mEntityCursor; 3413226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private volatile boolean mIsClosed; 3414226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3415226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final String[] PROJECTION = new String[]{ 3416226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups._ID, 3417226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.ACCOUNT_NAME, 3418226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.ACCOUNT_TYPE, 3419226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.SOURCE_ID, 3420226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.DIRTY, 3421226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.VERSION, 3422226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.RES_PACKAGE, 3423226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.TITLE, 3424226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.TITLE_RES, 34257a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.GROUP_VISIBLE, 34267a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.SYNC1, 34277a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.SYNC2, 34287a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.SYNC3, 34297a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.SYNC4, 34307a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.SYSTEM_ID, 343194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana Groups.NOTES, 343294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana Groups.DELETED}; 3433226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3434226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_ID = 0; 3435226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_ACCOUNT_NAME = 1; 3436226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_ACCOUNT_TYPE = 2; 3437226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_SOURCE_ID = 3; 3438226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_DIRTY = 4; 3439226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_VERSION = 5; 3440226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_RES_PACKAGE = 6; 3441226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_TITLE = 7; 3442226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_TITLE_RES = 8; 3443226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_GROUP_VISIBLE = 9; 34447a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC1 = 10; 34457a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC2 = 11; 34467a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC3 = 12; 34477a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC4 = 13; 34487a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYSTEM_ID = 14; 34497a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_NOTES = 15; 345094021b213e4db367f60b30fcbfe9019e28571784Fred Quintana private static final int COLUMN_DELETED = 16; 3451226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3452226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public GroupsEntityIterator(ContactsProvider2 provider, String groupIdString, Uri uri, 3453226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana String selection, String[] selectionArgs, String sortOrder) { 3454226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mIsClosed = false; 3455226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3456226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final String updatedSortOrder = (sortOrder == null) 3457226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana ? Groups._ID 3458226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana : (Groups._ID + "," + sortOrder); 3459226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3460226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final SQLiteDatabase db = provider.mOpenHelper.getReadableDatabase(); 3461226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 3462226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana qb.setTables(Tables.GROUPS_JOIN_PACKAGES); 3463226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana qb.setProjectionMap(sGroupsProjectionMap); 3464226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (groupIdString != null) { 3465226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana qb.appendWhere(Groups._ID + "=" + groupIdString); 3466226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3467226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final String accountName = uri.getQueryParameter(Groups.ACCOUNT_NAME); 3468226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final String accountType = uri.getQueryParameter(Groups.ACCOUNT_TYPE); 3469226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (!TextUtils.isEmpty(accountName)) { 3470226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana qb.appendWhere(Groups.ACCOUNT_NAME + "=" 3471226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana + DatabaseUtils.sqlEscapeString(accountName) + " AND " 3472226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana + Groups.ACCOUNT_TYPE + "=" 3473226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana + DatabaseUtils.sqlEscapeString(accountType)); 3474226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3475226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mEntityCursor = qb.query(db, PROJECTION, selection, selectionArgs, 3476226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana null, null, updatedSortOrder); 3477226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mEntityCursor.moveToFirst(); 3478226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3479226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3480226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public void close() { 3481226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (mIsClosed) { 3482226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana throw new IllegalStateException("closing when already closed"); 3483226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3484226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mIsClosed = true; 3485226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mEntityCursor.close(); 3486226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3487226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3488226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public boolean hasNext() throws RemoteException { 3489226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (mIsClosed) { 3490226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana throw new IllegalStateException("calling hasNext() when the iterator is closed"); 3491226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3492226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3493226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana return !mEntityCursor.isAfterLast(); 3494226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3495226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3496038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana public void reset() throws RemoteException { 3497038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana if (mIsClosed) { 3498038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana throw new IllegalStateException("calling reset() when the iterator is closed"); 3499038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana } 3500038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana mEntityCursor.moveToFirst(); 3501038c3db1b54dd9313c10c212025d37ca8a9e660fFred Quintana } 3502e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 3503226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public Entity next() throws RemoteException { 3504226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (mIsClosed) { 3505226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana throw new IllegalStateException("calling next() when the iterator is closed"); 3506226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3507226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (!hasNext()) { 3508226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana throw new IllegalStateException("you may only call next() if hasNext() is true"); 3509226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3510226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3511226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final SQLiteCursor c = (SQLiteCursor) mEntityCursor; 3512226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3513226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final long groupId = c.getLong(COLUMN_ID); 3514226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3515226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana // we expect the cursor is already at the row we need to read from 3516226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana ContentValues groupValues = new ContentValues(); 3517226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.ACCOUNT_NAME, c.getString(COLUMN_ACCOUNT_NAME)); 3518226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.ACCOUNT_TYPE, c.getString(COLUMN_ACCOUNT_TYPE)); 3519226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups._ID, groupId); 3520226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.DIRTY, c.getLong(COLUMN_DIRTY)); 3521226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.VERSION, c.getLong(COLUMN_VERSION)); 3522226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.SOURCE_ID, c.getString(COLUMN_SOURCE_ID)); 3523226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.RES_PACKAGE, c.getString(COLUMN_RES_PACKAGE)); 3524226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.TITLE, c.getString(COLUMN_TITLE)); 3525226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.TITLE_RES, c.getString(COLUMN_TITLE_RES)); 3526226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.GROUP_VISIBLE, c.getLong(COLUMN_GROUP_VISIBLE)); 35277a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.SYNC1, c.getString(COLUMN_SYNC1)); 35287a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.SYNC2, c.getString(COLUMN_SYNC2)); 35297a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.SYNC3, c.getString(COLUMN_SYNC3)); 35307a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.SYNC4, c.getString(COLUMN_SYNC4)); 35317a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.SYSTEM_ID, c.getString(COLUMN_SYSTEM_ID)); 353294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana groupValues.put(Groups.DELETED, c.getLong(COLUMN_DELETED)); 35337a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.NOTES, c.getString(COLUMN_NOTES)); 3534226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Entity group = new Entity(groupValues); 3535226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3536226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mEntityCursor.moveToNext(); 3537226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3538226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana return group; 3539226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3540226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3541226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3542a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov @Override 35437e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs, 35447e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana String sortOrder) { 3545568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov waitForAccess(); 3546568904d1cc9acfabac78b6fcbf8a7d5115688174Dmitri Plotnikov 35477e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final int match = sUriMatcher.match(uri); 35487e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana switch (match) { 35495ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS: 35505ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_ID: 35517e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana String contactsIdString = null; 35525ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov if (match == RAW_CONTACTS_ID) { 35537e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana contactsIdString = uri.getPathSegments().get(1); 35547e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 35557e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 35567e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana return new ContactsEntityIterator(this, contactsIdString, 35577e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana uri, selection, selectionArgs, sortOrder); 3558226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana case GROUPS: 3559226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana case GROUPS_ID: 3560226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana String idString = null; 3561226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (match == GROUPS_ID) { 3562226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana idString = uri.getPathSegments().get(1); 3563226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 3564226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 3565226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana return new GroupsEntityIterator(this, idString, 3566226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana uri, selection, selectionArgs, sortOrder); 35677e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana default: 35687e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana throw new UnsupportedOperationException("Unknown uri: " + uri); 35697e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 35707e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 35717e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 35724f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 35734f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton public String getType(Uri uri) { 3574a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton final int match = sUriMatcher.match(uri); 35754f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton switch (match) { 3576b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov case CONTACTS: 3577b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov case CONTACTS_LOOKUP: 3578be84be1519fe0b73f47c2b2fe9badb8a3e833b28Dmitri Plotnikov return Contacts.CONTENT_TYPE; 3579b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov case CONTACTS_ID: 3580b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov case CONTACTS_LOOKUP_ID: 3581b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov return Contacts.CONTENT_ITEM_TYPE; 3582b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov case RAW_CONTACTS: 3583be84be1519fe0b73f47c2b2fe9badb8a3e833b28Dmitri Plotnikov return RawContacts.CONTENT_TYPE; 3584b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov case RAW_CONTACTS_ID: 3585b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov return RawContacts.CONTENT_ITEM_TYPE; 3586508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey case DATA_ID: 3587b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov return mOpenHelper.getDataMimeType(ContentUris.parseId(uri)); 3588b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov case AGGREGATION_EXCEPTIONS: 3589b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov return AggregationExceptions.CONTENT_TYPE; 3590b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov case AGGREGATION_EXCEPTION_ID: 3591b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov return AggregationExceptions.CONTENT_ITEM_TYPE; 3592b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov case SETTINGS: 3593b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov return Settings.CONTENT_TYPE; 3594b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov case AGGREGATION_SUGGESTIONS: 3595b4cfef6f658ecade496351107f6ed2a4818f3e3aDmitri Plotnikov return Contacts.CONTENT_TYPE; 3596c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov case SEARCH_SUGGESTIONS: 3597c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return SearchManager.SUGGEST_MIME_TYPE; 3598c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov case SEARCH_SHORTCUT: 3599c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return SearchManager.SHORTCUT_MIME_TYPE; 360061efab87c2c8166b3cd69ed1a908d1c0d7271d0bDmitri Plotnikov default: 360161efab87c2c8166b3cd69ed1a908d1c0d7271d0bDmitri Plotnikov return mLegacyApiSupport.getType(uri); 36024f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 36034f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 36047e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 360525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov private void setDisplayName(long rawContactId, String displayName, int bestDisplayNameSource) { 36063cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (displayName != null) { 360725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov mRawContactDisplayNameUpdate.bindString(1, displayName); 36083cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else { 360925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov mRawContactDisplayNameUpdate.bindNull(1); 36103cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 361125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov mRawContactDisplayNameUpdate.bindLong(2, bestDisplayNameSource); 361225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov mRawContactDisplayNameUpdate.bindLong(3, rawContactId); 361325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov mRawContactDisplayNameUpdate.execute(); 36143cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 36153cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 361673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov /** 361773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * Checks the {@link Data#MARK_AS_DIRTY} query parameter. 361873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * 361973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * Returns true if the parameter is missing or is either "true" or "1". 362073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov */ 362173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private boolean shouldMarkRawContactAsDirty(Uri uri) { 362273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (mImportMode) { 362373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov return false; 362473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 362573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 362673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov String param = uri.getQueryParameter(Data.MARK_AS_DIRTY); 362773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov return param == null || (!param.equalsIgnoreCase("false") && !param.equals("0")); 362873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 362973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 363073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov /** 363173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * Sets the {@link RawContacts#DIRTY} for the specified raw contact. 363273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov */ 363373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private void setRawContactDirty(long rawContactId) { 363473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mRawContactDirtyUpdate.bindLong(1, rawContactId); 363573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mRawContactDirtyUpdate.execute(); 363673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 363773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 363873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov /** 363973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * Checks the {@link Groups#MARK_AS_DIRTY} query parameter. 364073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * 364173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * Returns true if the parameter is missing or is either "true" or "1". 364273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov */ 364373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private boolean shouldMarkGroupAsDirty(Uri uri) { 364473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (mImportMode) { 364573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov return false; 364673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 364773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 36482971716e6a68660721d45be97bf3bd2dfad1c5efFred Quintana return readBooleanQueryParameter(uri, Groups.MARK_AS_DIRTY, true); 364973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 365073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 3651c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar /* 3652c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * Sets the given dataId record in the "data" table to primary, and resets all data records of 3653c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * the same mimetype and under the same contact to not be primary. 3654c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * 3655c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * @param dataId the id of the data record to be set to primary. 3656c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar */ 3657653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov private void setIsPrimary(long rawContactId, long dataId, long mimeTypeId) { 3658c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetPrimaryStatement.bindLong(1, dataId); 3659653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov mSetPrimaryStatement.bindLong(2, mimeTypeId); 3660653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov mSetPrimaryStatement.bindLong(3, rawContactId); 3661c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetPrimaryStatement.execute(); 3662c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar } 3663c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar 3664c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar /* 3665c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * Sets the given dataId record in the "data" table to "super primary", and resets all data 3666c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * records of the same mimetype and under the same aggregate to not be "super primary". 3667c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * 3668c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * @param dataId the id of the data record to be set to primary. 3669c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar */ 3670653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov private void setIsSuperPrimary(long rawContactId, long dataId, long mimeTypeId) { 3671c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetSuperPrimaryStatement.bindLong(1, dataId); 3672653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov mSetSuperPrimaryStatement.bindLong(2, mimeTypeId); 3673653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov mSetSuperPrimaryStatement.bindLong(3, rawContactId); 3674c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetSuperPrimaryStatement.execute(); 3675c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar } 3676ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar 3677e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov private void appendContactByFilterAsNestedQuery(StringBuilder sb, String filterParam) { 3678e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov sb.append("(SELECT DISTINCT " + RawContacts.CONTACT_ID + " FROM " + Tables.RAW_CONTACTS 3679e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " JOIN name_lookup ON(" + RawContactsColumns.CONCRETE_ID + "=raw_contact_id)" 3680e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " WHERE normalized_name GLOB '"); 3681e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov sb.append(NameNormalizer.normalize(filterParam)); 3682e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov sb.append("*')"); 3683e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov } 3684e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 36855ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public String getRawContactsByFilterAsNestedQuery(String filterParam) { 3686c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov StringBuilder sb = new StringBuilder(); 3687c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov appendRawContactsByFilterAsNestedQuery(sb, filterParam, null); 3688c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return sb.toString(); 3689c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 3690c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3691a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov public void appendRawContactsByFilterAsNestedQuery(StringBuilder sb, String filterParam, 3692c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String limit) { 3693c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sb.append("(SELECT DISTINCT raw_contact_id FROM name_lookup WHERE normalized_name GLOB '"); 3694c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sb.append(NameNormalizer.normalize(filterParam)); 3695c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sb.append("*'"); 3696c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov if (limit != null) { 3697c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sb.append(" LIMIT ").append(limit); 3698c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 3699c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sb.append(")"); 3700ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 3701ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar 37024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 37034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * Inserts an argument at the beginning of the selection arg list. 37044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 37054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private String[] insertSelectionArg(String[] selectionArgs, String arg) { 3706b67163a1088f09c59f324350662eb18772fac6b6Evan Millar if (selectionArgs == null) { 3707b67163a1088f09c59f324350662eb18772fac6b6Evan Millar return new String[] {arg}; 3708b67163a1088f09c59f324350662eb18772fac6b6Evan Millar } else { 3709b67163a1088f09c59f324350662eb18772fac6b6Evan Millar int newLength = selectionArgs.length + 1; 3710b67163a1088f09c59f324350662eb18772fac6b6Evan Millar String[] newSelectionArgs = new String[newLength]; 37114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov newSelectionArgs[0] = arg; 37124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov System.arraycopy(selectionArgs, 0, newSelectionArgs, 1, selectionArgs.length); 3713b67163a1088f09c59f324350662eb18772fac6b6Evan Millar return newSelectionArgs; 3714b67163a1088f09c59f324350662eb18772fac6b6Evan Millar } 3715b67163a1088f09c59f324350662eb18772fac6b6Evan Millar } 3716caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov 3717caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov protected Account getDefaultAccount() { 3718caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov AccountManager accountManager = AccountManager.get(getContext()); 3719caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov try { 3720df9fd6b239de5829b04cb413e4dfa3e6da649c38Fred Quintana Account[] accounts = accountManager.getAccountsByTypeAndFeatures(DEFAULT_ACCOUNT_TYPE, 3721df9fd6b239de5829b04cb413e4dfa3e6da649c38Fred Quintana new String[] {FEATURE_LEGACY_HOSTED_OR_GOOGLE}, null, null).getResult(); 3722caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov if (accounts != null && accounts.length > 0) { 3723caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov return accounts[0]; 3724caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov } 3725caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov } catch (Throwable e) { 37266f7446a25ecb55ee213eaa7702837cdf32e68777Dmitri Plotnikov Log.e(TAG, "Cannot determine the default account for contacts compatibility", e); 3727caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov } 37286f7446a25ecb55ee213eaa7702837cdf32e68777Dmitri Plotnikov return null; 3729caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov } 37304f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton} 3731