Skip to content

Commit

Permalink
Fixing delta api for account removal case.
Browse files Browse the repository at this point in the history
Account removal uses a different code path from normal contact deletes.  This
patch properly adds deleted contacts into the delete log when an account is
removed.  Also updates contact last updated timestamp for the non-delete case
when a raw contact is removed from an aggregate contact.

Bug: 8654272
Change-Id: I05c3ef297e5ad2ca6713e06d0b40206876cf0b9e
  • Loading branch information
Chiao Cheng committed Apr 18, 2013
1 parent 9aec6b8 commit a62622b
Showing 1 changed file with 37 additions and 1 deletion.
38 changes: 37 additions & 1 deletion src/com/android/providers/contacts/ContactsProvider2.java
Expand Up @@ -110,6 +110,7 @@

import com.android.common.content.ProjectionMap;
import com.android.common.content.SyncStateContentProviderHelper;
import com.android.common.io.MoreCloseables;
import com.android.providers.contacts.ContactLookupKey.LookupKeySegment;
import com.android.providers.contacts.ContactsDatabaseHelper.AccountsColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.AggregatedPresenceColumns;
Expand Down Expand Up @@ -4667,7 +4668,15 @@ private boolean updateAccountsInBackground(Account[] systemAccounts) {

// WARNING: This method can be run in either contacts mode or profile mode. It is
// absolutely imperative that no calls be made inside the following try block that can
// interact with the contacts DB. Otherwise it is quite possible for a deadlock to occur.
// interact with a specific contacts or profile DB. Otherwise it is quite possible for a
// deadlock to occur. i.e. always use the current database in mDbHelper and do not access
// mContactsHelper or mProfileHelper directly.
//
// The problem may be a bit more subtle if you also access something that stores the current
// db instance in it's constructor. updateSearchIndexInTransaction relies on the
// SearchIndexManager which upon construction, stores the current db. In this case,
// SearchIndexManager always contains the contact DB. This is why the
// updateSearchIndexInTransaction is protected with !isInProfileMode now.
try {
// First, remove stale rows from raw_contacts, groups, and related tables.

Expand Down Expand Up @@ -4722,6 +4731,33 @@ private boolean updateAccountsInBackground(Account[] systemAccounts) {
" FROM " + Tables.RAW_CONTACTS +
" WHERE " + RawContactsColumns.ACCOUNT_ID + " = ?)",
accountIdParams);

// Delta api is only needed for regular contacts.
if (!inProfileMode()) {
// 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 +
" FROM " + Tables.RAW_CONTACTS +
" WHERE " + RawContactsColumns.ACCOUNT_ID + " = ?",
accountIdParams);
try {
while (cursor.moveToNext()) {
final long rawContactId = cursor.getLong(0);
rawContactIds.add(rawContactId);
ContactsTableUtil.deleteContactIfSingleton(db, rawContactId);
}
} finally {
MoreCloseables.closeQuietly(cursor);
}

// 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);
}

db.execSQL(
"DELETE FROM " + Tables.RAW_CONTACTS +
" WHERE " + RawContactsColumns.ACCOUNT_ID + " = ?",
Expand Down

0 comments on commit a62622b

Please sign in to comment.