Don't invalidate entire recipient cache when contact data changes

This commit is contained in:
Moxie Marlinspike
2017-11-20 14:48:39 -08:00
parent 8f6440ce17
commit 66e1be1aeb
9 changed files with 92 additions and 198 deletions

View File

@@ -1,5 +1,6 @@
/**
/*
* Copyright (C) 2011 Whisper Systems
* Copyright (C) 2013 - 2017 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,7 +18,6 @@
package org.thoughtcrime.securesms.recipients;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.NonNull;
@@ -50,9 +50,8 @@ import java.util.concurrent.ExecutionException;
public class Recipient implements RecipientModifiedListener {
public static final String RECIPIENT_CLEAR_ACTION = "org.thoughtcrime.securesms.database.RecipientFactory.CLEAR";
private static final String TAG = Recipient.class.getSimpleName();
private static final RecipientProvider provider = new RecipientProvider();
private static final String TAG = Recipient.class.getSimpleName();
private static final RecipientProvider provider = new RecipientProvider();
private final Set<RecipientModifiedListener> listeners = Collections.newSetFromMap(new WeakHashMap<RecipientModifiedListener, Boolean>());
@@ -61,7 +60,6 @@ public class Recipient implements RecipientModifiedListener {
private @Nullable String name;
private @Nullable String customLabel;
private boolean stale;
private boolean resolving;
private @Nullable ContactPhoto contactPhoto;
@@ -84,21 +82,18 @@ public class Recipient implements RecipientModifiedListener {
private boolean isSystemContact;
@SuppressWarnings("ConstantConditions")
public static @NonNull Recipient from(@NonNull Context context, @NonNull Address address, boolean asynchronous) {
if (address == null) throw new AssertionError(address);
return provider.getRecipient(context, address, Optional.absent(), Optional.absent(), asynchronous);
}
@SuppressWarnings("ConstantConditions")
public static @NonNull Recipient from(@NonNull Context context, @NonNull Address address, @NonNull Optional<RecipientSettings> settings, @NonNull Optional<GroupDatabase.GroupRecord> groupRecord, boolean asynchronous) {
if (address == null) throw new AssertionError(address);
return provider.getRecipient(context, address, settings, groupRecord, asynchronous);
}
public static void clearCache(Context context) {
provider.clearCache();
context.sendBroadcast(new Intent(RECIPIENT_CLEAR_ACTION));
}
Recipient(@NonNull Address address,
@Nullable Recipient stale,
@NonNull Optional<RecipientDetails> details,
@@ -246,6 +241,19 @@ public class Recipient implements RecipientModifiedListener {
return this.name;
}
public void setName(@Nullable String name) {
boolean notify = false;
synchronized (this) {
if (!Util.equals(this.name, name)) {
this.name = name;
notify = true;
}
}
if (notify) notifyListeners();
}
public synchronized @NonNull MaterialColor getColor() {
if (isGroupRecipient()) return MaterialColor.GROUP;
else if (color != null) return color;
@@ -333,6 +341,15 @@ public class Recipient implements RecipientModifiedListener {
return participants;
}
public void setParticipants(@NonNull List<Recipient> participants) {
synchronized (this) {
this.participants.clear();
this.participants.addAll(participants);
}
notifyListeners();
}
public synchronized void addListener(RecipientModifiedListener listener) {
if (listeners.isEmpty()) {
for (Recipient recipient : participants) recipient.addListener(this);
@@ -452,11 +469,16 @@ public class Recipient implements RecipientModifiedListener {
}
public void setRegistered(@NonNull RegisteredState value) {
boolean notify = false;
synchronized (this) {
this.registered = value;
if (this.registered != value) {
this.registered = value;
notify = true;
}
}
notifyListeners();
if (notify) notifyListeners();
}
public synchronized @Nullable byte[] getProfileKey() {
@@ -475,15 +497,6 @@ public class Recipient implements RecipientModifiedListener {
return isSystemContact;
}
public void setSystemDisplayName(@Nullable String displayName) {
synchronized (this) {
if (displayName == null) this.name = profileName;
else this.name = displayName;
}
notifyListeners();
}
public synchronized Recipient resolve() {
while (resolving) Util.wait(this, 0);
return this;
@@ -521,15 +534,6 @@ public class Recipient implements RecipientModifiedListener {
notifyListeners();
}
boolean isStale() {
return stale;
}
void setStale() {
this.stale = true;
}
// XXX This shouldn't be public, temporary workaround
public synchronized boolean isResolving() {
return resolving;
}

View File

@@ -77,7 +77,7 @@ class RecipientProvider {
@NonNull Recipient getRecipient(Context context, Address address, Optional<RecipientSettings> settings, Optional<GroupRecord> groupRecord, boolean asynchronous) {
Recipient cachedRecipient = recipientCache.get(address);
if (cachedRecipient != null && !cachedRecipient.isStale() && (asynchronous || !cachedRecipient.isResolving()) && ((!groupRecord.isPresent() && !settings.isPresent()) || !cachedRecipient.isResolving() || cachedRecipient.getName() != null)) {
if (cachedRecipient != null && (asynchronous || !cachedRecipient.isResolving()) && ((!groupRecord.isPresent() && !settings.isPresent()) || !cachedRecipient.isResolving() || cachedRecipient.getName() != null)) {
return cachedRecipient;
}
@@ -93,10 +93,6 @@ class RecipientProvider {
return cachedRecipient;
}
void clearCache() {
recipientCache.reset();
}
private @NonNull Optional<RecipientDetails> createPrefetchedRecipientDetails(@NonNull Context context, @NonNull Address address,
@NonNull Optional<RecipientSettings> settings,
@NonNull Optional<GroupRecord> groupRecord)
@@ -276,12 +272,6 @@ class RecipientProvider {
cache.put(address, recipient);
}
public synchronized void reset() {
for (Recipient recipient : cache.values()) {
recipient.setStale();
}
}
}
}