From e087b594ffd3e3639ddde7b9e40ded9b296e2351 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 21 Jan 2021 13:33:33 +0100 Subject: [PATCH] do not include own phone number in sycn fixes #3960 --- .../ui/widget/EmojiWrapperEditText.java | 3 +- .../android/PhoneNumberContact.java | 22 +++++----- .../services/QuickConversationsService.java | 42 +++++++++++++------ .../utils/PhoneNumberUtilWrapper.java | 2 +- 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/compat/java/eu/siacs/conversations/ui/widget/EmojiWrapperEditText.java b/src/compat/java/eu/siacs/conversations/ui/widget/EmojiWrapperEditText.java index 15b24d572..01905e376 100644 --- a/src/compat/java/eu/siacs/conversations/ui/widget/EmojiWrapperEditText.java +++ b/src/compat/java/eu/siacs/conversations/ui/widget/EmojiWrapperEditText.java @@ -1,9 +1,10 @@ package eu.siacs.conversations.ui.widget; import android.content.Context; -import androidx.emoji.widget.EmojiAppCompatEditText; import android.util.AttributeSet; +import androidx.emoji.widget.EmojiAppCompatEditText; + public class EmojiWrapperEditText extends EmojiAppCompatEditText { public EmojiWrapperEditText(Context context) { diff --git a/src/quicksy/java/eu/siacs/conversations/android/PhoneNumberContact.java b/src/quicksy/java/eu/siacs/conversations/android/PhoneNumberContact.java index 4515ec299..6afb5a0d7 100644 --- a/src/quicksy/java/eu/siacs/conversations/android/PhoneNumberContact.java +++ b/src/quicksy/java/eu/siacs/conversations/android/PhoneNumberContact.java @@ -9,6 +9,8 @@ import android.os.Build; import android.provider.ContactsContract; import android.util.Log; +import com.google.common.collect.ImmutableMap; + import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -20,7 +22,7 @@ import io.michaelrocks.libphonenumber.android.NumberParseException; public class PhoneNumberContact extends AbstractPhoneContact { - private String phoneNumber; + private final String phoneNumber; public String getPhoneNumber() { return phoneNumber; @@ -29,15 +31,15 @@ public class PhoneNumberContact extends AbstractPhoneContact { private PhoneNumberContact(Context context, Cursor cursor) throws IllegalArgumentException { super(cursor); try { - this.phoneNumber = PhoneNumberUtilWrapper.normalize(context,cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); + this.phoneNumber = PhoneNumberUtilWrapper.normalize(context, cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); } catch (NumberParseException | NullPointerException e) { throw new IllegalArgumentException(e); } } - public static Map load(Context context) { + public static ImmutableMap load(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { - return Collections.emptyMap(); + return ImmutableMap.of(); } final String[] PROJECTION = new String[]{ContactsContract.Data._ID, ContactsContract.Data.DISPLAY_NAME, @@ -47,8 +49,8 @@ public class PhoneNumberContact extends AbstractPhoneContact { final Cursor cursor; try { cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null); - } catch (Exception e) { - return Collections.emptyMap(); + } catch (final Exception e) { + return ImmutableMap.of(); } final HashMap contacts = new HashMap<>(); while (cursor != null && cursor.moveToNext()) { @@ -58,18 +60,18 @@ public class PhoneNumberContact extends AbstractPhoneContact { if (preexisting == null || preexisting.rating() < contact.rating()) { contacts.put(contact.getPhoneNumber(), contact); } - } catch (IllegalArgumentException e) { - Log.d(Config.LOGTAG, "unable to create phone contact"); + } catch (final IllegalArgumentException e) { + Log.d(Config.LOGTAG, e.getMessage()); } } if (cursor != null) { cursor.close(); } - return contacts; + return ImmutableMap.copyOf(contacts); } public static PhoneNumberContact findByUri(Collection haystack, Uri needle) { - for(PhoneNumberContact contact : haystack) { + for (PhoneNumberContact contact : haystack) { if (needle.equals(contact.getLookupUri())) { return contact; } diff --git a/src/quicksy/java/eu/siacs/conversations/services/QuickConversationsService.java b/src/quicksy/java/eu/siacs/conversations/services/QuickConversationsService.java index c5d1d7b9b..05b076424 100644 --- a/src/quicksy/java/eu/siacs/conversations/services/QuickConversationsService.java +++ b/src/quicksy/java/eu/siacs/conversations/services/QuickConversationsService.java @@ -9,6 +9,8 @@ import android.os.SystemClock; import android.preference.PreferenceManager; import android.util.Log; +import com.google.common.collect.ImmutableMap; + import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStream; @@ -24,6 +26,7 @@ import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -350,8 +353,12 @@ public class QuickConversationsService extends AbstractQuickConversationsService private void considerSync(boolean forced) { - Map contacts = PhoneNumberContact.load(service); - for (Account account : service.getAccounts()) { + final ImmutableMap allContacts = PhoneNumberContact.load(service); + for (final Account account : service.getAccounts()) { + final Map contacts = filtered(allContacts, account.getJid().getLocal()); + if (contacts.size() < allContacts.size()) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": found own phone number in address book. ignoring..."); + } refresh(account, contacts.values()); if (!considerSync(account, contacts, forced)) { service.syncRoster(account); @@ -359,6 +366,15 @@ public class QuickConversationsService extends AbstractQuickConversationsService } } + @SafeVarargs + private static Map filtered(final Map input, final A... filters) { + final HashMap result = new HashMap<>(input); + for (final A filtered : filters) { + result.remove(filtered); + } + return result; + } + private void refresh(Account account, Collection contacts) { for (Contact contact : account.getRoster().getWithSystemAccounts(PhoneNumberContact.class)) { final Uri uri = contact.getSystemAccount(); @@ -379,7 +395,7 @@ public class QuickConversationsService extends AbstractQuickConversationsService } } - private boolean considerSync(Account account, final Map contacts, final boolean forced) { + private boolean considerSync(final Account account, final Map contacts, final boolean forced) { final int hash = contacts.keySet().hashCode(); Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": consider sync of " + hash); if (!mLastSyncAttempt.retry(hash) && !forced) { @@ -389,14 +405,14 @@ public class QuickConversationsService extends AbstractQuickConversationsService mRunningSyncJobs.incrementAndGet(); final Jid syncServer = Jid.of(API_DOMAIN); Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": sending phone list to " + syncServer); - List entries = new ArrayList<>(); - for (PhoneNumberContact c : contacts.values()) { + final List entries = new ArrayList<>(); + for (final PhoneNumberContact c : contacts.values()) { entries.add(new Element("entry").setAttribute("number", c.getPhoneNumber())); } - IqPacket query = new IqPacket(IqPacket.TYPE.GET); + final IqPacket query = new IqPacket(IqPacket.TYPE.GET); query.setTo(syncServer); - Element book = new Element("phone-book", Namespace.SYNCHRONIZATION).setChildren(entries); - String statusQuo = Entry.statusQuo(contacts.values(), account.getRoster().getWithSystemAccounts(PhoneNumberContact.class)); + final Element book = new Element("phone-book", Namespace.SYNCHRONIZATION).setChildren(entries); + final String statusQuo = Entry.statusQuo(contacts.values(), account.getRoster().getWithSystemAccounts(PhoneNumberContact.class)); book.setAttribute("ver", statusQuo); query.addChild(book); mLastSyncAttempt = Attempt.create(hash); @@ -404,14 +420,14 @@ public class QuickConversationsService extends AbstractQuickConversationsService if (response.getType() == IqPacket.TYPE.RESULT) { final Element phoneBook = response.findChild("phone-book", Namespace.SYNCHRONIZATION); if (phoneBook != null) { - List withSystemAccounts = account.getRoster().getWithSystemAccounts(PhoneNumberContact.class); + final List withSystemAccounts = account.getRoster().getWithSystemAccounts(PhoneNumberContact.class); for (Entry entry : Entry.ofPhoneBook(phoneBook)) { - PhoneNumberContact phoneContact = contacts.get(entry.getNumber()); + final PhoneNumberContact phoneContact = contacts.get(entry.getNumber()); if (phoneContact == null) { continue; } - for (Jid jid : entry.getJids()) { - Contact contact = account.getRoster().getContact(jid); + for (final Jid jid : entry.getJids()) { + final Contact contact = account.getRoster().getContact(jid); final boolean needsCacheClean = contact.setPhoneContact(phoneContact); if (needsCacheClean) { service.getAvatarService().clear(contact); @@ -419,7 +435,7 @@ public class QuickConversationsService extends AbstractQuickConversationsService withSystemAccounts.remove(contact); } } - for (Contact contact : withSystemAccounts) { + for (final Contact contact : withSystemAccounts) { final boolean needsCacheClean = contact.unsetPhoneContact(PhoneNumberContact.class); if (needsCacheClean) { service.getAvatarService().clear(contact); diff --git a/src/quicksy/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java b/src/quicksy/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java index 5f68c2a06..4bc18b886 100644 --- a/src/quicksy/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java +++ b/src/quicksy/java/eu/siacs/conversations/utils/PhoneNumberUtilWrapper.java @@ -37,7 +37,7 @@ public class PhoneNumberUtilWrapper { public static String normalize(Context context, String input) throws IllegalArgumentException, NumberParseException { final Phonenumber.PhoneNumber number = getInstance(context).parse(input, LocationProvider.getUserCountry(context)); if (!getInstance(context).isValidNumber(number)) { - throw new IllegalArgumentException("Not a valid phone number"); + throw new IllegalArgumentException(String.format("%s is not a valid phone number", input)); } return normalize(context, number); }