Improve notification channel consistency checks with Android Conversations.

This commit is contained in:
Cody Henthorne
2021-06-07 15:58:39 -04:00
committed by GitHub
parent 36443c59f9
commit bece58d939
8 changed files with 108 additions and 15 deletions

View File

@@ -176,10 +176,15 @@ public final class NotificationCancellationHelper {
return true;
}
RecipientId recipientId = RecipientId.from(notification.getShortcutId());
Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipientId);
RecipientId recipientId = ConversationUtil.getRecipientId(notification.getShortcutId());
if (recipientId == null) {
Log.d(TAG, "isCancellable: Unable to get recipient from shortcut id");
return true;
}
Long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipientId);
long focusedThreadId = ApplicationDependencies.getMessageNotifier().getVisibleThread();
if (Objects.equals(threadId, focusedThreadId)) {
Log.d(TAG, "isCancellable: user entered full screen thread.");
return true;

View File

@@ -31,6 +31,8 @@ import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.ConversationUtil;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@@ -38,8 +40,12 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import static org.thoughtcrime.securesms.util.ConversationUtil.CONVERSATION_SUPPORT_VERSION;
public class NotificationChannels {
private static final String TAG = Log.tag(NotificationChannels.class);
@@ -165,7 +171,7 @@ public class NotificationChannels {
Uri messageRingtone = recipient.getMessageRingtone() != null ? recipient.getMessageRingtone() : getMessageRingtone(context);
String displayName = recipient.getDisplayName(context);
return createChannelFor(context, generateChannelIdFor(recipient), displayName, messageRingtone, vibrationEnabled);
return createChannelFor(context, generateChannelIdFor(recipient), displayName, messageRingtone, vibrationEnabled, ConversationUtil.getShortcutId(recipient));
}
/**
@@ -175,7 +181,8 @@ public class NotificationChannels {
@NonNull String channelId,
@NonNull String displayName,
@Nullable Uri messageSound,
boolean vibrationEnabled)
boolean vibrationEnabled,
@Nullable String shortcutId)
{
if (!supported()) {
return null;
@@ -193,6 +200,10 @@ public class NotificationChannels {
.build());
}
if (Build.VERSION.SDK_INT >= CONVERSATION_SUPPORT_VERSION && shortcutId != null) {
channel.setConversationId(getMessagesChannel(context), shortcutId);
}
NotificationManager notificationManager = ServiceUtil.getNotificationManager(context);
notificationManager.createNotificationChannel(channel);
@@ -465,6 +476,32 @@ public class NotificationChannels {
}
}
/**
* Attempt to update a recipient with shortcut based notification channel if the system made one for us and we don't
* have a channel set yet.
*
* @return true if a shortcut based notification channel was found and then associated with the recipient, false otherwise
*/
@WorkerThread
public static boolean updateWithShortcutBasedChannel(@NonNull Context context, @NonNull Recipient recipient) {
if (Build.VERSION.SDK_INT >= CONVERSATION_SUPPORT_VERSION && TextUtils.isEmpty(recipient.getNotificationChannel())) {
String shortcutId = ConversationUtil.getShortcutId(recipient);
Optional<NotificationChannel> channel = ServiceUtil.getNotificationManager(context)
.getNotificationChannels()
.stream()
.filter(c -> Objects.equals(shortcutId, c.getConversationId()))
.findFirst();
if (channel.isPresent()) {
Log.i(TAG, "Conversation channel created outside of app, while running. Update " + recipient.getId() + " to use '" + channel.get().getId() + "'");
DatabaseFactory.getRecipientDatabase(context).setNotificationChannel(recipient.getId(), channel.get().getId());
return true;
}
}
return false;
}
/**
* Updates the name of an existing channel to match the recipient's current name. Will have no
* effect if the recipient doesn't have an existing valid channel.
@@ -516,8 +553,24 @@ public class NotificationChannels {
if (existingChannel.getId().startsWith(CONTACT_PREFIX) && !customChannelIds.contains(existingChannel.getId())) {
Log.i(TAG, "Consistency: Deleting channel '"+ existingChannel.getId() + "' because the DB has no record of it.");
notificationManager.deleteNotificationChannel(existingChannel.getId());
} else if (existingChannel.getId().startsWith(MESSAGES_PREFIX) &&
Build.VERSION.SDK_INT >= CONVERSATION_SUPPORT_VERSION &&
existingChannel.getConversationId() != null)
{
if (customChannelIds.contains(existingChannel.getId())) {
continue;
}
RecipientId id = ConversationUtil.getRecipientId(existingChannel.getConversationId());
if (id != null) {
Log.i(TAG, "Consistency: Conversation channel created outside of app, update " + id + " to use '" + existingChannel.getId() + "'");
db.setNotificationChannel(id, existingChannel.getId());
} else {
Log.i(TAG, "Consistency: Conversation channel created outside of app with no matching recipient, deleting channel '" + existingChannel.getId() + "'");
notificationManager.deleteNotificationChannel(existingChannel.getId());
}
} else if (existingChannel.getId().startsWith(MESSAGES_PREFIX) && !existingChannel.getId().equals(getMessagesChannel(context))) {
Log.i(TAG, "Consistency: Deleting channel '"+ existingChannel.getId() + "' because it's out of date.");
Log.i(TAG, "Consistency: Deleting channel '" + existingChannel.getId() + "' because it's out of date.");
notificationManager.deleteNotificationChannel(existingChannel.getId());
}
}
@@ -617,6 +670,10 @@ public class NotificationChannels {
copy.setLightColor(original.getLightColor());
copy.enableLights(original.shouldShowLights());
if (Build.VERSION.SDK_INT >= CONVERSATION_SUPPORT_VERSION && original.getConversationId() != null) {
copy.setConversationId(original.getParentChannelId(), original.getConversationId());
}
return copy;
}