Add support for granular conversation data changes.

This commit is contained in:
Greyson Parrelli
2021-08-30 15:08:38 -04:00
parent bca2205945
commit f5a6d61362
28 changed files with 502 additions and 162 deletions

View File

@@ -5,6 +5,7 @@ import android.app.Application;
import androidx.annotation.NonNull;
import org.signal.core.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.database.model.MessageId;
import org.thoughtcrime.securesms.util.concurrent.SerialExecutor;
import java.util.HashMap;
@@ -24,13 +25,15 @@ public final class DatabaseObserver {
private final Application application;
private final Executor executor;
private final Set<Observer> conversationListObservers;
private final Map<Long, Set<Observer>> conversationObservers;
private final Map<Long, Set<Observer>> verboseConversationObservers;
private final Map<UUID, Set<Observer>> paymentObservers;
private final Set<Observer> allPaymentsObservers;
private final Set<Observer> chatColorsObservers;
private final Set<Observer> stickerPackObservers;
private final Set<Observer> conversationListObservers;
private final Map<Long, Set<Observer>> conversationObservers;
private final Map<Long, Set<Observer>> verboseConversationObservers;
private final Map<UUID, Set<Observer>> paymentObservers;
private final Set<Observer> allPaymentsObservers;
private final Set<Observer> chatColorsObservers;
private final Set<Observer> stickerPackObservers;
private final Set<MessageObserver> messageUpdateObservers;
private final Map<Long, Set<MessageObserver>> messageInsertObservers;
public DatabaseObserver(Application application) {
this.application = application;
@@ -42,6 +45,8 @@ public final class DatabaseObserver {
this.allPaymentsObservers = new HashSet<>();
this.chatColorsObservers = new HashSet<>();
this.stickerPackObservers = new HashSet<>();
this.messageUpdateObservers = new HashSet<>();
this.messageInsertObservers = new HashMap<>();
}
public void registerConversationListObserver(@NonNull Observer listener) {
@@ -86,6 +91,18 @@ public final class DatabaseObserver {
});
}
public void registerMessageUpdateObserver(@NonNull MessageObserver listener) {
executor.execute(() -> {
messageUpdateObservers.add(listener);
});
}
public void registerMessageInsertObserver(long threadId, @NonNull MessageObserver listener) {
executor.execute(() -> {
registerMapped(messageInsertObservers, threadId, listener);
});
}
public void unregisterObserver(@NonNull Observer listener) {
executor.execute(() -> {
conversationListObservers.remove(listener);
@@ -97,6 +114,12 @@ public final class DatabaseObserver {
});
}
public void unregisterObserver(@NonNull MessageObserver listener) {
executor.execute(() -> {
messageUpdateObservers.remove(listener);
});
}
public void notifyConversationListeners(Set<Long> threadIds) {
executor.execute(() -> {
for (long threadId : threadIds) {
@@ -177,8 +200,24 @@ public final class DatabaseObserver {
});
}
private <K> void registerMapped(@NonNull Map<K, Set<Observer>> map, @NonNull K key, @NonNull Observer listener) {
Set<Observer> listeners = map.get(key);
public void notifyMessageUpdateObservers(@NonNull MessageId messageId) {
executor.execute(() -> {
messageUpdateObservers.stream().forEach(l -> l.onMessageChanged(messageId));
});
}
public void notifyMessageInsertObservers(long threadId, @NonNull MessageId messageId) {
executor.execute(() -> {
Set<MessageObserver> listeners = messageInsertObservers.get(threadId);
if (listeners != null) {
listeners.stream().forEach(l -> l.onMessageChanged(messageId));
}
});
}
private <K, V> void registerMapped(@NonNull Map<K, Set<V>> map, @NonNull K key, @NonNull V listener) {
Set<V> listeners = map.get(key);
if (listeners == null) {
listeners = new HashSet<>();
@@ -217,4 +256,8 @@ public final class DatabaseObserver {
*/
void onChanged();
}
public interface MessageObserver {
void onMessageChanged(@NonNull MessageId messageId);
}
}

View File

@@ -769,14 +769,14 @@ public class MmsDatabase extends MessageDatabase {
public void markAsForcedSms(long messageId) {
long threadId = getThreadIdForMessage(messageId);
updateMailboxBitmask(messageId, Types.PUSH_MESSAGE_BIT, Types.MESSAGE_FORCE_SMS_BIT, Optional.of(threadId));
notifyConversationListeners(threadId);
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(new MessageId(messageId, true));
}
@Override
public void markAsRateLimited(long messageId) {
long threadId = getThreadIdForMessage(messageId);
updateMailboxBitmask(messageId, 0, Types.MESSAGE_RATE_LIMITED_BIT, Optional.of(threadId));
notifyConversationListeners(threadId);
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(new MessageId(messageId, true));
}
@Override
@@ -800,28 +800,28 @@ public class MmsDatabase extends MessageDatabase {
public void markAsPendingInsecureSmsFallback(long messageId) {
long threadId = getThreadIdForMessage(messageId);
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_PENDING_INSECURE_SMS_FALLBACK, Optional.of(threadId));
notifyConversationListeners(threadId);
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(new MessageId(messageId, true));
}
@Override
public void markAsSending(long messageId) {
long threadId = getThreadIdForMessage(messageId);
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_SENDING_TYPE, Optional.of(threadId));
notifyConversationListeners(threadId);
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(new MessageId(messageId, true));
}
@Override
public void markAsSentFailed(long messageId) {
long threadId = getThreadIdForMessage(messageId);
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_SENT_FAILED_TYPE, Optional.of(threadId));
notifyConversationListeners(threadId);
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(new MessageId(messageId, true));
}
@Override
public void markAsSent(long messageId, boolean secure) {
long threadId = getThreadIdForMessage(messageId);
updateMailboxBitmask(messageId, Types.BASE_TYPE_MASK, Types.BASE_SENT_TYPE | (secure ? Types.PUSH_MESSAGE_BIT | Types.SECURE_MESSAGE_BIT : 0), Optional.of(threadId));
notifyConversationListeners(threadId);
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(new MessageId(messageId, true));
}
@Override
@@ -854,7 +854,7 @@ public class MmsDatabase extends MessageDatabase {
} finally {
db.endTransaction();
}
notifyConversationListeners(threadId);
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(new MessageId(messageId, true));
}
@Override
@@ -864,7 +864,7 @@ public class MmsDatabase extends MessageDatabase {
contentValues.put(STATUS, state);
database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {messageId + ""});
notifyConversationListeners(getThreadIdForMessage(messageId));
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(new MessageId(messageId, true));
}
@Override
@@ -1559,7 +1559,7 @@ public class MmsDatabase extends MessageDatabase {
DatabaseFactory.getThreadDatabase(context).setLastSeenSilently(threadId);
DatabaseFactory.getThreadDatabase(context).setHasSentSilently(threadId, true);
notifyConversationListeners(threadId);
ApplicationDependencies.getDatabaseObserver().notifyMessageInsertObservers(threadId, new MessageId(messageId, true));
notifyConversationListListeners();
TrimThreadJob.enqueueAsync(threadId);
@@ -1651,7 +1651,6 @@ public class MmsDatabase extends MessageDatabase {
long contentValuesThreadId = contentValues.getAsLong(THREAD_ID);
notifyConversationListeners(contentValuesThreadId);
DatabaseFactory.getThreadDatabase(context).setLastScrolled(contentValuesThreadId, 0);
ThreadUpdateJob.enqueue(contentValuesThreadId);
}

View File

@@ -59,7 +59,6 @@ import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.CursorUtil;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.SqlUtil;
import org.thoughtcrime.securesms.util.Stopwatch;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libsignal.util.Pair;
@@ -198,7 +197,7 @@ public class SmsDatabase extends MessageDatabase {
db.endTransaction();
}
notifyConversationListeners(threadId);
ApplicationDependencies.getDatabaseObserver().notifyMessageUpdateObservers(new MessageId(id, false));
}
@Override
@@ -1235,7 +1234,7 @@ public class SmsDatabase extends MessageDatabase {
DatabaseFactory.getThreadDatabase(context).setHasSentSilently(threadId, true);
notifyConversationListeners(threadId);
ApplicationDependencies.getDatabaseObserver().notifyMessageInsertObservers(threadId, new MessageId(messageId, false));
if (!message.isIdentityVerified() && !message.isIdentityDefault()) {
TrimThreadJob.enqueueAsync(threadId);