diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index 5354fd7d0a..a979b62eab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -775,7 +775,7 @@ class ConversationFragment : ConversationUtil.refreshRecipientShortcuts() if (!args.conversationScreenType.isInBubble) { - AppDependencies.messageNotifier.clearVisibleThread() + AppDependencies.messageNotifier.clearVisibleThread(ConversationId.forConversation(args.threadId)) } else { AppDependencies.messageNotifier.clearVisibleBubbleThread() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/MessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/MessageNotifier.java index b8031de892..d46dc637a9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MessageNotifier.java @@ -18,6 +18,7 @@ public interface MessageNotifier { void setVisibleThread(@Nullable ConversationId conversationId); @NonNull Optional getVisibleThread(); void clearVisibleThread(); + void clearVisibleThread(@NonNull ConversationId conversationId); void setVisibleBubbleThread(@Nullable ConversationId conversationId); void clearVisibleBubbleThread(); void setLastDesktopActivityTimestamp(long timestamp); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java index b9cae54242..87ad2a2f02 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/OptimizedMessageNotifier.java @@ -52,6 +52,11 @@ public class OptimizedMessageNotifier implements MessageNotifier { getNotifier().clearVisibleThread(); } + @Override + public void clearVisibleThread(@NonNull ConversationId conversationId) { + getNotifier().clearVisibleThread(conversationId); + } + @Override public void setVisibleBubbleThread(@Nullable ConversationId conversationId) { getNotifier().setVisibleBubbleThread(conversationId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/DefaultMessageNotifier.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/DefaultMessageNotifier.kt index e9eb76d7a7..3e4b016f25 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/DefaultMessageNotifier.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/DefaultMessageNotifier.kt @@ -36,6 +36,7 @@ import java.util.concurrent.Executor import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicReference import kotlin.collections.MutableMap.MutableEntry import kotlin.math.max @@ -43,7 +44,7 @@ import kotlin.math.max * MessageNotifier implementation using the new system for creating and showing notifications. */ class DefaultMessageNotifier(context: Application) : MessageNotifier { - @Volatile private var visibleThread: ConversationId? = null + private val visibleThread: AtomicReference = AtomicReference(null) @Volatile private var visibleBubbleThread: ConversationId? = null @@ -66,7 +67,7 @@ class DefaultMessageNotifier(context: Application) : MessageNotifier { private val executor = CancelableExecutor() override fun setVisibleThread(conversationId: ConversationId?) { - visibleThread = conversationId + visibleThread.set(conversationId) stickyThreads.remove(conversationId) if (conversationId != null) { lastThreadNotification.remove(conversationId) @@ -74,13 +75,17 @@ class DefaultMessageNotifier(context: Application) : MessageNotifier { } override fun getVisibleThread(): Optional { - return Optional.ofNullable(visibleThread) + return Optional.ofNullable(visibleThread.get()) } override fun clearVisibleThread() { setVisibleThread(null) } + override fun clearVisibleThread(conversationId: ConversationId) { + visibleThread.compareAndSet(conversationId, null) + } + override fun setVisibleBubbleThread(conversationId: ConversationId?) { visibleBubbleThread = conversationId } @@ -94,7 +99,7 @@ class DefaultMessageNotifier(context: Application) : MessageNotifier { } override fun notifyMessageDeliveryFailed(context: Context, recipient: Recipient, conversationId: ConversationId) { - NotificationFactory.notifyMessageDeliveryFailed(context, recipient, conversationId, visibleThread, visibleBubbleThread) + NotificationFactory.notifyMessageDeliveryFailed(context, recipient, conversationId, visibleThread.get(), visibleBubbleThread) } override fun notifyStoryDeliveryFailed(context: Context, recipient: Recipient, conversationId: ConversationId) { @@ -102,7 +107,7 @@ class DefaultMessageNotifier(context: Application) : MessageNotifier { } override fun notifyProofRequired(context: Context, recipient: Recipient, conversationId: ConversationId) { - NotificationFactory.notifyProofRequired(context, recipient, conversationId, visibleThread) + NotificationFactory.notifyProofRequired(context, recipient, conversationId, visibleThread.get()) } override fun cancelDelayedNotifications() { @@ -194,7 +199,7 @@ class DefaultMessageNotifier(context: Application) : MessageNotifier { val threadsThatAlerted: Set = NotificationFactory.notify( context = ContextThemeWrapper(context, R.style.TextSecure_LightTheme), state = state, - visibleThread = visibleThread, + visibleThread = visibleThread.get(), targetThread = conversationId, defaultBubbleState = defaultBubbleState, lastAudibleNotification = lastAudibleNotification, @@ -219,7 +224,7 @@ class DefaultMessageNotifier(context: Application) : MessageNotifier { Log.i(TAG, "threads: ${state.threadCount} messages: ${state.messageCount}") if (Build.VERSION.SDK_INT >= 24) { - val ids = state.conversations.filter { it.thread != visibleThread }.map { it.notificationId } + stickyThreads.map { (_, stickyThread) -> stickyThread.notificationId } + val ids = state.conversations.filter { it.thread != visibleThread.get() }.map { it.notificationId } + stickyThreads.map { (_, stickyThread) -> stickyThread.notificationId } val notShown = ids - ServiceUtil.getNotificationManager(context).getDisplayedNotificationIds().getOrDefault(emptySet()) if (notShown.isNotEmpty()) { Log.e(TAG, "Notifications should be showing but are not for ${notShown.size} threads")