Use contact hash codes only on Android 7+ (workaround)

vcard4android: don't hash CATEGORIES, more verbose logging
pull/2/head
Ricki Hirner 8 years ago committed by Tom Hacohen
parent d707a1e643
commit 59f8305ba5

@ -14,6 +14,7 @@ import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.RemoteException;
@ -92,15 +93,22 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
* @return number of "really dirty" contacts
*/
public int verifyDirty() throws ContactsStorageException {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
App.log.severe("verifyDirty() should not be called on Android <7");
int reallyDirty = 0;
for (LocalContact contact : getDirtyContacts()) {
try {
if (contact.getLastHashCode() == contact.dataHashCode()) {
int lastHash = contact.getLastHashCode(),
currentHash = contact.dataHashCode();
if (lastHash == currentHash) {
// hash is code still the same, contact is not "really dirty" (only metadata been have changed)
App.log.log(Level.FINE, "Contact data hash has not changed, resetting dirty flag", contact);
contact.resetDirty();
} else
} else {
App.log.log(Level.FINE, "Contact data has changed from hash " + lastHash + " to " + currentHash, contact);
reallyDirty++;
}
} catch(FileNotFoundException e) {
throw new ContactsStorageException("Couldn't calculate hash code", e);
}

@ -12,6 +12,7 @@ import android.content.ContentProviderOperation;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
@ -82,9 +83,12 @@ public class LocalContact extends AndroidContact implements LocalResource {
values.put(COLUMN_ETAG, eTag);
values.put(ContactsContract.RawContacts.DIRTY, 0);
int hashCode = dataHashCode();
values.put(COLUMN_HASHCODE, hashCode);
App.log.finer("Clearing dirty flag with eTag = " + eTag + ", contact hash = " + hashCode);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// workaround for Android 7 which sets DIRTY flag when only meta-data is changed
int hashCode = dataHashCode();
values.put(COLUMN_HASHCODE, hashCode);
App.log.finer("Clearing dirty flag with eTag = " + eTag + ", contact hash = " + hashCode);
}
addressBook.provider.update(rawContactSyncURI(), values, null, null);
@ -161,14 +165,24 @@ public class LocalContact extends AndroidContact implements LocalResource {
@Override
public int update(Contact contact) throws ContactsStorageException {
int result = super.update(contact);
updateHashCode();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// workaround for Android 7 which sets DIRTY flag when only meta-data is changed
updateHashCode();
}
return result;
}
@Override
public Uri create() throws ContactsStorageException {
Uri uri = super.create();
updateHashCode();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// workaround for Android 7 which sets DIRTY flag when only meta-data is changed
updateHashCode();
}
return uri;
}
@ -177,11 +191,17 @@ public class LocalContact extends AndroidContact implements LocalResource {
* @return hash code of contact data (including group memberships)
*/
public int dataHashCode() throws FileNotFoundException, ContactsStorageException {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
App.log.severe("dataHashCode() should not be called on Android <7");
// groupMemberships is filled by getContact()
return getContact().hashCode() ^ groupMemberships.hashCode();
}
protected void updateHashCode() throws ContactsStorageException {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
App.log.severe("updateHashCode() should not be called on Android <7");
ContentValues values = new ContentValues(1);
try {
int hashCode = dataHashCode();
@ -194,6 +214,9 @@ public class LocalContact extends AndroidContact implements LocalResource {
}
int getLastHashCode() throws ContactsStorageException {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
App.log.severe("getLastHashCode() should not be called on Android <7");
try {
@Cleanup Cursor c = addressBook.provider.query(rawContactSyncURI(), new String[] { COLUMN_HASHCODE }, null, null, null);
if (c == null || !c.moveToNext() || c.isNull(0))

@ -14,6 +14,7 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.SyncResult;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
@ -82,10 +83,13 @@ public class ContactsSyncManager extends SyncManager {
LocalAddressBook localAddressBook = localAddressBook();
localAddressBook.setURL(info.url);
int reallyDirty = localAddressBook.verifyDirty();
if (extras.containsKey(ContentResolver.SYNC_EXTRAS_UPLOAD) && reallyDirty == 0) {
App.log.info("This sync was called to upload dirty contacts, but no contact data have been changed");
return false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// workaround for Android 7 which sets DIRTY flag when only meta-data is changed
int reallyDirty = localAddressBook.verifyDirty();
if (extras.containsKey(ContentResolver.SYNC_EXTRAS_UPLOAD) && reallyDirty == 0) {
App.log.info("This sync was called to upload dirty contacts, but no contact data have been changed");
return false;
}
}
// set up Contacts Provider Settings

Loading…
Cancel
Save