mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-25 05:39:18 +00:00
Remove the Canonical Address Database
This was a holdover from Signal's origins as a pure SMS app. It causes problems, depends on undefined device specific behavior, and should no longer be necessary now that we have all the information we need to E164 all numbers. // FREEBIE
This commit is contained in:
@@ -25,9 +25,9 @@ import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientProvider.RecipientDetails;
|
||||
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.ListenableFutureTask;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -42,9 +42,8 @@ public class Recipient {
|
||||
|
||||
private final Set<RecipientModifiedListener> listeners = Collections.newSetFromMap(new WeakHashMap<RecipientModifiedListener, Boolean>());
|
||||
|
||||
private final long recipientId;
|
||||
private final @NonNull Address address;
|
||||
|
||||
private @NonNull String number;
|
||||
private @Nullable String name;
|
||||
private @Nullable String customLabel;
|
||||
private boolean stale;
|
||||
@@ -55,13 +54,11 @@ public class Recipient {
|
||||
|
||||
@Nullable private MaterialColor color;
|
||||
|
||||
Recipient(long recipientId,
|
||||
@NonNull String number,
|
||||
Recipient(@NonNull Address address,
|
||||
@Nullable Recipient stale,
|
||||
@NonNull ListenableFutureTask<RecipientDetails> future)
|
||||
{
|
||||
this.recipientId = recipientId;
|
||||
this.number = number;
|
||||
this.address = address;
|
||||
this.contactPhoto = ContactPhotoFactory.getLoadingPhoto();
|
||||
this.color = null;
|
||||
this.resolving = true;
|
||||
@@ -80,7 +77,6 @@ public class Recipient {
|
||||
if (result != null) {
|
||||
synchronized (Recipient.this) {
|
||||
Recipient.this.name = result.name;
|
||||
Recipient.this.number = result.number;
|
||||
Recipient.this.contactUri = result.contactUri;
|
||||
Recipient.this.contactPhoto = result.avatar;
|
||||
Recipient.this.color = result.color;
|
||||
@@ -99,9 +95,8 @@ public class Recipient {
|
||||
});
|
||||
}
|
||||
|
||||
Recipient(long recipientId, RecipientDetails details) {
|
||||
this.recipientId = recipientId;
|
||||
this.number = details.number;
|
||||
Recipient(Address address, RecipientDetails details) {
|
||||
this.address = address;
|
||||
this.contactUri = details.contactUri;
|
||||
this.name = details.name;
|
||||
this.contactPhoto = details.avatar;
|
||||
@@ -132,20 +127,16 @@ public class Recipient {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
public @NonNull String getNumber() {
|
||||
return number;
|
||||
public @NonNull Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public @Nullable String getCustomLabel() {
|
||||
return customLabel;
|
||||
}
|
||||
|
||||
public long getRecipientId() {
|
||||
return recipientId;
|
||||
}
|
||||
|
||||
public boolean isGroupRecipient() {
|
||||
return GroupUtil.isEncodedGroup(number);
|
||||
return address.isGroup();
|
||||
}
|
||||
|
||||
public synchronized void addListener(RecipientModifiedListener listener) {
|
||||
@@ -157,17 +148,13 @@ public class Recipient {
|
||||
}
|
||||
|
||||
public synchronized String toShortString() {
|
||||
return (name == null ? number : name);
|
||||
return (name == null ? address.serialize() : name);
|
||||
}
|
||||
|
||||
public synchronized @NonNull ContactPhoto getContactPhoto() {
|
||||
return contactPhoto;
|
||||
}
|
||||
|
||||
public static Recipient getUnknownRecipient() {
|
||||
return new Recipient(-1, new RecipientDetails("Unknown", "Unknown", null, null,
|
||||
ContactPhotoFactory.getDefaultContactPhoto(null), null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
@@ -176,12 +163,12 @@ public class Recipient {
|
||||
|
||||
Recipient that = (Recipient) o;
|
||||
|
||||
return this.recipientId == that.recipientId;
|
||||
return this.address.equals(that.address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 + (int)this.recipientId;
|
||||
return this.address.hashCode();
|
||||
}
|
||||
|
||||
private void notifyListeners() {
|
||||
|
||||
@@ -19,16 +19,10 @@ package org.thoughtcrime.securesms.recipients;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.thoughtcrime.securesms.database.CanonicalAddressDatabase;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class RecipientFactory {
|
||||
|
||||
@@ -36,104 +30,32 @@ public class RecipientFactory {
|
||||
|
||||
private static final RecipientProvider provider = new RecipientProvider();
|
||||
|
||||
public static Recipients getRecipientsForIds(Context context, String recipientIds, boolean asynchronous) {
|
||||
if (TextUtils.isEmpty(recipientIds))
|
||||
return new Recipients();
|
||||
|
||||
return getRecipientsForIds(context, Util.split(recipientIds, " "), asynchronous);
|
||||
}
|
||||
|
||||
public static @NonNull Recipients getRecipientsFor(Context context, Collection<Recipient> recipients, boolean asynchronous) {
|
||||
long[] ids = new long[recipients.size()];
|
||||
Address[] addresses= new Address[recipients.size()];
|
||||
int i = 0;
|
||||
|
||||
for (Recipient recipient : recipients) {
|
||||
ids[i++] = recipient.getRecipientId();
|
||||
addresses[i++] = recipient.getAddress();
|
||||
}
|
||||
|
||||
return provider.getRecipients(context, ids, asynchronous);
|
||||
return provider.getRecipients(context, addresses, asynchronous);
|
||||
}
|
||||
|
||||
public static Recipients getRecipientsFor(Context context, Recipient recipient, boolean asynchronous) {
|
||||
long[] ids = new long[1];
|
||||
ids[0] = recipient.getRecipientId();
|
||||
Address[] addresses = new Address[1];
|
||||
addresses[0] = recipient.getAddress();
|
||||
|
||||
return provider.getRecipients(context, ids, asynchronous);
|
||||
return provider.getRecipients(context, addresses, asynchronous);
|
||||
}
|
||||
|
||||
public @NonNull static Recipient getRecipientForId(Context context, long recipientId, boolean asynchronous) {
|
||||
return provider.getRecipient(context, recipientId, asynchronous);
|
||||
public static @NonNull Recipients getRecipientsFor(@NonNull Context context, @NonNull Address[] addresses, boolean asynchronous) {
|
||||
if (addresses == null || addresses.length == 0) throw new AssertionError(addresses);
|
||||
return provider.getRecipients(context, addresses, asynchronous);
|
||||
}
|
||||
|
||||
public @NonNull static Recipients getRecipientsForIds(Context context, long[] recipientIds, boolean asynchronous) {
|
||||
return provider.getRecipients(context, recipientIds, asynchronous);
|
||||
}
|
||||
|
||||
public static @NonNull Recipients getRecipientsFromString(Context context, @NonNull String rawText, boolean asynchronous) {
|
||||
StringTokenizer tokenizer = new StringTokenizer(rawText, ",");
|
||||
List<String> ids = new LinkedList<>();
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
Optional<Long> id = getRecipientIdFromNumber(context, tokenizer.nextToken());
|
||||
|
||||
if (id.isPresent()) {
|
||||
ids.add(String.valueOf(id.get()));
|
||||
}
|
||||
}
|
||||
|
||||
return getRecipientsForIds(context, ids, asynchronous);
|
||||
}
|
||||
|
||||
public static @NonNull Recipients getRecipientsFromStrings(@NonNull Context context, @NonNull List<String> numbers, boolean asynchronous) {
|
||||
List<String> ids = new LinkedList<>();
|
||||
|
||||
for (String number : numbers) {
|
||||
Optional<Long> id = getRecipientIdFromNumber(context, number);
|
||||
|
||||
if (id.isPresent()) {
|
||||
ids.add(String.valueOf(id.get()));
|
||||
}
|
||||
}
|
||||
|
||||
return getRecipientsForIds(context, ids, asynchronous);
|
||||
}
|
||||
|
||||
private static @NonNull Recipients getRecipientsForIds(Context context, List<String> idStrings, boolean asynchronous) {
|
||||
long[] ids = new long[idStrings.size()];
|
||||
int i = 0;
|
||||
|
||||
for (String id : idStrings) {
|
||||
ids[i++] = Long.parseLong(id);
|
||||
}
|
||||
|
||||
return provider.getRecipients(context, ids, asynchronous);
|
||||
}
|
||||
|
||||
private static Optional<Long> getRecipientIdFromNumber(Context context, String number) {
|
||||
number = number.trim();
|
||||
|
||||
if (number.isEmpty()) return Optional.absent();
|
||||
|
||||
if (hasBracketedNumber(number)) {
|
||||
number = parseBracketedNumber(number);
|
||||
}
|
||||
|
||||
return Optional.of(CanonicalAddressDatabase.getInstance(context).getCanonicalAddressId(number));
|
||||
}
|
||||
|
||||
private static boolean hasBracketedNumber(String recipient) {
|
||||
int openBracketIndex = recipient.indexOf('<');
|
||||
|
||||
return (openBracketIndex != -1) &&
|
||||
(recipient.indexOf('>', openBracketIndex) != -1);
|
||||
}
|
||||
|
||||
private static String parseBracketedNumber(String recipient) {
|
||||
int begin = recipient.indexOf('<');
|
||||
int end = recipient.indexOf('>', begin);
|
||||
String value = recipient.substring(begin + 1, end);
|
||||
|
||||
return value;
|
||||
public static @NonNull Recipient getRecipientFor(@NonNull Context context, @NonNull Address address, boolean asynchronous) {
|
||||
if (address == null) throw new AssertionError(address);
|
||||
return provider.getRecipient(context, address, asynchronous);
|
||||
}
|
||||
|
||||
public static void clearCache(Context context) {
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.database.CanonicalAddressDatabase;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
||||
@@ -66,45 +66,43 @@ class RecipientProvider {
|
||||
};
|
||||
|
||||
private static final Map<String, RecipientDetails> STATIC_DETAILS = new HashMap<String, RecipientDetails>() {{
|
||||
put("262966", new RecipientDetails("Amazon", "262966", null, null,
|
||||
put("262966", new RecipientDetails("Amazon", null, null,
|
||||
ContactPhotoFactory.getResourceContactPhoto(R.drawable.ic_amazon),
|
||||
ContactColors.UNKNOWN_COLOR));
|
||||
}};
|
||||
|
||||
@NonNull Recipient getRecipient(Context context, long recipientId, boolean asynchronous) {
|
||||
Recipient cachedRecipient = recipientCache.get(recipientId);
|
||||
@NonNull Recipient getRecipient(Context context, Address address, boolean asynchronous) {
|
||||
Recipient cachedRecipient = recipientCache.get(address);
|
||||
if (cachedRecipient != null && !cachedRecipient.isStale() && (asynchronous || !cachedRecipient.isResolving())) {
|
||||
return cachedRecipient;
|
||||
}
|
||||
|
||||
String number = CanonicalAddressDatabase.getInstance(context).getAddressFromId(recipientId);
|
||||
|
||||
if (asynchronous) {
|
||||
cachedRecipient = new Recipient(recipientId, number, cachedRecipient, getRecipientDetailsAsync(context, recipientId, number));
|
||||
cachedRecipient = new Recipient(address, cachedRecipient, getRecipientDetailsAsync(context, address));
|
||||
} else {
|
||||
cachedRecipient = new Recipient(recipientId, getRecipientDetailsSync(context, recipientId, number));
|
||||
cachedRecipient = new Recipient(address, getRecipientDetailsSync(context, address));
|
||||
}
|
||||
|
||||
recipientCache.set(recipientId, cachedRecipient);
|
||||
recipientCache.set(address, cachedRecipient);
|
||||
return cachedRecipient;
|
||||
}
|
||||
|
||||
@NonNull Recipients getRecipients(Context context, long[] recipientIds, boolean asynchronous) {
|
||||
Recipients cachedRecipients = recipientsCache.get(new RecipientIds(recipientIds));
|
||||
@NonNull Recipients getRecipients(Context context, Address[] recipientAddresses, boolean asynchronous) {
|
||||
Recipients cachedRecipients = recipientsCache.get(new RecipientAddresses(recipientAddresses));
|
||||
if (cachedRecipients != null && !cachedRecipients.isStale() && (asynchronous || !cachedRecipients.isResolving())) {
|
||||
return cachedRecipients;
|
||||
}
|
||||
|
||||
List<Recipient> recipientList = new LinkedList<>();
|
||||
|
||||
for (long recipientId : recipientIds) {
|
||||
recipientList.add(getRecipient(context, recipientId, asynchronous));
|
||||
for (Address address : recipientAddresses) {
|
||||
recipientList.add(getRecipient(context, address, asynchronous));
|
||||
}
|
||||
|
||||
if (asynchronous) cachedRecipients = new Recipients(recipientList, cachedRecipients, getRecipientsPreferencesAsync(context, recipientIds));
|
||||
else cachedRecipients = new Recipients(recipientList, getRecipientsPreferencesSync(context, recipientIds));
|
||||
if (asynchronous) cachedRecipients = new Recipients(recipientList, cachedRecipients, getRecipientsPreferencesAsync(context, recipientAddresses));
|
||||
else cachedRecipients = new Recipients(recipientList, getRecipientsPreferencesSync(context, recipientAddresses));
|
||||
|
||||
recipientsCache.set(new RecipientIds(recipientIds), cachedRecipients);
|
||||
recipientsCache.set(new RecipientAddresses(recipientAddresses), cachedRecipients);
|
||||
return cachedRecipients;
|
||||
}
|
||||
|
||||
@@ -113,14 +111,12 @@ class RecipientProvider {
|
||||
recipientsCache.reset();
|
||||
}
|
||||
|
||||
private @NonNull ListenableFutureTask<RecipientDetails> getRecipientDetailsAsync(final Context context,
|
||||
final long recipientId,
|
||||
final @NonNull String number)
|
||||
private @NonNull ListenableFutureTask<RecipientDetails> getRecipientDetailsAsync(final Context context, final @NonNull Address address)
|
||||
{
|
||||
Callable<RecipientDetails> task = new Callable<RecipientDetails>() {
|
||||
@Override
|
||||
public RecipientDetails call() throws Exception {
|
||||
return getRecipientDetailsSync(context, recipientId, number);
|
||||
return getRecipientDetailsSync(context, address);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -129,15 +125,15 @@ class RecipientProvider {
|
||||
return future;
|
||||
}
|
||||
|
||||
private @NonNull RecipientDetails getRecipientDetailsSync(Context context, long recipientId, @NonNull String number) {
|
||||
if (GroupUtil.isEncodedGroup(number)) return getGroupRecipientDetails(context, number);
|
||||
else return getIndividualRecipientDetails(context, recipientId, number);
|
||||
private @NonNull RecipientDetails getRecipientDetailsSync(Context context, @NonNull Address address) {
|
||||
if (address.isGroup()) return getGroupRecipientDetails(context, address);
|
||||
else return getIndividualRecipientDetails(context, address);
|
||||
}
|
||||
|
||||
private @NonNull RecipientDetails getIndividualRecipientDetails(Context context, long recipientId, @NonNull String number) {
|
||||
Optional<RecipientsPreferences> preferences = DatabaseFactory.getRecipientPreferenceDatabase(context).getRecipientsPreferences(new long[]{recipientId});
|
||||
private @NonNull RecipientDetails getIndividualRecipientDetails(Context context, @NonNull Address address) {
|
||||
Optional<RecipientsPreferences> preferences = DatabaseFactory.getRecipientPreferenceDatabase(context).getRecipientsPreferences(new Address[]{address});
|
||||
MaterialColor color = preferences.isPresent() ? preferences.get().getColor() : null;
|
||||
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
|
||||
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address.toPhoneString()));
|
||||
Cursor cursor = context.getContentResolver().query(uri, CALLER_ID_PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
@@ -151,7 +147,7 @@ class RecipientProvider {
|
||||
Uri.withAppendedPath(Contacts.CONTENT_URI, cursor.getLong(2) + ""),
|
||||
name);
|
||||
|
||||
return new RecipientDetails(cursor.getString(0), resultNumber, cursor.getString(4), contactUri, contactPhoto, color);
|
||||
return new RecipientDetails(cursor.getString(0), cursor.getString(4), contactUri, contactPhoto, color);
|
||||
} else {
|
||||
Log.w(TAG, "resultNumber is null");
|
||||
}
|
||||
@@ -161,14 +157,14 @@ class RecipientProvider {
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
if (STATIC_DETAILS.containsKey(number)) return STATIC_DETAILS.get(number);
|
||||
else return new RecipientDetails(null, number, null, null, ContactPhotoFactory.getDefaultContactPhoto(null), color);
|
||||
if (STATIC_DETAILS.containsKey(address.toPhoneString())) return STATIC_DETAILS.get(address.toPhoneString());
|
||||
else return new RecipientDetails(null, null, null, ContactPhotoFactory.getDefaultContactPhoto(null), color);
|
||||
}
|
||||
|
||||
private @NonNull RecipientDetails getGroupRecipientDetails(Context context, String groupId) {
|
||||
private @NonNull RecipientDetails getGroupRecipientDetails(Context context, Address groupId) {
|
||||
try {
|
||||
GroupDatabase.GroupRecord record = DatabaseFactory.getGroupDatabase(context)
|
||||
.getGroup(GroupUtil.getDecodedId(groupId));
|
||||
.getGroup(GroupUtil.getDecodedId(groupId.toGroupString()));
|
||||
|
||||
if (record != null) {
|
||||
ContactPhoto contactPhoto = ContactPhotoFactory.getGroupContactPhoto(record.getAvatar());
|
||||
@@ -178,27 +174,27 @@ class RecipientProvider {
|
||||
title = context.getString(R.string.RecipientProvider_unnamed_group);;
|
||||
}
|
||||
|
||||
return new RecipientDetails(title, groupId, null, null, contactPhoto, null);
|
||||
return new RecipientDetails(title, null, null, contactPhoto, null);
|
||||
}
|
||||
|
||||
return new RecipientDetails(context.getString(R.string.RecipientProvider_unnamed_group), groupId, null, null, ContactPhotoFactory.getDefaultGroupPhoto(), null);
|
||||
return new RecipientDetails(context.getString(R.string.RecipientProvider_unnamed_group), null, null, ContactPhotoFactory.getDefaultGroupPhoto(), null);
|
||||
} catch (IOException e) {
|
||||
Log.w("RecipientProvider", e);
|
||||
return new RecipientDetails(context.getString(R.string.RecipientProvider_unnamed_group), groupId, null, null, ContactPhotoFactory.getDefaultGroupPhoto(), null);
|
||||
return new RecipientDetails(context.getString(R.string.RecipientProvider_unnamed_group), null, null, ContactPhotoFactory.getDefaultGroupPhoto(), null);
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable RecipientsPreferences getRecipientsPreferencesSync(Context context, long[] recipientIds) {
|
||||
private @Nullable RecipientsPreferences getRecipientsPreferencesSync(Context context, Address[] addresses) {
|
||||
return DatabaseFactory.getRecipientPreferenceDatabase(context)
|
||||
.getRecipientsPreferences(recipientIds)
|
||||
.getRecipientsPreferences(addresses)
|
||||
.orNull();
|
||||
}
|
||||
|
||||
private ListenableFutureTask<RecipientsPreferences> getRecipientsPreferencesAsync(final Context context, final long[] recipientIds) {
|
||||
private ListenableFutureTask<RecipientsPreferences> getRecipientsPreferencesAsync(final Context context, final Address[] addresses) {
|
||||
ListenableFutureTask<RecipientsPreferences> task = new ListenableFutureTask<>(new Callable<RecipientsPreferences>() {
|
||||
@Override
|
||||
public RecipientsPreferences call() throws Exception {
|
||||
return getRecipientsPreferencesSync(context, recipientIds);
|
||||
return getRecipientsPreferencesSync(context, addresses);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -209,52 +205,50 @@ class RecipientProvider {
|
||||
|
||||
public static class RecipientDetails {
|
||||
@Nullable public final String name;
|
||||
@NonNull public final String number;
|
||||
@Nullable public final String customLabel;
|
||||
@NonNull public final ContactPhoto avatar;
|
||||
@Nullable public final Uri contactUri;
|
||||
@Nullable public final MaterialColor color;
|
||||
|
||||
public RecipientDetails(@Nullable String name, @NonNull String number,
|
||||
@Nullable String customLabel, @Nullable Uri contactUri,
|
||||
@NonNull ContactPhoto avatar, @Nullable MaterialColor color)
|
||||
public RecipientDetails(@Nullable String name, @Nullable String customLabel,
|
||||
@Nullable Uri contactUri, @NonNull ContactPhoto avatar,
|
||||
@Nullable MaterialColor color)
|
||||
{
|
||||
this.name = name;
|
||||
this.customLabel = customLabel;
|
||||
this.number = number;
|
||||
this.avatar = avatar;
|
||||
this.contactUri = contactUri;
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
private static class RecipientIds {
|
||||
private final long[] ids;
|
||||
private static class RecipientAddresses {
|
||||
private final Address[] addresses;
|
||||
|
||||
private RecipientIds(long[] ids) {
|
||||
this.ids = ids;
|
||||
private RecipientAddresses(Address[] addresses) {
|
||||
this.addresses = addresses;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof RecipientIds)) return false;
|
||||
return Arrays.equals(this.ids, ((RecipientIds) other).ids);
|
||||
if (other == null || !(other instanceof RecipientAddresses)) return false;
|
||||
return Arrays.equals(this.addresses, ((RecipientAddresses) other).addresses);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(ids);
|
||||
return Arrays.hashCode(addresses);
|
||||
}
|
||||
}
|
||||
|
||||
private static class RecipientCache {
|
||||
|
||||
private final Map<Long,Recipient> cache = new LRUCache<>(1000);
|
||||
private final Map<Address,Recipient> cache = new LRUCache<>(1000);
|
||||
|
||||
public synchronized Recipient get(long recipientId) {
|
||||
return cache.get(recipientId);
|
||||
public synchronized Recipient get(Address address) {
|
||||
return cache.get(address);
|
||||
}
|
||||
|
||||
public synchronized void set(long recipientId, Recipient recipient) {
|
||||
cache.put(recipientId, recipient);
|
||||
public synchronized void set(Address address, Recipient recipient) {
|
||||
cache.put(address, recipient);
|
||||
}
|
||||
|
||||
public synchronized void reset() {
|
||||
@@ -267,14 +261,14 @@ class RecipientProvider {
|
||||
|
||||
private static class RecipientsCache {
|
||||
|
||||
private final Map<RecipientIds,Recipients> cache = new LRUCache<>(1000);
|
||||
private final Map<RecipientAddresses,Recipients> cache = new LRUCache<>(1000);
|
||||
|
||||
public synchronized Recipients get(RecipientIds ids) {
|
||||
return cache.get(ids);
|
||||
public synchronized Recipients get(RecipientAddresses addresses) {
|
||||
return cache.get(addresses);
|
||||
}
|
||||
|
||||
public synchronized void set(RecipientIds ids, Recipients recipients) {
|
||||
cache.put(ids, recipients);
|
||||
public synchronized void set(RecipientAddresses addresses, Recipients recipients) {
|
||||
cache.put(addresses, recipients);
|
||||
}
|
||||
|
||||
public synchronized void reset() {
|
||||
|
||||
@@ -20,20 +20,17 @@ import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.util.Patterns;
|
||||
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.VibrateState;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient.RecipientModifiedListener;
|
||||
import org.thoughtcrime.securesms.util.FutureTaskListener;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.ListenableFutureTask;
|
||||
import org.thoughtcrime.securesms.util.NumberUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -217,15 +214,16 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
|
||||
|
||||
public boolean isEmailRecipient() {
|
||||
for (Recipient recipient : recipients) {
|
||||
if (NumberUtil.isValidEmail(recipient.getNumber()))
|
||||
if (recipient.getAddress().isEmail()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isGroupRecipient() {
|
||||
return isSingleRecipient() && GroupUtil.isEncodedGroup(recipients.get(0).getNumber());
|
||||
return isSingleRecipient() && recipients.get(0).getAddress().isGroup();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
@@ -247,57 +245,20 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
|
||||
return this.recipients;
|
||||
}
|
||||
|
||||
public long[] getIds() {
|
||||
long[] ids = new long[recipients.size()];
|
||||
for (int i=0; i<recipients.size(); i++) {
|
||||
ids[i] = recipients.get(i).getRecipientId();
|
||||
public Address[] getAddresses() {
|
||||
Address[] addresses = new Address[recipients.size()];
|
||||
for (int i=0;i<recipients.size();i++) {
|
||||
addresses[i] = recipients.get(i).getAddress();
|
||||
}
|
||||
return ids;
|
||||
|
||||
Arrays.sort(addresses);
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public String getSortedIdsString() {
|
||||
Set<Long> recipientSet = new HashSet<>();
|
||||
|
||||
for (Recipient recipient : this.recipients) {
|
||||
recipientSet.add(recipient.getRecipientId());
|
||||
}
|
||||
|
||||
long[] recipientArray = new long[recipientSet.size()];
|
||||
int i = 0;
|
||||
|
||||
for (Long recipientId : recipientSet) {
|
||||
recipientArray[i++] = recipientId;
|
||||
}
|
||||
|
||||
Arrays.sort(recipientArray);
|
||||
|
||||
return Util.join(recipientArray, " ");
|
||||
}
|
||||
|
||||
public @NonNull String[] toNumberStringArray(boolean scrub) {
|
||||
String[] recipientsArray = new String[recipients.size()];
|
||||
Iterator<Recipient> iterator = recipients.iterator();
|
||||
int i = 0;
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
String number = iterator.next().getNumber();
|
||||
|
||||
if (scrub && number != null &&
|
||||
!Patterns.EMAIL_ADDRESS.matcher(number).matches() &&
|
||||
!GroupUtil.isEncodedGroup(number))
|
||||
{
|
||||
number = number.replaceAll("[^0-9+]", "");
|
||||
}
|
||||
|
||||
recipientsArray[i++] = number;
|
||||
}
|
||||
|
||||
return recipientsArray;
|
||||
}
|
||||
|
||||
public @NonNull List<String> toNumberStringList(boolean scrub) {
|
||||
List<String> results = new LinkedList<>();
|
||||
Collections.addAll(results, toNumberStringArray(scrub));
|
||||
public List<Address> getAddressesList() {
|
||||
List<Address> results = new LinkedList<>();
|
||||
Collections.addAll(results, getAddresses());
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user