handle on-device contacts with unstable system uri
on device contacts (contacts not synced) have an unstable system uri. For quicksy.im contacts we can identify the contact based on the phone number instead. fixes #4174
This commit is contained in:
parent
d5994a8d65
commit
75c20a7a2b
|
@ -1,2 +1,11 @@
|
||||||
package eu.siacs.conversations.utils;public class PhoneNumberUtilWrapper {
|
package eu.siacs.conversations.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.xmpp.Jid;
|
||||||
|
|
||||||
|
public class PhoneNumberUtilWrapper {
|
||||||
|
public static String toFormattedPhoneNumber(Context context, Jid jid) {
|
||||||
|
throw new AssertionError("This method is not implemented in Conversations");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -538,6 +538,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
final int theme = findTheme();
|
final int theme = findTheme();
|
||||||
if (this.mTheme != theme) {
|
if (this.mTheme != theme) {
|
||||||
this.mSkipBackgroundBinding = true;
|
this.mSkipBackgroundBinding = true;
|
||||||
|
@ -546,7 +547,6 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
||||||
this.mSkipBackgroundBinding = false;
|
this.mSkipBackgroundBinding = false;
|
||||||
}
|
}
|
||||||
mRedirectInProcess.set(false);
|
mRedirectInProcess.set(false);
|
||||||
super.onStart();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -46,30 +46,30 @@ public class PhoneNumberContact extends AbstractPhoneContact {
|
||||||
ContactsContract.Data.PHOTO_URI,
|
ContactsContract.Data.PHOTO_URI,
|
||||||
ContactsContract.Data.LOOKUP_KEY,
|
ContactsContract.Data.LOOKUP_KEY,
|
||||||
ContactsContract.CommonDataKinds.Phone.NUMBER};
|
ContactsContract.CommonDataKinds.Phone.NUMBER};
|
||||||
final Cursor cursor;
|
final HashMap<String, PhoneNumberContact> contacts = new HashMap<>();
|
||||||
try {
|
try (final Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null)){
|
||||||
cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null);
|
while (cursor != null && cursor.moveToNext()) {
|
||||||
|
try {
|
||||||
|
final PhoneNumberContact contact = new PhoneNumberContact(context, cursor);
|
||||||
|
final PhoneNumberContact preexisting = contacts.get(contact.getPhoneNumber());
|
||||||
|
if (preexisting == null || preexisting.rating() < contact.rating()) {
|
||||||
|
contacts.put(contact.getPhoneNumber(), contact);
|
||||||
|
}
|
||||||
|
} catch (final IllegalArgumentException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
return ImmutableMap.of();
|
return ImmutableMap.of();
|
||||||
}
|
}
|
||||||
final HashMap<String, PhoneNumberContact> contacts = new HashMap<>();
|
|
||||||
while (cursor != null && cursor.moveToNext()) {
|
|
||||||
try {
|
|
||||||
final PhoneNumberContact contact = new PhoneNumberContact(context, cursor);
|
|
||||||
final PhoneNumberContact preexisting = contacts.get(contact.getPhoneNumber());
|
|
||||||
if (preexisting == null || preexisting.rating() < contact.rating()) {
|
|
||||||
contacts.put(contact.getPhoneNumber(), contact);
|
|
||||||
}
|
|
||||||
} catch (final IllegalArgumentException e) {
|
|
||||||
Log.d(Config.LOGTAG, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
return ImmutableMap.copyOf(contacts);
|
return ImmutableMap.copyOf(contacts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PhoneNumberContact findByUriOrNumber(Collection<PhoneNumberContact> haystack, Uri uri, String number) {
|
||||||
|
final PhoneNumberContact byUri = findByUri(haystack, uri);
|
||||||
|
return byUri != null || number == null ? byUri : findByNumber(haystack, number);
|
||||||
|
}
|
||||||
|
|
||||||
public static PhoneNumberContact findByUri(Collection<PhoneNumberContact> haystack, Uri needle) {
|
public static PhoneNumberContact findByUri(Collection<PhoneNumberContact> haystack, Uri needle) {
|
||||||
for (PhoneNumberContact contact : haystack) {
|
for (PhoneNumberContact contact : haystack) {
|
||||||
if (needle.equals(contact.getLookupUri())) {
|
if (needle.equals(contact.getLookupUri())) {
|
||||||
|
@ -78,4 +78,13 @@ public class PhoneNumberContact extends AbstractPhoneContact {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static PhoneNumberContact findByNumber(Collection<PhoneNumberContact> haystack, String needle) {
|
||||||
|
for (PhoneNumberContact contact : haystack) {
|
||||||
|
if (needle.equals(contact.getPhoneNumber())) {
|
||||||
|
return contact;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@ package eu.siacs.conversations.entities;
|
||||||
|
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.hash.Hashing;
|
||||||
|
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -63,20 +66,15 @@ public class Entry implements Comparable<Entry> {
|
||||||
builder.append(jid.asBareJid().toEscapedString());
|
builder.append(jid.asBareJid().toEscapedString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MessageDigest md;
|
@SuppressWarnings("deprecation")
|
||||||
try {
|
final byte[] sha1 = Hashing.sha1().hashString(builder.toString(), Charsets.UTF_8).asBytes();
|
||||||
md = MessageDigest.getInstance("SHA-1");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
byte[] sha1 = md.digest(builder.toString().getBytes());
|
|
||||||
return new String(Base64.encode(sha1, Base64.DEFAULT)).trim();
|
return new String(Base64.encode(sha1, Base64.DEFAULT)).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Entry> ofPhoneNumberContactsAndContacts(final Collection<PhoneNumberContact> phoneNumberContacts, Collection<Contact> systemContacts) {
|
private static List<Entry> ofPhoneNumberContactsAndContacts(final Collection<PhoneNumberContact> phoneNumberContacts, Collection<Contact> systemContacts) {
|
||||||
ArrayList<Entry> entries = new ArrayList<>();
|
final ArrayList<Entry> entries = new ArrayList<>();
|
||||||
for(Contact contact : systemContacts) {
|
for(Contact contact : systemContacts) {
|
||||||
PhoneNumberContact phoneNumberContact = PhoneNumberContact.findByUri(phoneNumberContacts, contact.getSystemAccount());
|
final PhoneNumberContact phoneNumberContact = PhoneNumberContact.findByUri(phoneNumberContacts, contact.getSystemAccount());
|
||||||
if (phoneNumberContact != null && phoneNumberContact.getPhoneNumber() != null) {
|
if (phoneNumberContact != null && phoneNumberContact.getPhoneNumber() != null) {
|
||||||
Entry entry = findOrCreateByPhoneNumber(entries, phoneNumberContact.getPhoneNumber());
|
Entry entry = findOrCreateByPhoneNumber(entries, phoneNumberContact.getPhoneNumber());
|
||||||
entry.jids.add(contact.getJid().asBareJid());
|
entry.jids.add(contact.getJid().asBareJid());
|
||||||
|
|
|
@ -382,9 +382,13 @@ public class QuickConversationsService extends AbstractQuickConversationsService
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PhoneNumberContact phoneNumberContact = PhoneNumberContact.findByUri(contacts, uri);
|
final String number = getNumber(contact);
|
||||||
|
final PhoneNumberContact phoneNumberContact = PhoneNumberContact.findByUriOrNumber(contacts, uri, number);
|
||||||
final boolean needsCacheClean;
|
final boolean needsCacheClean;
|
||||||
if (phoneNumberContact != null) {
|
if (phoneNumberContact != null) {
|
||||||
|
if (!uri.equals(phoneNumberContact.getLookupUri())) {
|
||||||
|
Log.d(Config.LOGTAG, "lookupUri has changed from " + uri + " to " + phoneNumberContact.getLookupUri());
|
||||||
|
}
|
||||||
needsCacheClean = contact.setPhoneContact(phoneNumberContact);
|
needsCacheClean = contact.setPhoneContact(phoneNumberContact);
|
||||||
} else {
|
} else {
|
||||||
needsCacheClean = contact.unsetPhoneContact(PhoneNumberContact.class);
|
needsCacheClean = contact.unsetPhoneContact(PhoneNumberContact.class);
|
||||||
|
@ -396,6 +400,14 @@ public class QuickConversationsService extends AbstractQuickConversationsService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getNumber(final Contact contact) {
|
||||||
|
final Jid jid = contact.getJid();
|
||||||
|
if (jid.getLocal() != null && Config.QUICKSY_DOMAIN.equals(jid.getDomain())) {
|
||||||
|
return jid.getLocal();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean considerSync(final Account account, final Map<String, PhoneNumberContact> contacts, final boolean forced) {
|
private boolean considerSync(final Account account, final Map<String, PhoneNumberContact> contacts, final boolean forced) {
|
||||||
final int hash = contacts.keySet().hashCode();
|
final int hash = contacts.keySet().hashCode();
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": consider sync of " + hash);
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": consider sync of " + hash);
|
||||||
|
|
Loading…
Reference in a new issue