summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChiao Cheng <chiaocheng@google.com>2013-04-23 14:39:19 -0700
committerChiao Cheng <chiaocheng@google.com>2013-04-23 16:39:30 -0700
commitda51adb4b99894666e7ea91fed0e8afc94162333 (patch)
tree77b665df0e98b8dfbc263394d2d4d9e09f9a70e0
parent0cc5d1504803de51f8b421442e04ece87728af43 (diff)
downloadpackages_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.java53
-rw-r--r--src/com/android/providers/contacts/database/ContactsTableUtil.java12
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;
}