diff options
author | Chiao Cheng <chiaocheng@google.com> | 2013-04-23 14:39:19 -0700 |
---|---|---|
committer | Chiao Cheng <chiaocheng@google.com> | 2013-04-23 16:39:30 -0700 |
commit | da51adb4b99894666e7ea91fed0e8afc94162333 (patch) | |
tree | 77b665df0e98b8dfbc263394d2d4d9e09f9a70e0 | |
parent | 0cc5d1504803de51f8b421442e04ece87728af43 (diff) | |
download | packages_providers_ContactsProvider-da51adb4b99894666e7ea91fed0e8afc94162333.zip packages_providers_ContactsProvider-da51adb4b99894666e7ea91fed0e8afc94162333.tar.gz packages_providers_ContactsProvider-da51adb4b99894666e7ea91fed0e8afc94162333.tar.bz2 |
Fixed issue where some contacts are not added to delete log.
Contacts with multiple raw contacts were not being inserted into the delete
log when accounts are removed. This was due to the raw contacts being removed
in batch instead of one at a time. The logic to determine whether a contact
can be deleted was determining whether other raw contacts exist. This does
not work when all raw contacts are removed in a single batch.
Added logic to pre-select contacts that will be deleted.
Bug: 8696462
Change-Id: I95adccf9e6756bbf6ca9dd7d144c1d9ee8905631
-rw-r--r-- | src/com/android/providers/contacts/ContactsProvider2.java | 53 | ||||
-rw-r--r-- | src/com/android/providers/contacts/database/ContactsTableUtil.java | 12 |
2 files changed, 53 insertions, 12 deletions
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java index e114d4c..5754ced 100644 --- a/src/com/android/providers/contacts/ContactsProvider2.java +++ b/src/com/android/providers/contacts/ContactsProvider2.java @@ -2308,7 +2308,7 @@ public class ContactsProvider2 extends AbstractContactsProvider } final Set<Long> changedRawContacts = mTransactionContext.get().getChangedRawContactIds(); - ContactsTableUtil.updateContactLastUpdate(db, changedRawContacts); + ContactsTableUtil.updateContactLastUpdateByRawContactId(db, changedRawContacts); // Update sync states. for (Map.Entry<Long, Object> entry : mTransactionContext.get().getUpdatedSyncStates()) { @@ -4701,8 +4701,9 @@ public class ContactsProvider2 extends AbstractContactsProvider // getAccountIdOrNull() really shouldn't return null here, but just in case... if (accountIdOrNull != null) { + final String accountId = Long.toString(accountIdOrNull); final String[] accountIdParams = - new String[] {Long.toString(accountIdOrNull)}; + new String[] {accountId}; db.execSQL( "DELETE FROM " + Tables.GROUPS + " WHERE " + GroupsColumns.ACCOUNT_ID + " = ?", @@ -4737,17 +4738,27 @@ public class ContactsProvider2 extends AbstractContactsProvider // Contacts are deleted by a trigger on the raw_contacts table. // But we also need to insert the contact into the delete log. // This logic is being consolidated into the ContactsTableUtil. - HashSet<Long> rawContactIds = Sets.newHashSet(); - final Cursor cursor = db.rawQuery( - "SELECT " + RawContactsColumns.CONCRETE_ID + + + // deleteContactIfSingleton() does not work in this case because raw + // contacts will be deleted in a single batch below. Contacts with + // multiple raw contacts in the same account will be missed. + + // Find all contacts that do not have raw contacts in other accounts. + // These should be deleted. + Cursor cursor = db.rawQuery( + "SELECT " + RawContactsColumns.CONCRETE_CONTACT_ID + " FROM " + Tables.RAW_CONTACTS + - " WHERE " + RawContactsColumns.ACCOUNT_ID + " = ?", - accountIdParams); + " WHERE " + RawContactsColumns.ACCOUNT_ID + " = ?1" + + " AND " + RawContactsColumns.CONCRETE_CONTACT_ID + + " NOT IN (" + + " SELECT " + RawContactsColumns.CONCRETE_CONTACT_ID + + " FROM " + Tables.RAW_CONTACTS + + " WHERE " + RawContactsColumns.ACCOUNT_ID + " != ?1" + + ")", accountIdParams); try { while (cursor.moveToNext()) { - final long rawContactId = cursor.getLong(0); - rawContactIds.add(rawContactId); - ContactsTableUtil.deleteContactIfSingleton(db, rawContactId); + final long contactId = cursor.getLong(0); + ContactsTableUtil.deleteContact(db, contactId); } } finally { MoreCloseables.closeQuietly(cursor); @@ -4755,7 +4766,27 @@ public class ContactsProvider2 extends AbstractContactsProvider // If the contact was not deleted, it's last updated timestamp needs to // be refreshed since one of it's raw contacts got removed. - ContactsTableUtil.updateContactLastUpdate(db, rawContactIds); + // Find all contacts that will not be deleted (i.e. contacts with + // raw contacts in other accounts) + cursor = db.rawQuery( + "SELECT DISTINCT " + RawContactsColumns.CONCRETE_CONTACT_ID + + " FROM " + Tables.RAW_CONTACTS + + " WHERE " + RawContactsColumns.ACCOUNT_ID + " = ?1" + + " AND " + RawContactsColumns.CONCRETE_CONTACT_ID + + " IN (" + + " SELECT " + RawContactsColumns.CONCRETE_CONTACT_ID + + " FROM " + Tables.RAW_CONTACTS + + " WHERE " + RawContactsColumns.ACCOUNT_ID + " != ?1" + + ")", accountIdParams); + try { + while (cursor.moveToNext()) { + final long contactId = cursor.getLong(0); + ContactsTableUtil.updateContactLastUpdateByContactId(db, + contactId); + } + } finally { + MoreCloseables.closeQuietly(cursor); + } } db.execSQL( diff --git a/src/com/android/providers/contacts/database/ContactsTableUtil.java b/src/com/android/providers/contacts/database/ContactsTableUtil.java index 27c3d5b..dbc3d3e 100644 --- a/src/com/android/providers/contacts/database/ContactsTableUtil.java +++ b/src/com/android/providers/contacts/database/ContactsTableUtil.java @@ -19,6 +19,7 @@ package com.android.providers.contacts.database; import static android.provider.ContactsContract.Contacts; import static com.android.providers.contacts.ContactsDatabaseHelper.Tables; +import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.provider.ContactsContract; @@ -54,13 +55,22 @@ public class ContactsTableUtil { Contacts.CONTACT_LAST_UPDATED_TIMESTAMP)); } + public static void updateContactLastUpdateByContactId(SQLiteDatabase db, long contactId) { + final ContentValues values = new ContentValues(); + values.put(Contacts.CONTACT_LAST_UPDATED_TIMESTAMP, + Clock.getInstance().currentTimeMillis()); + db.update(Tables.CONTACTS, values, Contacts._ID + " = ?", + new String[] {String.valueOf(contactId)}); + } + /** * Refreshes the last updated timestamp of the contact with the current time. * * @param db The sqlite database instance. * @param rawContactIds A set of raw contacts ids to refresh the contact for. */ - public static void updateContactLastUpdate(SQLiteDatabase db, Set<Long> rawContactIds) { + public static void updateContactLastUpdateByRawContactId(SQLiteDatabase db, + Set<Long> rawContactIds) { if (rawContactIds.isEmpty()) { return; } |