1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.providers.contacts; 18 19 import com.android.internal.content.SyncStateContentProviderHelper; 20 import com.android.providers.contacts.ContactLookupKey.LookupKeySegment; 21 import com.android.providers.contacts.ContactsDatabaseHelper.AggregatedPresenceColumns; 22 import com.android.providers.contacts.ContactsDatabaseHelper.AggregationExceptionColumns; 23 import com.android.providers.contacts.ContactsDatabaseHelper.Clauses; 24 import com.android.providers.contacts.ContactsDatabaseHelper.ContactsColumns; 25 import com.android.providers.contacts.ContactsDatabaseHelper.ContactsStatusUpdatesColumns; 26 import com.android.providers.contacts.ContactsDatabaseHelper.DataColumns; 27 import com.android.providers.contacts.ContactsDatabaseHelper.DisplayNameSources; 28 import com.android.providers.contacts.ContactsDatabaseHelper.GroupsColumns; 29 import com.android.providers.contacts.ContactsDatabaseHelper.MimetypesColumns; 30 import com.android.providers.contacts.ContactsDatabaseHelper.NameLookupColumns; 31 import com.android.providers.contacts.ContactsDatabaseHelper.NameLookupType; 32 import com.android.providers.contacts.ContactsDatabaseHelper.NicknameLookupColumns; 33 import com.android.providers.contacts.ContactsDatabaseHelper.PhoneColumns; 34 import com.android.providers.contacts.ContactsDatabaseHelper.PhoneLookupColumns; 35 import com.android.providers.contacts.ContactsDatabaseHelper.PresenceColumns; 36 import com.android.providers.contacts.ContactsDatabaseHelper.RawContactsColumns; 37 import com.android.providers.contacts.ContactsDatabaseHelper.SettingsColumns; 38 import com.android.providers.contacts.ContactsDatabaseHelper.StatusUpdatesColumns; 39 import com.android.providers.contacts.ContactsDatabaseHelper.Tables; 40 import com.google.android.collect.Lists; 41 import com.google.android.collect.Maps; 42 import com.google.android.collect.Sets; 43 44 import android.accounts.Account; 45 import android.accounts.AccountManager; 46 import android.accounts.OnAccountsUpdateListener; 47 import android.app.SearchManager; 48 import android.content.ContentProviderOperation; 49 import android.content.ContentProviderResult; 50 import android.content.ContentResolver; 51 import android.content.ContentUris; 52 import android.content.ContentValues; 53 import android.content.Context; 54 import android.content.Entity; 55 import android.content.EntityIterator; 56 import android.content.IContentService; 57 import android.content.OperationApplicationException; 58 import android.content.SharedPreferences; 59 import android.content.SyncAdapterType; 60 import android.content.UriMatcher; 61 import android.content.SharedPreferences.Editor; 62 import android.content.res.AssetFileDescriptor; 63 import android.database.Cursor; 64 import android.database.DatabaseUtils; 65 import android.database.sqlite.SQLiteConstraintException; 66 import android.database.sqlite.SQLiteContentHelper; 67 import android.database.sqlite.SQLiteCursor; 68 import android.database.sqlite.SQLiteDatabase; 69 import android.database.sqlite.SQLiteQueryBuilder; 70 import android.database.sqlite.SQLiteStatement; 71 import android.net.Uri; 72 import android.os.Bundle; 73 import android.os.MemoryFile; 74 import android.os.RemoteException; 75 import android.os.SystemProperties; 76 import android.pim.vcard.VCardComposer; 77 import android.preference.PreferenceManager; 78 import android.provider.BaseColumns; 79 import android.provider.ContactsContract; 80 import android.provider.LiveFolders; 81 import android.provider.OpenableColumns; 82 import android.provider.SyncStateContract; 83 import android.provider.ContactsContract.AggregationExceptions; 84 import android.provider.ContactsContract.Contacts; 85 import android.provider.ContactsContract.Data; 86 import android.provider.ContactsContract.Groups; 87 import android.provider.ContactsContract.PhoneLookup; 88 import android.provider.ContactsContract.RawContacts; 89 import android.provider.ContactsContract.Settings; 90 import android.provider.ContactsContract.StatusUpdates; 91 import android.provider.ContactsContract.CommonDataKinds.BaseTypes; 92 import android.provider.ContactsContract.CommonDataKinds.Email; 93 import android.provider.ContactsContract.CommonDataKinds.GroupMembership; 94 import android.provider.ContactsContract.CommonDataKinds.Im; 95 import android.provider.ContactsContract.CommonDataKinds.Nickname; 96 import android.provider.ContactsContract.CommonDataKinds.Organization; 97 import android.provider.ContactsContract.CommonDataKinds.Phone; 98 import android.provider.ContactsContract.CommonDataKinds.Photo; 99 import android.provider.ContactsContract.CommonDataKinds.StructuredName; 100 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 101 import android.telephony.PhoneNumberUtils; 102 import android.text.TextUtils; 103 import android.text.util.Rfc822Token; 104 import android.text.util.Rfc822Tokenizer; 105 import android.util.Log; 106 107 import java.io.ByteArrayOutputStream; 108 import java.io.FileNotFoundException; 109 import java.io.IOException; 110 import java.io.OutputStream; 111 import java.lang.ref.SoftReference; 112 import java.util.ArrayList; 113 import java.util.Collections; 114 import java.util.HashMap; 115 import java.util.HashSet; 116 import java.util.List; 117 import java.util.Locale; 118 import java.util.Map; 119 import java.util.Set; 120 import java.util.concurrent.CountDownLatch; 121 122 /** 123 * Contacts content provider. The contract between this provider and applications 124 * is defined in {@link ContactsContract}. 125 */ 126 public class ContactsProvider2 extends SQLiteContentProvider implements OnAccountsUpdateListener { 127 128 private static final String TAG = "ContactsProvider"; 129 130 private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE); 131 132 // TODO: carefully prevent all incoming nested queries; they can be gaping security holes 133 // TODO: check for restricted flag during insert(), update(), and delete() calls 134 135 /** Default for the maximum number of returned aggregation suggestions. */ 136 private static final int DEFAULT_MAX_SUGGESTIONS = 5; 137 138 /** 139 * Shared preference key for the legacy contact import version. The need for a version 140 * as opposed to a boolean flag is that if we discover bugs in the contact import process, 141 * we can trigger re-import by incrementing the import version. 142 */ 143 private static final String PREF_CONTACTS_IMPORTED = "contacts_imported_v1"; 144 private static final int PREF_CONTACTS_IMPORT_VERSION = 1; 145 146 private static final String AGGREGATE_CONTACTS = "sync.contacts.aggregate"; 147 148 private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 149 150 private static final String TIMES_CONTACED_SORT_COLUMN = "times_contacted_sort"; 151 152 private static final String STREQUENT_ORDER_BY = Contacts.STARRED + " DESC, " 153 + TIMES_CONTACED_SORT_COLUMN + " DESC, " 154 + Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; 155 private static final String STREQUENT_LIMIT = 156 "(SELECT COUNT(1) FROM " + Tables.CONTACTS + " WHERE " 157 + Contacts.STARRED + "=1) + 25"; 158 159 private static final int CONTACTS = 1000; 160 private static final int CONTACTS_ID = 1001; 161 private static final int CONTACTS_LOOKUP = 1002; 162 private static final int CONTACTS_LOOKUP_ID = 1003; 163 private static final int CONTACTS_DATA = 1004; 164 private static final int CONTACTS_FILTER = 1005; 165 private static final int CONTACTS_STREQUENT = 1006; 166 private static final int CONTACTS_STREQUENT_FILTER = 1007; 167 private static final int CONTACTS_GROUP = 1008; 168 private static final int CONTACTS_PHOTO = 1009; 169 private static final int CONTACTS_AS_VCARD = 1010; 170 171 private static final int RAW_CONTACTS = 2002; 172 private static final int RAW_CONTACTS_ID = 2003; 173 private static final int RAW_CONTACTS_DATA = 2004; 174 private static final int RAW_CONTACT_ENTITY_ID = 2005; 175 176 private static final int DATA = 3000; 177 private static final int DATA_ID = 3001; 178 private static final int PHONES = 3002; 179 private static final int PHONES_ID = 3003; 180 private static final int PHONES_FILTER = 3004; 181 private static final int EMAILS = 3005; 182 private static final int EMAILS_ID = 3006; 183 private static final int EMAILS_LOOKUP = 3007; 184 private static final int EMAILS_FILTER = 3008; 185 private static final int POSTALS = 3009; 186 private static final int POSTALS_ID = 3010; 187 188 private static final int PHONE_LOOKUP = 4000; 189 190 private static final int AGGREGATION_EXCEPTIONS = 6000; 191 private static final int AGGREGATION_EXCEPTION_ID = 6001; 192 193 private static final int STATUS_UPDATES = 7000; 194 private static final int STATUS_UPDATES_ID = 7001; 195 196 private static final int AGGREGATION_SUGGESTIONS = 8000; 197 198 private static final int SETTINGS = 9000; 199 200 private static final int GROUPS = 10000; 201 private static final int GROUPS_ID = 10001; 202 private static final int GROUPS_SUMMARY = 10003; 203 204 private static final int SYNCSTATE = 11000; 205 private static final int SYNCSTATE_ID = 11001; 206 207 private static final int SEARCH_SUGGESTIONS = 12001; 208 private static final int SEARCH_SHORTCUT = 12002; 209 210 private static final int LIVE_FOLDERS_CONTACTS = 14000; 211 private static final int LIVE_FOLDERS_CONTACTS_WITH_PHONES = 14001; 212 private static final int LIVE_FOLDERS_CONTACTS_FAVORITES = 14002; 213 private static final int LIVE_FOLDERS_CONTACTS_GROUP_NAME = 14003; 214 215 private static final int RAW_CONTACT_ENTITIES = 15001; 216 217 private interface ContactsQuery { 218 public static final String TABLE = Tables.RAW_CONTACTS; 219 220 public static final String[] PROJECTION = new String[] { 221 RawContactsColumns.CONCRETE_ID, 222 RawContacts.ACCOUNT_NAME, 223 RawContacts.ACCOUNT_TYPE, 224 }; 225 226 public static final int RAW_CONTACT_ID = 0; 227 public static final int ACCOUNT_NAME = 1; 228 public static final int ACCOUNT_TYPE = 2; 229 } 230 231 private interface DataContactsQuery { 232 public static final String TABLE = "data " 233 + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) " 234 + "JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 235 236 public static final String[] PROJECTION = new String[] { 237 RawContactsColumns.CONCRETE_ID, 238 DataColumns.CONCRETE_ID, 239 ContactsColumns.CONCRETE_ID 240 }; 241 242 public static final int RAW_CONTACT_ID = 0; 243 public static final int DATA_ID = 1; 244 public static final int CONTACT_ID = 2; 245 } 246 247 private interface DisplayNameQuery { 248 public static final String TABLE = Tables.DATA_JOIN_MIMETYPES; 249 250 public static final String[] COLUMNS = new String[] { 251 MimetypesColumns.MIMETYPE, 252 Data.IS_PRIMARY, 253 Data.DATA1, 254 Organization.TITLE, 255 }; 256 257 public static final int MIMETYPE = 0; 258 public static final int IS_PRIMARY = 1; 259 public static final int DATA = 2; 260 public static final int TITLE = 3; 261 } 262 263 private interface DataDeleteQuery { 264 public static final String TABLE = Tables.DATA_JOIN_MIMETYPES; 265 266 public static final String[] CONCRETE_COLUMNS = new String[] { 267 DataColumns.CONCRETE_ID, 268 MimetypesColumns.MIMETYPE, 269 Data.RAW_CONTACT_ID, 270 Data.IS_PRIMARY, 271 Data.DATA1, 272 }; 273 274 public static final String[] COLUMNS = new String[] { 275 Data._ID, 276 MimetypesColumns.MIMETYPE, 277 Data.RAW_CONTACT_ID, 278 Data.IS_PRIMARY, 279 Data.DATA1, 280 }; 281 282 public static final int _ID = 0; 283 public static final int MIMETYPE = 1; 284 public static final int RAW_CONTACT_ID = 2; 285 public static final int IS_PRIMARY = 3; 286 public static final int DATA1 = 4; 287 } 288 289 private interface DataUpdateQuery { 290 String[] COLUMNS = { Data._ID, Data.RAW_CONTACT_ID, Data.MIMETYPE }; 291 292 int _ID = 0; 293 int RAW_CONTACT_ID = 1; 294 int MIMETYPE = 2; 295 } 296 297 298 private interface NicknameLookupQuery { 299 String TABLE = Tables.NICKNAME_LOOKUP; 300 301 String[] COLUMNS = new String[] { 302 NicknameLookupColumns.CLUSTER 303 }; 304 305 int CLUSTER = 0; 306 } 307 308 private interface RawContactsQuery { 309 String TABLE = Tables.RAW_CONTACTS; 310 311 String[] COLUMNS = new String[] { 312 ContactsContract.RawContacts.DELETED 313 }; 314 315 int DELETED = 0; 316 } 317 318 private static final HashMap<String, Integer> sDisplayNameSources; 319 static { 320 sDisplayNameSources = new HashMap<String, Integer>(); sDisplayNameSources.put(StructuredName.CONTENT_ITEM_TYPE, DisplayNameSources.STRUCTURED_NAME)321 sDisplayNameSources.put(StructuredName.CONTENT_ITEM_TYPE, 322 DisplayNameSources.STRUCTURED_NAME); sDisplayNameSources.put(Nickname.CONTENT_ITEM_TYPE, DisplayNameSources.NICKNAME)323 sDisplayNameSources.put(Nickname.CONTENT_ITEM_TYPE, 324 DisplayNameSources.NICKNAME); sDisplayNameSources.put(Organization.CONTENT_ITEM_TYPE, DisplayNameSources.ORGANIZATION)325 sDisplayNameSources.put(Organization.CONTENT_ITEM_TYPE, 326 DisplayNameSources.ORGANIZATION); sDisplayNameSources.put(Phone.CONTENT_ITEM_TYPE, DisplayNameSources.PHONE)327 sDisplayNameSources.put(Phone.CONTENT_ITEM_TYPE, 328 DisplayNameSources.PHONE); sDisplayNameSources.put(Email.CONTENT_ITEM_TYPE, DisplayNameSources.EMAIL)329 sDisplayNameSources.put(Email.CONTENT_ITEM_TYPE, 330 DisplayNameSources.EMAIL); 331 } 332 333 public static final String DEFAULT_ACCOUNT_TYPE = "com.google"; 334 public static final String FEATURE_LEGACY_HOSTED_OR_GOOGLE = "legacy_hosted_or_google"; 335 336 /** Sql where statement for filtering on groups. */ 337 private static final String CONTACTS_IN_GROUP_SELECT = 338 Contacts._ID + " IN " 339 + "(SELECT " + RawContacts.CONTACT_ID 340 + " FROM " + Tables.RAW_CONTACTS 341 + " WHERE " + RawContactsColumns.CONCRETE_ID + " IN " 342 + "(SELECT " + DataColumns.CONCRETE_RAW_CONTACT_ID 343 + " FROM " + Tables.DATA_JOIN_MIMETYPES 344 + " WHERE " + Data.MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 345 + "' AND " + GroupMembership.GROUP_ROW_ID + "=" 346 + "(SELECT " + Tables.GROUPS + "." + Groups._ID 347 + " FROM " + Tables.GROUPS 348 + " WHERE " + Groups.TITLE + "=?)))"; 349 350 /** Contains just BaseColumns._COUNT */ 351 private static final HashMap<String, String> sCountProjectionMap; 352 /** Contains just the contacts columns */ 353 private static final HashMap<String, String> sContactsProjectionMap; 354 /** Used for pushing starred contacts to the top of a times contacted list **/ 355 private static final HashMap<String, String> sStrequentStarredProjectionMap; 356 private static final HashMap<String, String> sStrequentFrequentProjectionMap; 357 /** Contains just the contacts vCard columns */ 358 private static final HashMap<String, String> sContactsVCardProjectionMap; 359 /** Contains just the raw contacts columns */ 360 private static final HashMap<String, String> sRawContactsProjectionMap; 361 /** Contains the columns from the raw contacts entity view*/ 362 private static final HashMap<String, String> sRawContactsEntityProjectionMap; 363 /** Contains columns from the data view */ 364 private static final HashMap<String, String> sDataProjectionMap; 365 /** Contains columns from the data view */ 366 private static final HashMap<String, String> sDistinctDataProjectionMap; 367 /** Contains the data and contacts columns, for joined tables */ 368 private static final HashMap<String, String> sPhoneLookupProjectionMap; 369 /** Contains the just the {@link Groups} columns */ 370 private static final HashMap<String, String> sGroupsProjectionMap; 371 /** Contains {@link Groups} columns along with summary details */ 372 private static final HashMap<String, String> sGroupsSummaryProjectionMap; 373 /** Contains the agg_exceptions columns */ 374 private static final HashMap<String, String> sAggregationExceptionsProjectionMap; 375 /** Contains the agg_exceptions columns */ 376 private static final HashMap<String, String> sSettingsProjectionMap; 377 /** Contains StatusUpdates columns */ 378 private static final HashMap<String, String> sStatusUpdatesProjectionMap; 379 /** Contains Live Folders columns */ 380 private static final HashMap<String, String> sLiveFoldersProjectionMap; 381 382 /** Precompiled sql statement for setting a data record to the primary. */ 383 private SQLiteStatement mSetPrimaryStatement; 384 /** Precompiled sql statement for setting a data record to the super primary. */ 385 private SQLiteStatement mSetSuperPrimaryStatement; 386 /** Precompiled sql statement for incrementing times contacted for a contact */ 387 private SQLiteStatement mContactsLastTimeContactedUpdate; 388 /** Precompiled sql statement for updating a contact display name */ 389 private SQLiteStatement mRawContactDisplayNameUpdate; 390 /** Precompiled sql statement for marking a raw contact as dirty */ 391 private SQLiteStatement mRawContactDirtyUpdate; 392 /** Precompiled sql statement for updating an aggregated status update */ 393 private SQLiteStatement mLastStatusUpdate; 394 private SQLiteStatement mNameLookupInsert; 395 private SQLiteStatement mNameLookupDelete; 396 private SQLiteStatement mStatusUpdateAutoTimestamp; 397 private SQLiteStatement mStatusUpdateInsert; 398 private SQLiteStatement mStatusUpdateReplace; 399 private SQLiteStatement mStatusAttributionUpdate; 400 private SQLiteStatement mStatusUpdateDelete; 401 402 private long mMimeTypeIdEmail; 403 private long mMimeTypeIdIm; 404 private StringBuilder mSb = new StringBuilder(); 405 406 static { 407 // Contacts URI matching table 408 final UriMatcher matcher = sUriMatcher; matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS)409 matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS); matcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID)410 matcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID); matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_DATA)411 matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_DATA); matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions", AGGREGATION_SUGGESTIONS)412 matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions", 413 AGGREGATION_SUGGESTIONS); matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions/*", AGGREGATION_SUGGESTIONS)414 matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions/*", 415 AGGREGATION_SUGGESTIONS); matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/photo", CONTACTS_PHOTO)416 matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/photo", CONTACTS_PHOTO); matcher.addURI(ContactsContract.AUTHORITY, "contacts/filter/*", CONTACTS_FILTER)417 matcher.addURI(ContactsContract.AUTHORITY, "contacts/filter/*", CONTACTS_FILTER); matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*", CONTACTS_LOOKUP)418 matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*", CONTACTS_LOOKUP); matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*/#", CONTACTS_LOOKUP_ID)419 matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*/#", CONTACTS_LOOKUP_ID); matcher.addURI(ContactsContract.AUTHORITY, "contacts/as_vcard/*", CONTACTS_AS_VCARD)420 matcher.addURI(ContactsContract.AUTHORITY, "contacts/as_vcard/*", CONTACTS_AS_VCARD); matcher.addURI(ContactsContract.AUTHORITY, "contacts/strequent/", CONTACTS_STREQUENT)421 matcher.addURI(ContactsContract.AUTHORITY, "contacts/strequent/", CONTACTS_STREQUENT); matcher.addURI(ContactsContract.AUTHORITY, "contacts/strequent/filter/*", CONTACTS_STREQUENT_FILTER)422 matcher.addURI(ContactsContract.AUTHORITY, "contacts/strequent/filter/*", 423 CONTACTS_STREQUENT_FILTER); matcher.addURI(ContactsContract.AUTHORITY, "contacts/group/*", CONTACTS_GROUP)424 matcher.addURI(ContactsContract.AUTHORITY, "contacts/group/*", CONTACTS_GROUP); 425 matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts", RAW_CONTACTS)426 matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts", RAW_CONTACTS); matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#", RAW_CONTACTS_ID)427 matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#", RAW_CONTACTS_ID); matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/data", RAW_CONTACTS_DATA)428 matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/data", RAW_CONTACTS_DATA); matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/entity", RAW_CONTACT_ENTITY_ID)429 matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/entity", RAW_CONTACT_ENTITY_ID); 430 matcher.addURI(ContactsContract.AUTHORITY, "raw_contact_entities", RAW_CONTACT_ENTITIES)431 matcher.addURI(ContactsContract.AUTHORITY, "raw_contact_entities", RAW_CONTACT_ENTITIES); 432 matcher.addURI(ContactsContract.AUTHORITY, "data", DATA)433 matcher.addURI(ContactsContract.AUTHORITY, "data", DATA); matcher.addURI(ContactsContract.AUTHORITY, "data/#", DATA_ID)434 matcher.addURI(ContactsContract.AUTHORITY, "data/#", DATA_ID); matcher.addURI(ContactsContract.AUTHORITY, "data/phones", PHONES)435 matcher.addURI(ContactsContract.AUTHORITY, "data/phones", PHONES); matcher.addURI(ContactsContract.AUTHORITY, "data/phones/#", PHONES_ID)436 matcher.addURI(ContactsContract.AUTHORITY, "data/phones/#", PHONES_ID); matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter", PHONES_FILTER)437 matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter", PHONES_FILTER); matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter/*", PHONES_FILTER)438 matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter/*", PHONES_FILTER); matcher.addURI(ContactsContract.AUTHORITY, "data/emails", EMAILS)439 matcher.addURI(ContactsContract.AUTHORITY, "data/emails", EMAILS); matcher.addURI(ContactsContract.AUTHORITY, "data/emails/#", EMAILS_ID)440 matcher.addURI(ContactsContract.AUTHORITY, "data/emails/#", EMAILS_ID); matcher.addURI(ContactsContract.AUTHORITY, "data/emails/lookup/*", EMAILS_LOOKUP)441 matcher.addURI(ContactsContract.AUTHORITY, "data/emails/lookup/*", EMAILS_LOOKUP); matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter", EMAILS_FILTER)442 matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter", EMAILS_FILTER); matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter/*", EMAILS_FILTER)443 matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter/*", EMAILS_FILTER); matcher.addURI(ContactsContract.AUTHORITY, "data/postals", POSTALS)444 matcher.addURI(ContactsContract.AUTHORITY, "data/postals", POSTALS); matcher.addURI(ContactsContract.AUTHORITY, "data/postals/#", POSTALS_ID)445 matcher.addURI(ContactsContract.AUTHORITY, "data/postals/#", POSTALS_ID); 446 matcher.addURI(ContactsContract.AUTHORITY, "groups", GROUPS)447 matcher.addURI(ContactsContract.AUTHORITY, "groups", GROUPS); matcher.addURI(ContactsContract.AUTHORITY, "groups/#", GROUPS_ID)448 matcher.addURI(ContactsContract.AUTHORITY, "groups/#", GROUPS_ID); matcher.addURI(ContactsContract.AUTHORITY, "groups_summary", GROUPS_SUMMARY)449 matcher.addURI(ContactsContract.AUTHORITY, "groups_summary", GROUPS_SUMMARY); 450 matcher.addURI(ContactsContract.AUTHORITY, SyncStateContentProviderHelper.PATH, SYNCSTATE)451 matcher.addURI(ContactsContract.AUTHORITY, SyncStateContentProviderHelper.PATH, SYNCSTATE); matcher.addURI(ContactsContract.AUTHORITY, SyncStateContentProviderHelper.PATH + "/#", SYNCSTATE_ID)452 matcher.addURI(ContactsContract.AUTHORITY, SyncStateContentProviderHelper.PATH + "/#", 453 SYNCSTATE_ID); 454 matcher.addURI(ContactsContract.AUTHORITY, "phone_lookup/*", PHONE_LOOKUP)455 matcher.addURI(ContactsContract.AUTHORITY, "phone_lookup/*", PHONE_LOOKUP); matcher.addURI(ContactsContract.AUTHORITY, "aggregation_exceptions", AGGREGATION_EXCEPTIONS)456 matcher.addURI(ContactsContract.AUTHORITY, "aggregation_exceptions", 457 AGGREGATION_EXCEPTIONS); matcher.addURI(ContactsContract.AUTHORITY, "aggregation_exceptions/*", AGGREGATION_EXCEPTION_ID)458 matcher.addURI(ContactsContract.AUTHORITY, "aggregation_exceptions/*", 459 AGGREGATION_EXCEPTION_ID); 460 matcher.addURI(ContactsContract.AUTHORITY, "settings", SETTINGS)461 matcher.addURI(ContactsContract.AUTHORITY, "settings", SETTINGS); 462 matcher.addURI(ContactsContract.AUTHORITY, "status_updates", STATUS_UPDATES)463 matcher.addURI(ContactsContract.AUTHORITY, "status_updates", STATUS_UPDATES); matcher.addURI(ContactsContract.AUTHORITY, "status_updates/#", STATUS_UPDATES_ID)464 matcher.addURI(ContactsContract.AUTHORITY, "status_updates/#", STATUS_UPDATES_ID); 465 matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGESTIONS)466 matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, 467 SEARCH_SUGGESTIONS); matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGESTIONS)468 matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", 469 SEARCH_SUGGESTIONS); matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/#", SEARCH_SHORTCUT)470 matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/#", 471 SEARCH_SHORTCUT); 472 matcher.addURI(ContactsContract.AUTHORITY, "live_folders/contacts", LIVE_FOLDERS_CONTACTS)473 matcher.addURI(ContactsContract.AUTHORITY, "live_folders/contacts", 474 LIVE_FOLDERS_CONTACTS); matcher.addURI(ContactsContract.AUTHORITY, "live_folders/contacts/*", LIVE_FOLDERS_CONTACTS_GROUP_NAME)475 matcher.addURI(ContactsContract.AUTHORITY, "live_folders/contacts/*", 476 LIVE_FOLDERS_CONTACTS_GROUP_NAME); matcher.addURI(ContactsContract.AUTHORITY, "live_folders/contacts_with_phones", LIVE_FOLDERS_CONTACTS_WITH_PHONES)477 matcher.addURI(ContactsContract.AUTHORITY, "live_folders/contacts_with_phones", 478 LIVE_FOLDERS_CONTACTS_WITH_PHONES); matcher.addURI(ContactsContract.AUTHORITY, "live_folders/favorites", LIVE_FOLDERS_CONTACTS_FAVORITES)479 matcher.addURI(ContactsContract.AUTHORITY, "live_folders/favorites", 480 LIVE_FOLDERS_CONTACTS_FAVORITES); 481 } 482 483 static { 484 sCountProjectionMap = new HashMap<String, String>(); sCountProjectionMap.put(BaseColumns._COUNT, "COUNT(*)")485 sCountProjectionMap.put(BaseColumns._COUNT, "COUNT(*)"); 486 487 sContactsProjectionMap = new HashMap<String, String>(); sContactsProjectionMap.put(Contacts._ID, Contacts._ID)488 sContactsProjectionMap.put(Contacts._ID, Contacts._ID); sContactsProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME)489 sContactsProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME); sContactsProjectionMap.put(Contacts.LAST_TIME_CONTACTED, Contacts.LAST_TIME_CONTACTED)490 sContactsProjectionMap.put(Contacts.LAST_TIME_CONTACTED, Contacts.LAST_TIME_CONTACTED); sContactsProjectionMap.put(Contacts.TIMES_CONTACTED, Contacts.TIMES_CONTACTED)491 sContactsProjectionMap.put(Contacts.TIMES_CONTACTED, Contacts.TIMES_CONTACTED); sContactsProjectionMap.put(Contacts.STARRED, Contacts.STARRED)492 sContactsProjectionMap.put(Contacts.STARRED, Contacts.STARRED); sContactsProjectionMap.put(Contacts.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP)493 sContactsProjectionMap.put(Contacts.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP); sContactsProjectionMap.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID)494 sContactsProjectionMap.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID); sContactsProjectionMap.put(Contacts.CUSTOM_RINGTONE, Contacts.CUSTOM_RINGTONE)495 sContactsProjectionMap.put(Contacts.CUSTOM_RINGTONE, Contacts.CUSTOM_RINGTONE); sContactsProjectionMap.put(Contacts.HAS_PHONE_NUMBER, Contacts.HAS_PHONE_NUMBER)496 sContactsProjectionMap.put(Contacts.HAS_PHONE_NUMBER, Contacts.HAS_PHONE_NUMBER); sContactsProjectionMap.put(Contacts.SEND_TO_VOICEMAIL, Contacts.SEND_TO_VOICEMAIL)497 sContactsProjectionMap.put(Contacts.SEND_TO_VOICEMAIL, Contacts.SEND_TO_VOICEMAIL); sContactsProjectionMap.put(Contacts.LOOKUP_KEY, Contacts.LOOKUP_KEY)498 sContactsProjectionMap.put(Contacts.LOOKUP_KEY, Contacts.LOOKUP_KEY); 499 500 // Handle projections for Contacts-level statuses addProjection(sContactsProjectionMap, Contacts.CONTACT_PRESENCE, Tables.AGGREGATED_PRESENCE + "." + StatusUpdates.PRESENCE)501 addProjection(sContactsProjectionMap, Contacts.CONTACT_PRESENCE, 502 Tables.AGGREGATED_PRESENCE + "." + StatusUpdates.PRESENCE); addProjection(sContactsProjectionMap, Contacts.CONTACT_STATUS, ContactsStatusUpdatesColumns.CONCRETE_STATUS)503 addProjection(sContactsProjectionMap, Contacts.CONTACT_STATUS, 504 ContactsStatusUpdatesColumns.CONCRETE_STATUS); addProjection(sContactsProjectionMap, Contacts.CONTACT_STATUS_TIMESTAMP, ContactsStatusUpdatesColumns.CONCRETE_STATUS_TIMESTAMP)505 addProjection(sContactsProjectionMap, Contacts.CONTACT_STATUS_TIMESTAMP, 506 ContactsStatusUpdatesColumns.CONCRETE_STATUS_TIMESTAMP); addProjection(sContactsProjectionMap, Contacts.CONTACT_STATUS_RES_PACKAGE, ContactsStatusUpdatesColumns.CONCRETE_STATUS_RES_PACKAGE)507 addProjection(sContactsProjectionMap, Contacts.CONTACT_STATUS_RES_PACKAGE, 508 ContactsStatusUpdatesColumns.CONCRETE_STATUS_RES_PACKAGE); addProjection(sContactsProjectionMap, Contacts.CONTACT_STATUS_LABEL, ContactsStatusUpdatesColumns.CONCRETE_STATUS_LABEL)509 addProjection(sContactsProjectionMap, Contacts.CONTACT_STATUS_LABEL, 510 ContactsStatusUpdatesColumns.CONCRETE_STATUS_LABEL); addProjection(sContactsProjectionMap, Contacts.CONTACT_STATUS_ICON, ContactsStatusUpdatesColumns.CONCRETE_STATUS_ICON)511 addProjection(sContactsProjectionMap, Contacts.CONTACT_STATUS_ICON, 512 ContactsStatusUpdatesColumns.CONCRETE_STATUS_ICON); 513 514 sStrequentStarredProjectionMap = new HashMap<String, String>(sContactsProjectionMap); sStrequentStarredProjectionMap.put(TIMES_CONTACED_SORT_COLUMN, Long.MAX_VALUE + " AS " + TIMES_CONTACED_SORT_COLUMN)515 sStrequentStarredProjectionMap.put(TIMES_CONTACED_SORT_COLUMN, 516 Long.MAX_VALUE + " AS " + TIMES_CONTACED_SORT_COLUMN); 517 518 sStrequentFrequentProjectionMap = new HashMap<String, String>(sContactsProjectionMap); sStrequentFrequentProjectionMap.put(TIMES_CONTACED_SORT_COLUMN, Contacts.TIMES_CONTACTED + " AS " + TIMES_CONTACED_SORT_COLUMN)519 sStrequentFrequentProjectionMap.put(TIMES_CONTACED_SORT_COLUMN, 520 Contacts.TIMES_CONTACTED + " AS " + TIMES_CONTACED_SORT_COLUMN); 521 522 sContactsVCardProjectionMap = Maps.newHashMap(); sContactsVCardProjectionMap.put(OpenableColumns.DISPLAY_NAME, Contacts.DISPLAY_NAME + " || '.vcf' AS " + OpenableColumns.DISPLAY_NAME)523 sContactsVCardProjectionMap.put(OpenableColumns.DISPLAY_NAME, Contacts.DISPLAY_NAME 524 + " || '.vcf' AS " + OpenableColumns.DISPLAY_NAME); sContactsVCardProjectionMap.put(OpenableColumns.SIZE, "0 AS " + OpenableColumns.SIZE)525 sContactsVCardProjectionMap.put(OpenableColumns.SIZE, "0 AS " + OpenableColumns.SIZE); 526 527 sRawContactsProjectionMap = new HashMap<String, String>(); sRawContactsProjectionMap.put(RawContacts._ID, RawContacts._ID)528 sRawContactsProjectionMap.put(RawContacts._ID, RawContacts._ID); sRawContactsProjectionMap.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID)529 sRawContactsProjectionMap.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID); sRawContactsProjectionMap.put(RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_NAME)530 sRawContactsProjectionMap.put(RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_NAME); sRawContactsProjectionMap.put(RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_TYPE)531 sRawContactsProjectionMap.put(RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_TYPE); sRawContactsProjectionMap.put(RawContacts.SOURCE_ID, RawContacts.SOURCE_ID)532 sRawContactsProjectionMap.put(RawContacts.SOURCE_ID, RawContacts.SOURCE_ID); sRawContactsProjectionMap.put(RawContacts.VERSION, RawContacts.VERSION)533 sRawContactsProjectionMap.put(RawContacts.VERSION, RawContacts.VERSION); sRawContactsProjectionMap.put(RawContacts.DIRTY, RawContacts.DIRTY)534 sRawContactsProjectionMap.put(RawContacts.DIRTY, RawContacts.DIRTY); sRawContactsProjectionMap.put(RawContacts.DELETED, RawContacts.DELETED)535 sRawContactsProjectionMap.put(RawContacts.DELETED, RawContacts.DELETED); sRawContactsProjectionMap.put(RawContacts.TIMES_CONTACTED, RawContacts.TIMES_CONTACTED)536 sRawContactsProjectionMap.put(RawContacts.TIMES_CONTACTED, RawContacts.TIMES_CONTACTED); sRawContactsProjectionMap.put(RawContacts.LAST_TIME_CONTACTED, RawContacts.LAST_TIME_CONTACTED)537 sRawContactsProjectionMap.put(RawContacts.LAST_TIME_CONTACTED, 538 RawContacts.LAST_TIME_CONTACTED); sRawContactsProjectionMap.put(RawContacts.CUSTOM_RINGTONE, RawContacts.CUSTOM_RINGTONE)539 sRawContactsProjectionMap.put(RawContacts.CUSTOM_RINGTONE, RawContacts.CUSTOM_RINGTONE); sRawContactsProjectionMap.put(RawContacts.SEND_TO_VOICEMAIL, RawContacts.SEND_TO_VOICEMAIL)540 sRawContactsProjectionMap.put(RawContacts.SEND_TO_VOICEMAIL, RawContacts.SEND_TO_VOICEMAIL); sRawContactsProjectionMap.put(RawContacts.STARRED, RawContacts.STARRED)541 sRawContactsProjectionMap.put(RawContacts.STARRED, RawContacts.STARRED); sRawContactsProjectionMap.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE)542 sRawContactsProjectionMap.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE); sRawContactsProjectionMap.put(RawContacts.SYNC1, RawContacts.SYNC1)543 sRawContactsProjectionMap.put(RawContacts.SYNC1, RawContacts.SYNC1); sRawContactsProjectionMap.put(RawContacts.SYNC2, RawContacts.SYNC2)544 sRawContactsProjectionMap.put(RawContacts.SYNC2, RawContacts.SYNC2); sRawContactsProjectionMap.put(RawContacts.SYNC3, RawContacts.SYNC3)545 sRawContactsProjectionMap.put(RawContacts.SYNC3, RawContacts.SYNC3); sRawContactsProjectionMap.put(RawContacts.SYNC4, RawContacts.SYNC4)546 sRawContactsProjectionMap.put(RawContacts.SYNC4, RawContacts.SYNC4); 547 548 sDataProjectionMap = new HashMap<String, String>(); sDataProjectionMap.put(Data._ID, Data._ID)549 sDataProjectionMap.put(Data._ID, Data._ID); sDataProjectionMap.put(Data.RAW_CONTACT_ID, Data.RAW_CONTACT_ID)550 sDataProjectionMap.put(Data.RAW_CONTACT_ID, Data.RAW_CONTACT_ID); sDataProjectionMap.put(Data.DATA_VERSION, Data.DATA_VERSION)551 sDataProjectionMap.put(Data.DATA_VERSION, Data.DATA_VERSION); sDataProjectionMap.put(Data.IS_PRIMARY, Data.IS_PRIMARY)552 sDataProjectionMap.put(Data.IS_PRIMARY, Data.IS_PRIMARY); sDataProjectionMap.put(Data.IS_SUPER_PRIMARY, Data.IS_SUPER_PRIMARY)553 sDataProjectionMap.put(Data.IS_SUPER_PRIMARY, Data.IS_SUPER_PRIMARY); sDataProjectionMap.put(Data.RES_PACKAGE, Data.RES_PACKAGE)554 sDataProjectionMap.put(Data.RES_PACKAGE, Data.RES_PACKAGE); sDataProjectionMap.put(Data.MIMETYPE, Data.MIMETYPE)555 sDataProjectionMap.put(Data.MIMETYPE, Data.MIMETYPE); sDataProjectionMap.put(Data.DATA1, Data.DATA1)556 sDataProjectionMap.put(Data.DATA1, Data.DATA1); sDataProjectionMap.put(Data.DATA2, Data.DATA2)557 sDataProjectionMap.put(Data.DATA2, Data.DATA2); sDataProjectionMap.put(Data.DATA3, Data.DATA3)558 sDataProjectionMap.put(Data.DATA3, Data.DATA3); sDataProjectionMap.put(Data.DATA4, Data.DATA4)559 sDataProjectionMap.put(Data.DATA4, Data.DATA4); sDataProjectionMap.put(Data.DATA5, Data.DATA5)560 sDataProjectionMap.put(Data.DATA5, Data.DATA5); sDataProjectionMap.put(Data.DATA6, Data.DATA6)561 sDataProjectionMap.put(Data.DATA6, Data.DATA6); sDataProjectionMap.put(Data.DATA7, Data.DATA7)562 sDataProjectionMap.put(Data.DATA7, Data.DATA7); sDataProjectionMap.put(Data.DATA8, Data.DATA8)563 sDataProjectionMap.put(Data.DATA8, Data.DATA8); sDataProjectionMap.put(Data.DATA9, Data.DATA9)564 sDataProjectionMap.put(Data.DATA9, Data.DATA9); sDataProjectionMap.put(Data.DATA10, Data.DATA10)565 sDataProjectionMap.put(Data.DATA10, Data.DATA10); sDataProjectionMap.put(Data.DATA11, Data.DATA11)566 sDataProjectionMap.put(Data.DATA11, Data.DATA11); sDataProjectionMap.put(Data.DATA12, Data.DATA12)567 sDataProjectionMap.put(Data.DATA12, Data.DATA12); sDataProjectionMap.put(Data.DATA13, Data.DATA13)568 sDataProjectionMap.put(Data.DATA13, Data.DATA13); sDataProjectionMap.put(Data.DATA14, Data.DATA14)569 sDataProjectionMap.put(Data.DATA14, Data.DATA14); sDataProjectionMap.put(Data.DATA15, Data.DATA15)570 sDataProjectionMap.put(Data.DATA15, Data.DATA15); sDataProjectionMap.put(Data.SYNC1, Data.SYNC1)571 sDataProjectionMap.put(Data.SYNC1, Data.SYNC1); sDataProjectionMap.put(Data.SYNC2, Data.SYNC2)572 sDataProjectionMap.put(Data.SYNC2, Data.SYNC2); sDataProjectionMap.put(Data.SYNC3, Data.SYNC3)573 sDataProjectionMap.put(Data.SYNC3, Data.SYNC3); sDataProjectionMap.put(Data.SYNC4, Data.SYNC4)574 sDataProjectionMap.put(Data.SYNC4, Data.SYNC4); sDataProjectionMap.put(Data.CONTACT_ID, Data.CONTACT_ID)575 sDataProjectionMap.put(Data.CONTACT_ID, Data.CONTACT_ID); sDataProjectionMap.put(RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_NAME)576 sDataProjectionMap.put(RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_NAME); sDataProjectionMap.put(RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_TYPE)577 sDataProjectionMap.put(RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_TYPE); sDataProjectionMap.put(RawContacts.SOURCE_ID, RawContacts.SOURCE_ID)578 sDataProjectionMap.put(RawContacts.SOURCE_ID, RawContacts.SOURCE_ID); sDataProjectionMap.put(RawContacts.VERSION, RawContacts.VERSION)579 sDataProjectionMap.put(RawContacts.VERSION, RawContacts.VERSION); sDataProjectionMap.put(RawContacts.DIRTY, RawContacts.DIRTY)580 sDataProjectionMap.put(RawContacts.DIRTY, RawContacts.DIRTY); sDataProjectionMap.put(Contacts.LOOKUP_KEY, Contacts.LOOKUP_KEY)581 sDataProjectionMap.put(Contacts.LOOKUP_KEY, Contacts.LOOKUP_KEY); sDataProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME)582 sDataProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME); sDataProjectionMap.put(Contacts.CUSTOM_RINGTONE, Contacts.CUSTOM_RINGTONE)583 sDataProjectionMap.put(Contacts.CUSTOM_RINGTONE, Contacts.CUSTOM_RINGTONE); sDataProjectionMap.put(Contacts.SEND_TO_VOICEMAIL, Contacts.SEND_TO_VOICEMAIL)584 sDataProjectionMap.put(Contacts.SEND_TO_VOICEMAIL, Contacts.SEND_TO_VOICEMAIL); sDataProjectionMap.put(Contacts.LAST_TIME_CONTACTED, Contacts.LAST_TIME_CONTACTED)585 sDataProjectionMap.put(Contacts.LAST_TIME_CONTACTED, Contacts.LAST_TIME_CONTACTED); sDataProjectionMap.put(Contacts.TIMES_CONTACTED, Contacts.TIMES_CONTACTED)586 sDataProjectionMap.put(Contacts.TIMES_CONTACTED, Contacts.TIMES_CONTACTED); sDataProjectionMap.put(Contacts.STARRED, Contacts.STARRED)587 sDataProjectionMap.put(Contacts.STARRED, Contacts.STARRED); sDataProjectionMap.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID)588 sDataProjectionMap.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID); sDataProjectionMap.put(Contacts.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP)589 sDataProjectionMap.put(Contacts.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP); sDataProjectionMap.put(GroupMembership.GROUP_SOURCE_ID, GroupMembership.GROUP_SOURCE_ID)590 sDataProjectionMap.put(GroupMembership.GROUP_SOURCE_ID, GroupMembership.GROUP_SOURCE_ID); 591 592 HashMap<String, String> columns; 593 columns = new HashMap<String, String>(); columns.put(RawContacts._ID, RawContacts._ID)594 columns.put(RawContacts._ID, RawContacts._ID); columns.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID)595 columns.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID); columns.put(RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_NAME)596 columns.put(RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_NAME); columns.put(RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_TYPE)597 columns.put(RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_TYPE); columns.put(RawContacts.SOURCE_ID, RawContacts.SOURCE_ID)598 columns.put(RawContacts.SOURCE_ID, RawContacts.SOURCE_ID); columns.put(RawContacts.VERSION, RawContacts.VERSION)599 columns.put(RawContacts.VERSION, RawContacts.VERSION); columns.put(RawContacts.DIRTY, RawContacts.DIRTY)600 columns.put(RawContacts.DIRTY, RawContacts.DIRTY); columns.put(RawContacts.DELETED, RawContacts.DELETED)601 columns.put(RawContacts.DELETED, RawContacts.DELETED); columns.put(RawContacts.IS_RESTRICTED, RawContacts.IS_RESTRICTED)602 columns.put(RawContacts.IS_RESTRICTED, RawContacts.IS_RESTRICTED); columns.put(RawContacts.SYNC1, RawContacts.SYNC1)603 columns.put(RawContacts.SYNC1, RawContacts.SYNC1); columns.put(RawContacts.SYNC2, RawContacts.SYNC2)604 columns.put(RawContacts.SYNC2, RawContacts.SYNC2); columns.put(RawContacts.SYNC3, RawContacts.SYNC3)605 columns.put(RawContacts.SYNC3, RawContacts.SYNC3); columns.put(RawContacts.SYNC4, RawContacts.SYNC4)606 columns.put(RawContacts.SYNC4, RawContacts.SYNC4); columns.put(Data.RES_PACKAGE, Data.RES_PACKAGE)607 columns.put(Data.RES_PACKAGE, Data.RES_PACKAGE); columns.put(Data.MIMETYPE, Data.MIMETYPE)608 columns.put(Data.MIMETYPE, Data.MIMETYPE); columns.put(Data.DATA1, Data.DATA1)609 columns.put(Data.DATA1, Data.DATA1); columns.put(Data.DATA2, Data.DATA2)610 columns.put(Data.DATA2, Data.DATA2); columns.put(Data.DATA3, Data.DATA3)611 columns.put(Data.DATA3, Data.DATA3); columns.put(Data.DATA4, Data.DATA4)612 columns.put(Data.DATA4, Data.DATA4); columns.put(Data.DATA5, Data.DATA5)613 columns.put(Data.DATA5, Data.DATA5); columns.put(Data.DATA6, Data.DATA6)614 columns.put(Data.DATA6, Data.DATA6); columns.put(Data.DATA7, Data.DATA7)615 columns.put(Data.DATA7, Data.DATA7); columns.put(Data.DATA8, Data.DATA8)616 columns.put(Data.DATA8, Data.DATA8); columns.put(Data.DATA9, Data.DATA9)617 columns.put(Data.DATA9, Data.DATA9); columns.put(Data.DATA10, Data.DATA10)618 columns.put(Data.DATA10, Data.DATA10); columns.put(Data.DATA11, Data.DATA11)619 columns.put(Data.DATA11, Data.DATA11); columns.put(Data.DATA12, Data.DATA12)620 columns.put(Data.DATA12, Data.DATA12); columns.put(Data.DATA13, Data.DATA13)621 columns.put(Data.DATA13, Data.DATA13); columns.put(Data.DATA14, Data.DATA14)622 columns.put(Data.DATA14, Data.DATA14); columns.put(Data.DATA15, Data.DATA15)623 columns.put(Data.DATA15, Data.DATA15); columns.put(Data.SYNC1, Data.SYNC1)624 columns.put(Data.SYNC1, Data.SYNC1); columns.put(Data.SYNC2, Data.SYNC2)625 columns.put(Data.SYNC2, Data.SYNC2); columns.put(Data.SYNC3, Data.SYNC3)626 columns.put(Data.SYNC3, Data.SYNC3); columns.put(Data.SYNC4, Data.SYNC4)627 columns.put(Data.SYNC4, Data.SYNC4); columns.put(RawContacts.Entity.DATA_ID, RawContacts.Entity.DATA_ID)628 columns.put(RawContacts.Entity.DATA_ID, RawContacts.Entity.DATA_ID); columns.put(Data.STARRED, Data.STARRED)629 columns.put(Data.STARRED, Data.STARRED); columns.put(Data.DATA_VERSION, Data.DATA_VERSION)630 columns.put(Data.DATA_VERSION, Data.DATA_VERSION); columns.put(Data.IS_PRIMARY, Data.IS_PRIMARY)631 columns.put(Data.IS_PRIMARY, Data.IS_PRIMARY); columns.put(Data.IS_SUPER_PRIMARY, Data.IS_SUPER_PRIMARY)632 columns.put(Data.IS_SUPER_PRIMARY, Data.IS_SUPER_PRIMARY); columns.put(GroupMembership.GROUP_SOURCE_ID, GroupMembership.GROUP_SOURCE_ID)633 columns.put(GroupMembership.GROUP_SOURCE_ID, GroupMembership.GROUP_SOURCE_ID); 634 sRawContactsEntityProjectionMap = columns; 635 636 // Handle projections for Contacts-level statuses addProjection(sDataProjectionMap, Contacts.CONTACT_PRESENCE, Tables.AGGREGATED_PRESENCE + "." + StatusUpdates.PRESENCE)637 addProjection(sDataProjectionMap, Contacts.CONTACT_PRESENCE, 638 Tables.AGGREGATED_PRESENCE + "." + StatusUpdates.PRESENCE); addProjection(sDataProjectionMap, Contacts.CONTACT_STATUS, ContactsStatusUpdatesColumns.CONCRETE_STATUS)639 addProjection(sDataProjectionMap, Contacts.CONTACT_STATUS, 640 ContactsStatusUpdatesColumns.CONCRETE_STATUS); addProjection(sDataProjectionMap, Contacts.CONTACT_STATUS_TIMESTAMP, ContactsStatusUpdatesColumns.CONCRETE_STATUS_TIMESTAMP)641 addProjection(sDataProjectionMap, Contacts.CONTACT_STATUS_TIMESTAMP, 642 ContactsStatusUpdatesColumns.CONCRETE_STATUS_TIMESTAMP); addProjection(sDataProjectionMap, Contacts.CONTACT_STATUS_RES_PACKAGE, ContactsStatusUpdatesColumns.CONCRETE_STATUS_RES_PACKAGE)643 addProjection(sDataProjectionMap, Contacts.CONTACT_STATUS_RES_PACKAGE, 644 ContactsStatusUpdatesColumns.CONCRETE_STATUS_RES_PACKAGE); addProjection(sDataProjectionMap, Contacts.CONTACT_STATUS_LABEL, ContactsStatusUpdatesColumns.CONCRETE_STATUS_LABEL)645 addProjection(sDataProjectionMap, Contacts.CONTACT_STATUS_LABEL, 646 ContactsStatusUpdatesColumns.CONCRETE_STATUS_LABEL); addProjection(sDataProjectionMap, Contacts.CONTACT_STATUS_ICON, ContactsStatusUpdatesColumns.CONCRETE_STATUS_ICON)647 addProjection(sDataProjectionMap, Contacts.CONTACT_STATUS_ICON, 648 ContactsStatusUpdatesColumns.CONCRETE_STATUS_ICON); 649 650 // Handle projections for Data-level statuses addProjection(sDataProjectionMap, Data.PRESENCE, Tables.PRESENCE + "." + StatusUpdates.PRESENCE)651 addProjection(sDataProjectionMap, Data.PRESENCE, 652 Tables.PRESENCE + "." + StatusUpdates.PRESENCE); addProjection(sDataProjectionMap, Data.STATUS, StatusUpdatesColumns.CONCRETE_STATUS)653 addProjection(sDataProjectionMap, Data.STATUS, 654 StatusUpdatesColumns.CONCRETE_STATUS); addProjection(sDataProjectionMap, Data.STATUS_TIMESTAMP, StatusUpdatesColumns.CONCRETE_STATUS_TIMESTAMP)655 addProjection(sDataProjectionMap, Data.STATUS_TIMESTAMP, 656 StatusUpdatesColumns.CONCRETE_STATUS_TIMESTAMP); addProjection(sDataProjectionMap, Data.STATUS_RES_PACKAGE, StatusUpdatesColumns.CONCRETE_STATUS_RES_PACKAGE)657 addProjection(sDataProjectionMap, Data.STATUS_RES_PACKAGE, 658 StatusUpdatesColumns.CONCRETE_STATUS_RES_PACKAGE); addProjection(sDataProjectionMap, Data.STATUS_LABEL, StatusUpdatesColumns.CONCRETE_STATUS_LABEL)659 addProjection(sDataProjectionMap, Data.STATUS_LABEL, 660 StatusUpdatesColumns.CONCRETE_STATUS_LABEL); addProjection(sDataProjectionMap, Data.STATUS_ICON, StatusUpdatesColumns.CONCRETE_STATUS_ICON)661 addProjection(sDataProjectionMap, Data.STATUS_ICON, 662 StatusUpdatesColumns.CONCRETE_STATUS_ICON); 663 664 // Projection map for data grouped by contact (not raw contact) and some data field(s) 665 sDistinctDataProjectionMap = new HashMap<String, String>(); sDistinctDataProjectionMap.put(Data._ID, "MIN(" + Data._ID + ") AS " + Data._ID)666 sDistinctDataProjectionMap.put(Data._ID, 667 "MIN(" + Data._ID + ") AS " + Data._ID); sDistinctDataProjectionMap.put(Data.DATA_VERSION, Data.DATA_VERSION)668 sDistinctDataProjectionMap.put(Data.DATA_VERSION, Data.DATA_VERSION); sDistinctDataProjectionMap.put(Data.IS_PRIMARY, Data.IS_PRIMARY)669 sDistinctDataProjectionMap.put(Data.IS_PRIMARY, Data.IS_PRIMARY); sDistinctDataProjectionMap.put(Data.IS_SUPER_PRIMARY, Data.IS_SUPER_PRIMARY)670 sDistinctDataProjectionMap.put(Data.IS_SUPER_PRIMARY, Data.IS_SUPER_PRIMARY); sDistinctDataProjectionMap.put(Data.RES_PACKAGE, Data.RES_PACKAGE)671 sDistinctDataProjectionMap.put(Data.RES_PACKAGE, Data.RES_PACKAGE); sDistinctDataProjectionMap.put(Data.MIMETYPE, Data.MIMETYPE)672 sDistinctDataProjectionMap.put(Data.MIMETYPE, Data.MIMETYPE); sDistinctDataProjectionMap.put(Data.DATA1, Data.DATA1)673 sDistinctDataProjectionMap.put(Data.DATA1, Data.DATA1); sDistinctDataProjectionMap.put(Data.DATA2, Data.DATA2)674 sDistinctDataProjectionMap.put(Data.DATA2, Data.DATA2); sDistinctDataProjectionMap.put(Data.DATA3, Data.DATA3)675 sDistinctDataProjectionMap.put(Data.DATA3, Data.DATA3); sDistinctDataProjectionMap.put(Data.DATA4, Data.DATA4)676 sDistinctDataProjectionMap.put(Data.DATA4, Data.DATA4); sDistinctDataProjectionMap.put(Data.DATA5, Data.DATA5)677 sDistinctDataProjectionMap.put(Data.DATA5, Data.DATA5); sDistinctDataProjectionMap.put(Data.DATA6, Data.DATA6)678 sDistinctDataProjectionMap.put(Data.DATA6, Data.DATA6); sDistinctDataProjectionMap.put(Data.DATA7, Data.DATA7)679 sDistinctDataProjectionMap.put(Data.DATA7, Data.DATA7); sDistinctDataProjectionMap.put(Data.DATA8, Data.DATA8)680 sDistinctDataProjectionMap.put(Data.DATA8, Data.DATA8); sDistinctDataProjectionMap.put(Data.DATA9, Data.DATA9)681 sDistinctDataProjectionMap.put(Data.DATA9, Data.DATA9); sDistinctDataProjectionMap.put(Data.DATA10, Data.DATA10)682 sDistinctDataProjectionMap.put(Data.DATA10, Data.DATA10); sDistinctDataProjectionMap.put(Data.DATA11, Data.DATA11)683 sDistinctDataProjectionMap.put(Data.DATA11, Data.DATA11); sDistinctDataProjectionMap.put(Data.DATA12, Data.DATA12)684 sDistinctDataProjectionMap.put(Data.DATA12, Data.DATA12); sDistinctDataProjectionMap.put(Data.DATA13, Data.DATA13)685 sDistinctDataProjectionMap.put(Data.DATA13, Data.DATA13); sDistinctDataProjectionMap.put(Data.DATA14, Data.DATA14)686 sDistinctDataProjectionMap.put(Data.DATA14, Data.DATA14); sDistinctDataProjectionMap.put(Data.DATA15, Data.DATA15)687 sDistinctDataProjectionMap.put(Data.DATA15, Data.DATA15); sDistinctDataProjectionMap.put(Data.SYNC1, Data.SYNC1)688 sDistinctDataProjectionMap.put(Data.SYNC1, Data.SYNC1); sDistinctDataProjectionMap.put(Data.SYNC2, Data.SYNC2)689 sDistinctDataProjectionMap.put(Data.SYNC2, Data.SYNC2); sDistinctDataProjectionMap.put(Data.SYNC3, Data.SYNC3)690 sDistinctDataProjectionMap.put(Data.SYNC3, Data.SYNC3); sDistinctDataProjectionMap.put(Data.SYNC4, Data.SYNC4)691 sDistinctDataProjectionMap.put(Data.SYNC4, Data.SYNC4); sDistinctDataProjectionMap.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID)692 sDistinctDataProjectionMap.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID); sDistinctDataProjectionMap.put(Contacts.LOOKUP_KEY, Contacts.LOOKUP_KEY)693 sDistinctDataProjectionMap.put(Contacts.LOOKUP_KEY, Contacts.LOOKUP_KEY); sDistinctDataProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME)694 sDistinctDataProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME); sDistinctDataProjectionMap.put(Contacts.CUSTOM_RINGTONE, Contacts.CUSTOM_RINGTONE)695 sDistinctDataProjectionMap.put(Contacts.CUSTOM_RINGTONE, Contacts.CUSTOM_RINGTONE); sDistinctDataProjectionMap.put(Contacts.SEND_TO_VOICEMAIL, Contacts.SEND_TO_VOICEMAIL)696 sDistinctDataProjectionMap.put(Contacts.SEND_TO_VOICEMAIL, Contacts.SEND_TO_VOICEMAIL); sDistinctDataProjectionMap.put(Contacts.LAST_TIME_CONTACTED, Contacts.LAST_TIME_CONTACTED)697 sDistinctDataProjectionMap.put(Contacts.LAST_TIME_CONTACTED, Contacts.LAST_TIME_CONTACTED); sDistinctDataProjectionMap.put(Contacts.TIMES_CONTACTED, Contacts.TIMES_CONTACTED)698 sDistinctDataProjectionMap.put(Contacts.TIMES_CONTACTED, Contacts.TIMES_CONTACTED); sDistinctDataProjectionMap.put(Contacts.STARRED, Contacts.STARRED)699 sDistinctDataProjectionMap.put(Contacts.STARRED, Contacts.STARRED); sDistinctDataProjectionMap.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID)700 sDistinctDataProjectionMap.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID); sDistinctDataProjectionMap.put(Contacts.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP)701 sDistinctDataProjectionMap.put(Contacts.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP); sDistinctDataProjectionMap.put(GroupMembership.GROUP_SOURCE_ID, GroupMembership.GROUP_SOURCE_ID)702 sDistinctDataProjectionMap.put(GroupMembership.GROUP_SOURCE_ID, 703 GroupMembership.GROUP_SOURCE_ID); 704 705 // Handle projections for Contacts-level statuses addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_PRESENCE, Tables.AGGREGATED_PRESENCE + "." + StatusUpdates.PRESENCE)706 addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_PRESENCE, 707 Tables.AGGREGATED_PRESENCE + "." + StatusUpdates.PRESENCE); addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_STATUS, ContactsStatusUpdatesColumns.CONCRETE_STATUS)708 addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_STATUS, 709 ContactsStatusUpdatesColumns.CONCRETE_STATUS); addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_STATUS_TIMESTAMP, ContactsStatusUpdatesColumns.CONCRETE_STATUS_TIMESTAMP)710 addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_STATUS_TIMESTAMP, 711 ContactsStatusUpdatesColumns.CONCRETE_STATUS_TIMESTAMP); addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_STATUS_RES_PACKAGE, ContactsStatusUpdatesColumns.CONCRETE_STATUS_RES_PACKAGE)712 addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_STATUS_RES_PACKAGE, 713 ContactsStatusUpdatesColumns.CONCRETE_STATUS_RES_PACKAGE); addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_STATUS_LABEL, ContactsStatusUpdatesColumns.CONCRETE_STATUS_LABEL)714 addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_STATUS_LABEL, 715 ContactsStatusUpdatesColumns.CONCRETE_STATUS_LABEL); addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_STATUS_ICON, ContactsStatusUpdatesColumns.CONCRETE_STATUS_ICON)716 addProjection(sDistinctDataProjectionMap, Contacts.CONTACT_STATUS_ICON, 717 ContactsStatusUpdatesColumns.CONCRETE_STATUS_ICON); 718 719 // Handle projections for Data-level statuses addProjection(sDistinctDataProjectionMap, Data.PRESENCE, Tables.PRESENCE + "." + StatusUpdates.PRESENCE)720 addProjection(sDistinctDataProjectionMap, Data.PRESENCE, 721 Tables.PRESENCE + "." + StatusUpdates.PRESENCE); addProjection(sDistinctDataProjectionMap, Data.STATUS, StatusUpdatesColumns.CONCRETE_STATUS)722 addProjection(sDistinctDataProjectionMap, Data.STATUS, 723 StatusUpdatesColumns.CONCRETE_STATUS); addProjection(sDistinctDataProjectionMap, Data.STATUS_TIMESTAMP, StatusUpdatesColumns.CONCRETE_STATUS_TIMESTAMP)724 addProjection(sDistinctDataProjectionMap, Data.STATUS_TIMESTAMP, 725 StatusUpdatesColumns.CONCRETE_STATUS_TIMESTAMP); addProjection(sDistinctDataProjectionMap, Data.STATUS_RES_PACKAGE, StatusUpdatesColumns.CONCRETE_STATUS_RES_PACKAGE)726 addProjection(sDistinctDataProjectionMap, Data.STATUS_RES_PACKAGE, 727 StatusUpdatesColumns.CONCRETE_STATUS_RES_PACKAGE); addProjection(sDistinctDataProjectionMap, Data.STATUS_LABEL, StatusUpdatesColumns.CONCRETE_STATUS_LABEL)728 addProjection(sDistinctDataProjectionMap, Data.STATUS_LABEL, 729 StatusUpdatesColumns.CONCRETE_STATUS_LABEL); addProjection(sDistinctDataProjectionMap, Data.STATUS_ICON, StatusUpdatesColumns.CONCRETE_STATUS_ICON)730 addProjection(sDistinctDataProjectionMap, Data.STATUS_ICON, 731 StatusUpdatesColumns.CONCRETE_STATUS_ICON); 732 733 sPhoneLookupProjectionMap = new HashMap<String, String>(); sPhoneLookupProjectionMap.put(PhoneLookup._ID, ContactsColumns.CONCRETE_ID + " AS " + PhoneLookup._ID)734 sPhoneLookupProjectionMap.put(PhoneLookup._ID, 735 ContactsColumns.CONCRETE_ID + " AS " + PhoneLookup._ID); sPhoneLookupProjectionMap.put(PhoneLookup.LOOKUP_KEY, Contacts.LOOKUP_KEY + " AS " + PhoneLookup.LOOKUP_KEY)736 sPhoneLookupProjectionMap.put(PhoneLookup.LOOKUP_KEY, 737 Contacts.LOOKUP_KEY + " AS " + PhoneLookup.LOOKUP_KEY); sPhoneLookupProjectionMap.put(PhoneLookup.DISPLAY_NAME, ContactsColumns.CONCRETE_DISPLAY_NAME + " AS " + PhoneLookup.DISPLAY_NAME)738 sPhoneLookupProjectionMap.put(PhoneLookup.DISPLAY_NAME, 739 ContactsColumns.CONCRETE_DISPLAY_NAME + " AS " + PhoneLookup.DISPLAY_NAME); sPhoneLookupProjectionMap.put(PhoneLookup.LAST_TIME_CONTACTED, ContactsColumns.CONCRETE_LAST_TIME_CONTACTED + " AS " + PhoneLookup.LAST_TIME_CONTACTED)740 sPhoneLookupProjectionMap.put(PhoneLookup.LAST_TIME_CONTACTED, 741 ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 742 + " AS " + PhoneLookup.LAST_TIME_CONTACTED); sPhoneLookupProjectionMap.put(PhoneLookup.TIMES_CONTACTED, ContactsColumns.CONCRETE_TIMES_CONTACTED + " AS " + PhoneLookup.TIMES_CONTACTED)743 sPhoneLookupProjectionMap.put(PhoneLookup.TIMES_CONTACTED, 744 ContactsColumns.CONCRETE_TIMES_CONTACTED + " AS " + PhoneLookup.TIMES_CONTACTED); sPhoneLookupProjectionMap.put(PhoneLookup.STARRED, ContactsColumns.CONCRETE_STARRED + " AS " + PhoneLookup.STARRED)745 sPhoneLookupProjectionMap.put(PhoneLookup.STARRED, 746 ContactsColumns.CONCRETE_STARRED + " AS " + PhoneLookup.STARRED); sPhoneLookupProjectionMap.put(PhoneLookup.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP + " AS " + PhoneLookup.IN_VISIBLE_GROUP)747 sPhoneLookupProjectionMap.put(PhoneLookup.IN_VISIBLE_GROUP, 748 Contacts.IN_VISIBLE_GROUP + " AS " + PhoneLookup.IN_VISIBLE_GROUP); sPhoneLookupProjectionMap.put(PhoneLookup.PHOTO_ID, Contacts.PHOTO_ID + " AS " + PhoneLookup.PHOTO_ID)749 sPhoneLookupProjectionMap.put(PhoneLookup.PHOTO_ID, 750 Contacts.PHOTO_ID + " AS " + PhoneLookup.PHOTO_ID); sPhoneLookupProjectionMap.put(PhoneLookup.CUSTOM_RINGTONE, ContactsColumns.CONCRETE_CUSTOM_RINGTONE + " AS " + PhoneLookup.CUSTOM_RINGTONE)751 sPhoneLookupProjectionMap.put(PhoneLookup.CUSTOM_RINGTONE, 752 ContactsColumns.CONCRETE_CUSTOM_RINGTONE + " AS " + PhoneLookup.CUSTOM_RINGTONE); sPhoneLookupProjectionMap.put(PhoneLookup.HAS_PHONE_NUMBER, Contacts.HAS_PHONE_NUMBER + " AS " + PhoneLookup.HAS_PHONE_NUMBER)753 sPhoneLookupProjectionMap.put(PhoneLookup.HAS_PHONE_NUMBER, 754 Contacts.HAS_PHONE_NUMBER + " AS " + PhoneLookup.HAS_PHONE_NUMBER); sPhoneLookupProjectionMap.put(PhoneLookup.SEND_TO_VOICEMAIL, ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL + " AS " + PhoneLookup.SEND_TO_VOICEMAIL)755 sPhoneLookupProjectionMap.put(PhoneLookup.SEND_TO_VOICEMAIL, 756 ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 757 + " AS " + PhoneLookup.SEND_TO_VOICEMAIL); sPhoneLookupProjectionMap.put(PhoneLookup.NUMBER, Phone.NUMBER + " AS " + PhoneLookup.NUMBER)758 sPhoneLookupProjectionMap.put(PhoneLookup.NUMBER, 759 Phone.NUMBER + " AS " + PhoneLookup.NUMBER); sPhoneLookupProjectionMap.put(PhoneLookup.TYPE, Phone.TYPE + " AS " + PhoneLookup.TYPE)760 sPhoneLookupProjectionMap.put(PhoneLookup.TYPE, 761 Phone.TYPE + " AS " + PhoneLookup.TYPE); sPhoneLookupProjectionMap.put(PhoneLookup.LABEL, Phone.LABEL + " AS " + PhoneLookup.LABEL)762 sPhoneLookupProjectionMap.put(PhoneLookup.LABEL, 763 Phone.LABEL + " AS " + PhoneLookup.LABEL); 764 765 // Groups projection map 766 columns = new HashMap<String, String>(); columns.put(Groups._ID, Groups._ID)767 columns.put(Groups._ID, Groups._ID); columns.put(Groups.ACCOUNT_NAME, Groups.ACCOUNT_NAME)768 columns.put(Groups.ACCOUNT_NAME, Groups.ACCOUNT_NAME); columns.put(Groups.ACCOUNT_TYPE, Groups.ACCOUNT_TYPE)769 columns.put(Groups.ACCOUNT_TYPE, Groups.ACCOUNT_TYPE); columns.put(Groups.SOURCE_ID, Groups.SOURCE_ID)770 columns.put(Groups.SOURCE_ID, Groups.SOURCE_ID); columns.put(Groups.DIRTY, Groups.DIRTY)771 columns.put(Groups.DIRTY, Groups.DIRTY); columns.put(Groups.VERSION, Groups.VERSION)772 columns.put(Groups.VERSION, Groups.VERSION); columns.put(Groups.RES_PACKAGE, Groups.RES_PACKAGE)773 columns.put(Groups.RES_PACKAGE, Groups.RES_PACKAGE); columns.put(Groups.TITLE, Groups.TITLE)774 columns.put(Groups.TITLE, Groups.TITLE); columns.put(Groups.TITLE_RES, Groups.TITLE_RES)775 columns.put(Groups.TITLE_RES, Groups.TITLE_RES); columns.put(Groups.GROUP_VISIBLE, Groups.GROUP_VISIBLE)776 columns.put(Groups.GROUP_VISIBLE, Groups.GROUP_VISIBLE); columns.put(Groups.SYSTEM_ID, Groups.SYSTEM_ID)777 columns.put(Groups.SYSTEM_ID, Groups.SYSTEM_ID); columns.put(Groups.DELETED, Groups.DELETED)778 columns.put(Groups.DELETED, Groups.DELETED); columns.put(Groups.NOTES, Groups.NOTES)779 columns.put(Groups.NOTES, Groups.NOTES); columns.put(Groups.SHOULD_SYNC, Groups.SHOULD_SYNC)780 columns.put(Groups.SHOULD_SYNC, Groups.SHOULD_SYNC); columns.put(Groups.SYNC1, Groups.SYNC1)781 columns.put(Groups.SYNC1, Groups.SYNC1); columns.put(Groups.SYNC2, Groups.SYNC2)782 columns.put(Groups.SYNC2, Groups.SYNC2); columns.put(Groups.SYNC3, Groups.SYNC3)783 columns.put(Groups.SYNC3, Groups.SYNC3); columns.put(Groups.SYNC4, Groups.SYNC4)784 columns.put(Groups.SYNC4, Groups.SYNC4); 785 sGroupsProjectionMap = columns; 786 787 // RawContacts and groups projection map 788 columns = new HashMap<String, String>(); 789 columns.putAll(sGroupsProjectionMap); columns.put(Groups.SUMMARY_COUNT, "(SELECT COUNT(DISTINCT " + ContactsColumns.CONCRETE_ID + ") FROM " + Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS + " WHERE " + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP + ") AS " + Groups.SUMMARY_COUNT)790 columns.put(Groups.SUMMARY_COUNT, "(SELECT COUNT(DISTINCT " + ContactsColumns.CONCRETE_ID 791 + ") FROM " + Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS + " WHERE " 792 + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP 793 + ") AS " + Groups.SUMMARY_COUNT); columns.put(Groups.SUMMARY_WITH_PHONES, "(SELECT COUNT(DISTINCT " + ContactsColumns.CONCRETE_ID + ") FROM " + Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS + " WHERE " + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP + " AND " + Contacts.HAS_PHONE_NUMBER + ") AS " + Groups.SUMMARY_WITH_PHONES)794 columns.put(Groups.SUMMARY_WITH_PHONES, "(SELECT COUNT(DISTINCT " 795 + ContactsColumns.CONCRETE_ID + ") FROM " 796 + Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS + " WHERE " 797 + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP 798 + " AND " + Contacts.HAS_PHONE_NUMBER + ") AS " + Groups.SUMMARY_WITH_PHONES); 799 sGroupsSummaryProjectionMap = columns; 800 801 // Aggregate exception projection map 802 columns = new HashMap<String, String>(); columns.put(AggregationExceptionColumns._ID, Tables.AGGREGATION_EXCEPTIONS + "._id AS _id")803 columns.put(AggregationExceptionColumns._ID, Tables.AGGREGATION_EXCEPTIONS + "._id AS _id"); columns.put(AggregationExceptions.TYPE, AggregationExceptions.TYPE)804 columns.put(AggregationExceptions.TYPE, AggregationExceptions.TYPE); columns.put(AggregationExceptions.RAW_CONTACT_ID1, AggregationExceptions.RAW_CONTACT_ID1)805 columns.put(AggregationExceptions.RAW_CONTACT_ID1, AggregationExceptions.RAW_CONTACT_ID1); columns.put(AggregationExceptions.RAW_CONTACT_ID2, AggregationExceptions.RAW_CONTACT_ID2)806 columns.put(AggregationExceptions.RAW_CONTACT_ID2, AggregationExceptions.RAW_CONTACT_ID2); 807 sAggregationExceptionsProjectionMap = columns; 808 809 // Settings projection map 810 columns = new HashMap<String, String>(); columns.put(Settings.ACCOUNT_NAME, Settings.ACCOUNT_NAME)811 columns.put(Settings.ACCOUNT_NAME, Settings.ACCOUNT_NAME); columns.put(Settings.ACCOUNT_TYPE, Settings.ACCOUNT_TYPE)812 columns.put(Settings.ACCOUNT_TYPE, Settings.ACCOUNT_TYPE); columns.put(Settings.UNGROUPED_VISIBLE, Settings.UNGROUPED_VISIBLE)813 columns.put(Settings.UNGROUPED_VISIBLE, Settings.UNGROUPED_VISIBLE); columns.put(Settings.SHOULD_SYNC, Settings.SHOULD_SYNC)814 columns.put(Settings.SHOULD_SYNC, Settings.SHOULD_SYNC); columns.put(Settings.ANY_UNSYNCED, "(CASE WHEN MIN(" + Settings.SHOULD_SYNC + ",(SELECT (CASE WHEN MIN(" + Groups.SHOULD_SYNC + ") IS NULL THEN 1 ELSE MIN(" + Groups.SHOULD_SYNC + ") END) FROM " + Tables.GROUPS + " WHERE " + GroupsColumns.CONCRETE_ACCOUNT_NAME + "=" + SettingsColumns.CONCRETE_ACCOUNT_NAME + " AND " + GroupsColumns.CONCRETE_ACCOUNT_TYPE + "=" + SettingsColumns.CONCRETE_ACCOUNT_TYPE + "))=0 THEN 1 ELSE 0 END) AS " + Settings.ANY_UNSYNCED)815 columns.put(Settings.ANY_UNSYNCED, "(CASE WHEN MIN(" + Settings.SHOULD_SYNC 816 + ",(SELECT (CASE WHEN MIN(" + Groups.SHOULD_SYNC + ") IS NULL THEN 1 ELSE MIN(" 817 + Groups.SHOULD_SYNC + ") END) FROM " + Tables.GROUPS + " WHERE " 818 + GroupsColumns.CONCRETE_ACCOUNT_NAME + "=" + SettingsColumns.CONCRETE_ACCOUNT_NAME 819 + " AND " + GroupsColumns.CONCRETE_ACCOUNT_TYPE + "=" 820 + SettingsColumns.CONCRETE_ACCOUNT_TYPE + "))=0 THEN 1 ELSE 0 END) AS " 821 + Settings.ANY_UNSYNCED); columns.put(Settings.UNGROUPED_COUNT, "(SELECT COUNT(*) FROM (SELECT 1 FROM " + Tables.SETTINGS_JOIN_RAW_CONTACTS_DATA_MIMETYPES_CONTACTS + " GROUP BY " + Clauses.GROUP_BY_ACCOUNT_CONTACT_ID + " HAVING " + Clauses.HAVING_NO_GROUPS + ")) AS " + Settings.UNGROUPED_COUNT)822