mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 00:59:49 +01:00
Add support for granular conversation data changes.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user