diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java index 1296c3cd2..93a6405e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.dependencies; import android.app.Application; +import androidx.annotation.MainThread; import androidx.annotation.NonNull; import org.thoughtcrime.securesms.BuildConfig; @@ -61,13 +62,15 @@ public class ApplicationDependencies { private static InitialMessageRetriever initialMessageRetriever; private static MessageNotifier messageNotifier; + @MainThread public static synchronized void init(@NonNull Application application, @NonNull Provider provider) { if (ApplicationDependencies.application != null || ApplicationDependencies.provider != null) { throw new IllegalStateException("Already initialized!"); } - ApplicationDependencies.application = application; - ApplicationDependencies.provider = provider; + ApplicationDependencies.application = application; + ApplicationDependencies.provider = provider; + ApplicationDependencies.messageNotifier = provider.provideMessageNotifier(); } public static @NonNull Application getApplication() { @@ -251,11 +254,6 @@ public class ApplicationDependencies { public static synchronized @NonNull MessageNotifier getMessageNotifier() { assertInitialization(); - - if (messageNotifier == null) { - messageNotifier = provider.provideMessageNotifier(); - } - return messageNotifier; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java index 83c3791fe..87fae5ab8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java @@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.megaphone.MegaphoneRepository; import org.thoughtcrime.securesms.messages.InitialMessageRetriever; import org.thoughtcrime.securesms.notifications.DefaultMessageNotifier; import org.thoughtcrime.securesms.notifications.MessageNotifier; +import org.thoughtcrime.securesms.notifications.OptimizedMessageNotifier; import org.thoughtcrime.securesms.push.SecurityEventListener; import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; import org.thoughtcrime.securesms.recipients.LiveRecipientCache; @@ -162,7 +163,7 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr @Override public @NonNull MessageNotifier provideMessageNotifier() { - return new DefaultMessageNotifier(); + return new OptimizedMessageNotifier(new DefaultMessageNotifier()); } private static class DynamicCredentialsProvider implements CredentialsProvider { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/InitialMessageRetriever.java b/app/src/main/java/org/thoughtcrime/securesms/messages/InitialMessageRetriever.java index 079c63b7b..f2e23e616 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/InitialMessageRetriever.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/InitialMessageRetriever.java @@ -8,6 +8,7 @@ import androidx.annotation.WorkerThread; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.logging.Log; +import org.thoughtcrime.securesms.notifications.MessageNotifier; import org.thoughtcrime.securesms.util.concurrent.SignalExecutors; import java.util.List; @@ -102,6 +103,8 @@ public class InitialMessageRetriever { listeners.clear(); } + ApplicationDependencies.getMessageNotifier().updateNotification(ApplicationDependencies.getApplication()); + if (success) { Log.i(TAG, "Successfully caught up in " + (System.currentTimeMillis() - startTime) + " ms."); return Result.SUCCESS; diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java new file mode 100644 index 000000000..a30aa3e87 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java @@ -0,0 +1,97 @@ +package org.thoughtcrime.securesms.notifications; + +import android.content.Context; + +import androidx.annotation.MainThread; +import androidx.annotation.NonNull; + +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; +import org.thoughtcrime.securesms.messages.InitialMessageRetriever; +import org.thoughtcrime.securesms.recipients.Recipient; +import org.thoughtcrime.securesms.util.Throttler; + +import java.util.concurrent.TimeUnit; + +/** + * Wraps another {@link MessageNotifier} and throttles it while {@link InitialMessageRetriever} is + * running. + */ +public class OptimizedMessageNotifier implements MessageNotifier { + + private final MessageNotifier wrapped; + private final Throttler throttler; + private final InitialMessageRetriever retriever; + + @MainThread + public OptimizedMessageNotifier(@NonNull MessageNotifier wrapped) { + this.wrapped = wrapped; + this.throttler = new Throttler(TimeUnit.SECONDS.toMillis(5)); + this.retriever = ApplicationDependencies.getInitialMessageRetriever(); + } + + @Override + public void setVisibleThread(long threadId) { + wrapped.setVisibleThread(threadId); + } + + @Override + public void clearVisibleThread() { + wrapped.clearVisibleThread(); + } + + @Override + public void setLastDesktopActivityTimestamp(long timestamp) { + wrapped.setLastDesktopActivityTimestamp(timestamp); + } + + @Override + public void notifyMessageDeliveryFailed(Context context, Recipient recipient, long threadId) { + wrapped.notifyMessageDeliveryFailed(context, recipient, threadId); + } + + @Override + public void cancelDelayedNotifications() { + wrapped.cancelDelayedNotifications(); + } + + @Override + public void updateNotification(@NonNull Context context) { + if (retriever.isCaughtUp()) { + wrapped.updateNotification(context); + } else { + throttler.publish(() -> wrapped.updateNotification(context)); + } + } + + @Override + public void updateNotification(@NonNull Context context, long threadId) { + if (retriever.isCaughtUp()) { + wrapped.updateNotification(context, threadId); + } else { + throttler.publish(() -> wrapped.updateNotification(context)); + } + } + + @Override + public void updateNotification(@NonNull Context context, long threadId, boolean signal) { + if (retriever.isCaughtUp()) { + wrapped.updateNotification(context, threadId, signal); + } else { + throttler.publish(() -> wrapped.updateNotification(context)); + } + } + + @Override + public void updateNotification(@NonNull Context context, long threadId, boolean signal, int reminderCount) { + if (retriever.isCaughtUp()) { + wrapped.updateNotification(context, threadId, signal, reminderCount); + } else { + throttler.publish(() -> wrapped.updateNotification(context)); + } + } + + @Override + public void clearReminder(@NonNull Context context) { + wrapped.clearReminder(context); + } +}