mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-25 02:30:15 +00:00
Support for bundled notifications (Android wear and Android N)
// FREEBIE
This commit is contained in:
@@ -17,18 +17,15 @@
|
||||
|
||||
package org.thoughtcrime.securesms.notifications;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob;
|
||||
import org.whispersystems.libsignal.logging.Log;
|
||||
|
||||
import java.util.LinkedList;
|
||||
@@ -39,9 +36,10 @@ import java.util.List;
|
||||
*/
|
||||
public class AndroidAutoHeardReceiver extends MasterSecretBroadcastReceiver {
|
||||
|
||||
public static final String TAG = AndroidAutoHeardReceiver.class.getSimpleName();
|
||||
public static final String HEARD_ACTION = "org.thoughtcrime.securesms.notifications.ANDROID_AUTO_HEARD";
|
||||
public static final String THREAD_IDS_EXTRA = "car_heard_thread_ids";
|
||||
public static final String TAG = AndroidAutoHeardReceiver.class.getSimpleName();
|
||||
public static final String HEARD_ACTION = "org.thoughtcrime.securesms.notifications.ANDROID_AUTO_HEARD";
|
||||
public static final String THREAD_IDS_EXTRA = "car_heard_thread_ids";
|
||||
public static final String NOTIFICATION_ID_EXTRA = "car_notification_id";
|
||||
|
||||
@Override
|
||||
protected void onReceive(final Context context, Intent intent,
|
||||
@@ -53,8 +51,8 @@ public class AndroidAutoHeardReceiver extends MasterSecretBroadcastReceiver {
|
||||
final long[] threadIds = intent.getLongArrayExtra(THREAD_IDS_EXTRA);
|
||||
|
||||
if (threadIds != null) {
|
||||
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE))
|
||||
.cancel(MessageNotifier.NOTIFICATION_ID);
|
||||
int notificationId = intent.getIntExtra(NOTIFICATION_ID_EXTRA, -1);
|
||||
NotificationManagerCompat.from(context).cancel(notificationId);
|
||||
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
package org.thoughtcrime.securesms.notifications;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.ExpirationInfo;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
||||
@@ -24,9 +22,10 @@ import java.util.List;
|
||||
|
||||
public class MarkReadReceiver extends MasterSecretBroadcastReceiver {
|
||||
|
||||
private static final String TAG = MarkReadReceiver.class.getSimpleName();
|
||||
public static final String CLEAR_ACTION = "org.thoughtcrime.securesms.notifications.CLEAR";
|
||||
public static final String THREAD_IDS_EXTRA = "thread_ids";
|
||||
private static final String TAG = MarkReadReceiver.class.getSimpleName();
|
||||
public static final String CLEAR_ACTION = "org.thoughtcrime.securesms.notifications.CLEAR";
|
||||
public static final String THREAD_IDS_EXTRA = "thread_ids";
|
||||
public static final String NOTIFICATION_ID_EXTRA = "notification_id";
|
||||
|
||||
@Override
|
||||
protected void onReceive(final Context context, Intent intent, @Nullable final MasterSecret masterSecret)
|
||||
@@ -37,10 +36,7 @@ public class MarkReadReceiver extends MasterSecretBroadcastReceiver {
|
||||
final long[] threadIds = intent.getLongArrayExtra(THREAD_IDS_EXTRA);
|
||||
|
||||
if (threadIds != null) {
|
||||
Log.w("TAG", "threadIds length: " + threadIds.length);
|
||||
|
||||
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE))
|
||||
.cancel(MessageNotifier.NOTIFICATION_ID);
|
||||
NotificationManagerCompat.from(context).cancel(intent.getIntExtra(NOTIFICATION_ID_EXTRA, -1));
|
||||
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
|
||||
@@ -30,14 +30,17 @@ import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.redphone.ui.NotificationBarManager;
|
||||
import org.thoughtcrime.redphone.util.Util;
|
||||
import org.thoughtcrime.securesms.ConversationActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
@@ -84,7 +87,9 @@ public class MessageNotifier {
|
||||
private static final String TAG = MessageNotifier.class.getSimpleName();
|
||||
|
||||
public static final String EXTRA_VOICE_REPLY = "extra_voice_reply";
|
||||
public static final int NOTIFICATION_ID = 1338;
|
||||
|
||||
private static final int SUMMARY_NOTIFICATION_ID = 1338;
|
||||
private static final String NOTIFICATION_GROUP = "messages";
|
||||
private static final long MIN_AUDIBLE_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(2);
|
||||
private static final long DESKTOP_ACTIVITY_PERIOD = TimeUnit.MINUTES.toMillis(1);
|
||||
|
||||
@@ -101,10 +106,6 @@ public class MessageNotifier {
|
||||
lastDesktopActivityTimestamp = timestamp;
|
||||
}
|
||||
|
||||
public static void cancelDelayedNotifications() {
|
||||
executor.cancel();
|
||||
}
|
||||
|
||||
public static void notifyMessageDeliveryFailed(Context context, Recipients recipients, long threadId) {
|
||||
if (visibleThread == threadId) {
|
||||
sendInThreadNotification(context, recipients);
|
||||
@@ -120,6 +121,49 @@ public class MessageNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
public static void cancelDelayedNotifications() {
|
||||
executor.cancel();
|
||||
}
|
||||
|
||||
private static void cancelActiveNotifications(@NonNull Context context) {
|
||||
NotificationManager notifications = ServiceUtil.getNotificationManager(context);
|
||||
notifications.cancel(SUMMARY_NOTIFICATION_ID);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
StatusBarNotification[] activeNotifications = notifications.getActiveNotifications();
|
||||
|
||||
for (StatusBarNotification activeNotification : activeNotifications) {
|
||||
if (activeNotification.getId() != NotificationBarManager.RED_PHONE_NOTIFICATION) {
|
||||
notifications.cancel(activeNotification.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void cancelOrphanedNotifications(@NonNull Context context, NotificationState notificationState) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
NotificationManager notifications = ServiceUtil.getNotificationManager(context);
|
||||
StatusBarNotification[] activeNotifications = notifications.getActiveNotifications();
|
||||
|
||||
for (StatusBarNotification notification : activeNotifications) {
|
||||
boolean validNotification = false;
|
||||
|
||||
if (notification.getId() != SUMMARY_NOTIFICATION_ID && notification.getId() != NotificationBarManager.RED_PHONE_NOTIFICATION) {
|
||||
for (NotificationItem item : notificationState.getNotifications()) {
|
||||
if (notification.getId() == (SUMMARY_NOTIFICATION_ID + item.getThreadId())) {
|
||||
validNotification = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!validNotification) {
|
||||
notifications.cancel(notification.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateNotification(@NonNull Context context, @Nullable MasterSecret masterSecret) {
|
||||
if (!TextSecurePreferences.isNotificationsEnabled(context)) {
|
||||
return;
|
||||
@@ -194,8 +238,7 @@ public class MessageNotifier {
|
||||
if ((telcoCursor == null || telcoCursor.isAfterLast()) &&
|
||||
(pushCursor == null || pushCursor.isAfterLast()))
|
||||
{
|
||||
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE))
|
||||
.cancel(NOTIFICATION_ID);
|
||||
cancelActiveNotifications(context);
|
||||
updateBadge(context, 0);
|
||||
clearReminder(context);
|
||||
return;
|
||||
@@ -214,11 +257,18 @@ public class MessageNotifier {
|
||||
}
|
||||
|
||||
if (notificationState.hasMultipleThreads()) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
for (long threadId : notificationState.getThreads()) {
|
||||
sendSingleThreadNotification(context, masterSecret, new NotificationState(notificationState.getNotificationsForThread(threadId)), false, true);
|
||||
}
|
||||
}
|
||||
|
||||
sendMultipleThreadNotification(context, notificationState, signal);
|
||||
} else {
|
||||
sendSingleThreadNotification(context, masterSecret, notificationState, signal);
|
||||
sendSingleThreadNotification(context, masterSecret, notificationState, signal, false);
|
||||
}
|
||||
|
||||
cancelOrphanedNotifications(context, notificationState);
|
||||
updateBadge(context, notificationState.getMessageCount());
|
||||
|
||||
if (signal) {
|
||||
@@ -233,33 +283,35 @@ public class MessageNotifier {
|
||||
private static void sendSingleThreadNotification(@NonNull Context context,
|
||||
@Nullable MasterSecret masterSecret,
|
||||
@NonNull NotificationState notificationState,
|
||||
boolean signal)
|
||||
boolean signal, boolean bundled)
|
||||
{
|
||||
if (notificationState.getNotifications().isEmpty()) {
|
||||
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE))
|
||||
.cancel(NOTIFICATION_ID);
|
||||
if (!bundled) cancelActiveNotifications(context);
|
||||
return;
|
||||
}
|
||||
|
||||
SingleRecipientNotificationBuilder builder = new SingleRecipientNotificationBuilder(context, masterSecret, TextSecurePreferences.getNotificationPrivacy(context));
|
||||
List<NotificationItem> notifications = notificationState.getNotifications();
|
||||
Recipients recipients = notifications.get(0).getRecipients();
|
||||
SingleRecipientNotificationBuilder builder = new SingleRecipientNotificationBuilder(context, masterSecret, TextSecurePreferences.getNotificationPrivacy(context));
|
||||
List<NotificationItem> notifications = notificationState.getNotifications();
|
||||
Recipients recipients = notifications.get(0).getRecipients();
|
||||
int notificationId = (int) (SUMMARY_NOTIFICATION_ID + (bundled ? notifications.get(0).getThreadId() : 0));
|
||||
|
||||
|
||||
builder.setThread(notifications.get(0).getRecipients());
|
||||
builder.setMessageCount(notificationState.getMessageCount());
|
||||
builder.setPrimaryMessageBody(recipients, notifications.get(0).getIndividualRecipient(),
|
||||
notifications.get(0).getText(), notifications.get(0).getSlideDeck());
|
||||
builder.setContentIntent(notifications.get(0).getPendingIntent(context));
|
||||
builder.setGroup(NOTIFICATION_GROUP);
|
||||
|
||||
long timestamp = notifications.get(0).getTimestamp();
|
||||
if (timestamp != 0) builder.setWhen(timestamp);
|
||||
|
||||
builder.addActions(masterSecret,
|
||||
notificationState.getMarkAsReadIntent(context),
|
||||
notificationState.getMarkAsReadIntent(context, notificationId),
|
||||
notificationState.getQuickReplyIntent(context, notifications.get(0).getRecipients()),
|
||||
notificationState.getWearableReplyIntent(context, notifications.get(0).getRecipients()));
|
||||
builder.addAndroidAutoAction(notificationState.getAndroidAutoReplyIntent(context, notifications.get(0).getRecipients()),
|
||||
notificationState.getAndroidAutoHeardIntent(context, notifications.get(0).getRecipients()), notifications.get(0).getTimestamp());
|
||||
notificationState.getAndroidAutoHeardIntent(context, notificationId), notifications.get(0).getTimestamp());
|
||||
|
||||
ListIterator<NotificationItem> iterator = notifications.listIterator(notifications.size());
|
||||
|
||||
@@ -274,8 +326,11 @@ public class MessageNotifier {
|
||||
notifications.get(0).getText());
|
||||
}
|
||||
|
||||
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE))
|
||||
.notify(NOTIFICATION_ID, builder.build());
|
||||
if (!bundled) {
|
||||
builder.setGroupSummary(true);
|
||||
}
|
||||
|
||||
NotificationManagerCompat.from(context).notify(notificationId, builder.build());
|
||||
}
|
||||
|
||||
private static void sendMultipleThreadNotification(@NonNull Context context,
|
||||
@@ -287,11 +342,12 @@ public class MessageNotifier {
|
||||
|
||||
builder.setMessageCount(notificationState.getMessageCount(), notificationState.getThreadCount());
|
||||
builder.setMostRecentSender(notifications.get(0).getIndividualRecipient());
|
||||
builder.setGroup(NOTIFICATION_GROUP);
|
||||
|
||||
long timestamp = notifications.get(0).getTimestamp();
|
||||
if (timestamp != 0) builder.setWhen(timestamp);
|
||||
|
||||
builder.addActions(notificationState.getMarkAsReadIntent(context));
|
||||
builder.addActions(notificationState.getMarkAsReadIntent(context, SUMMARY_NOTIFICATION_ID));
|
||||
|
||||
ListIterator<NotificationItem> iterator = notifications.listIterator(notifications.size());
|
||||
|
||||
@@ -306,8 +362,7 @@ public class MessageNotifier {
|
||||
notifications.get(0).getText());
|
||||
}
|
||||
|
||||
((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE))
|
||||
.notify(NOTIFICATION_ID, builder.build());
|
||||
NotificationManagerCompat.from(context).notify(SUMMARY_NOTIFICATION_ID, builder.build());
|
||||
}
|
||||
|
||||
private static void sendInThreadNotification(Context context, Recipients recipients) {
|
||||
|
||||
@@ -31,6 +31,7 @@ public class MultipleRecipientNotificationBuilder extends AbstractNotificationBu
|
||||
setCategory(NotificationCompat.CATEGORY_MESSAGE);
|
||||
setPriority(NotificationCompat.PRIORITY_HIGH);
|
||||
setDeleteIntent(PendingIntent.getBroadcast(context, 0, new Intent(MessageNotifier.DeleteReceiver.DELETE_REMINDER_ACTION), 0));
|
||||
setGroupSummary(true);
|
||||
}
|
||||
|
||||
public void setMessageCount(int messageCount, int threadCount) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -13,6 +14,7 @@ import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.VibrateSt
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -20,12 +22,25 @@ import java.util.Set;
|
||||
public class NotificationState {
|
||||
|
||||
private final LinkedList<NotificationItem> notifications = new LinkedList<>();
|
||||
private final Set<Long> threads = new HashSet<>();
|
||||
private final LinkedHashSet<Long> threads = new LinkedHashSet<>();
|
||||
|
||||
private int notificationCount = 0;
|
||||
|
||||
public NotificationState() {}
|
||||
|
||||
public NotificationState(@NonNull List<NotificationItem> items) {
|
||||
for (NotificationItem item : items) {
|
||||
addNotification(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void addNotification(NotificationItem item) {
|
||||
notifications.addFirst(item);
|
||||
|
||||
if (threads.contains(item.getThreadId())) {
|
||||
threads.remove(item.getThreadId());
|
||||
}
|
||||
|
||||
threads.add(item.getThreadId());
|
||||
notificationCount++;
|
||||
}
|
||||
@@ -58,6 +73,10 @@ public class NotificationState {
|
||||
return threads.size() > 1;
|
||||
}
|
||||
|
||||
public LinkedHashSet<Long> getThreads() {
|
||||
return threads;
|
||||
}
|
||||
|
||||
public int getThreadCount() {
|
||||
return threads.size();
|
||||
}
|
||||
@@ -70,7 +89,17 @@ public class NotificationState {
|
||||
return notifications;
|
||||
}
|
||||
|
||||
public PendingIntent getMarkAsReadIntent(Context context) {
|
||||
public List<NotificationItem> getNotificationsForThread(long threadId) {
|
||||
LinkedList<NotificationItem> list = new LinkedList<>();
|
||||
|
||||
for (NotificationItem item : notifications) {
|
||||
if (item.getThreadId() == threadId) list.addFirst(item);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public PendingIntent getMarkAsReadIntent(Context context, int notificationId) {
|
||||
long[] threadArray = new long[threads.size()];
|
||||
int index = 0;
|
||||
|
||||
@@ -80,14 +109,10 @@ public class NotificationState {
|
||||
}
|
||||
|
||||
Intent intent = new Intent(MarkReadReceiver.CLEAR_ACTION);
|
||||
intent.setClass(context, MarkReadReceiver.class);
|
||||
intent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
|
||||
intent.putExtra(MarkReadReceiver.THREAD_IDS_EXTRA, threadArray);
|
||||
intent.setPackage(context.getPackageName());
|
||||
|
||||
// XXX : This is an Android bug. If we don't pull off the extra
|
||||
// once before handing off the PendingIntent, the array will be
|
||||
// truncated to one element when the PendingIntent fires. Thanks guys!
|
||||
Log.w("NotificationState", "Pending array off intent length: " +
|
||||
intent.getLongArrayExtra("thread_ids").length);
|
||||
intent.putExtra(MarkReadReceiver.NOTIFICATION_ID_EXTRA, notificationId);
|
||||
|
||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
@@ -96,6 +121,8 @@ public class NotificationState {
|
||||
if (threads.size() != 1) throw new AssertionError("We only support replies to single thread notifications!");
|
||||
|
||||
Intent intent = new Intent(WearReplyReceiver.REPLY_ACTION);
|
||||
intent.setClass(context, WearReplyReceiver.class);
|
||||
intent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
|
||||
intent.putExtra(WearReplyReceiver.RECIPIENT_IDS_EXTRA, recipients.getIds());
|
||||
intent.setPackage(context.getPackageName());
|
||||
|
||||
@@ -106,6 +133,8 @@ public class NotificationState {
|
||||
if (threads.size() != 1) throw new AssertionError("We only support replies to single thread notifications!");
|
||||
|
||||
Intent intent = new Intent(AndroidAutoReplyReceiver.REPLY_ACTION);
|
||||
intent.setClass(context, AndroidAutoReplyReceiver.class);
|
||||
intent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
|
||||
intent.putExtra(AndroidAutoReplyReceiver.RECIPIENT_IDS_EXTRA, recipients.getIds());
|
||||
intent.putExtra(AndroidAutoReplyReceiver.THREAD_ID_EXTRA, (long)threads.toArray()[0]);
|
||||
intent.setPackage(context.getPackageName());
|
||||
@@ -113,7 +142,7 @@ public class NotificationState {
|
||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
|
||||
public PendingIntent getAndroidAutoHeardIntent(Context context, Recipients recipients) {
|
||||
public PendingIntent getAndroidAutoHeardIntent(Context context, int notificationId) {
|
||||
long[] threadArray = new long[threads.size()];
|
||||
int index = 0;
|
||||
for (long thread : threads) {
|
||||
@@ -122,17 +151,17 @@ public class NotificationState {
|
||||
}
|
||||
|
||||
Intent intent = new Intent(AndroidAutoHeardReceiver.HEARD_ACTION);
|
||||
intent.setClass(context, AndroidAutoHeardReceiver.class);
|
||||
intent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
|
||||
intent.putExtra(AndroidAutoHeardReceiver.THREAD_IDS_EXTRA, threadArray);
|
||||
intent.putExtra(AndroidAutoHeardReceiver.NOTIFICATION_ID_EXTRA, notificationId);
|
||||
intent.setPackage(context.getPackageName());
|
||||
|
||||
Log.w("NotificationState", "getAndroidAutoHeardIntent - Pending array off intent length: " +
|
||||
intent.getLongArrayExtra(AndroidAutoHeardReceiver.THREAD_IDS_EXTRA).length);
|
||||
|
||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
|
||||
public PendingIntent getQuickReplyIntent(Context context, Recipients recipients) {
|
||||
if (threads.size() != 1) throw new AssertionError("We only support replies to single thread notifications!");
|
||||
if (threads.size() != 1) throw new AssertionError("We only support replies to single thread notifications! " + threads.size());
|
||||
|
||||
Intent intent = new Intent(context, ConversationPopupActivity.class);
|
||||
intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.getIds());
|
||||
|
||||
@@ -24,15 +24,11 @@ import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.RemoteInput;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
|
||||
Reference in New Issue
Block a user