diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java index 8e631301df..1a8e487d25 100644 --- a/src/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationActivity.java @@ -92,6 +92,8 @@ import org.thoughtcrime.securesms.database.DraftDatabase; import org.thoughtcrime.securesms.database.DraftDatabase.Draft; import org.thoughtcrime.securesms.database.DraftDatabase.Drafts; import org.thoughtcrime.securesms.database.GroupDatabase; +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.MmsSmsColumns.Types; import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences; @@ -110,6 +112,7 @@ import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage; import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.SlideDeck; +import org.thoughtcrime.securesms.notifications.MarkReadReceiver; import org.thoughtcrime.securesms.notifications.MessageNotifier; import org.thoughtcrime.securesms.providers.PersistentBlobProvider; import org.thoughtcrime.securesms.recipients.Recipient; @@ -1305,14 +1308,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity new AsyncTask() { @Override protected Void doInBackground(Long... params) { - Context context = ConversationActivity.this; - List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(params[0]); + Context context = ConversationActivity.this; + List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(params[0]); MessageNotifier.updateNotification(context, masterSecret); - - if (!messageIds.isEmpty()) { - ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceReadUpdateJob(context, messageIds)); - } + MarkReadReceiver.process(context, messageIds); return null; } diff --git a/src/org/thoughtcrime/securesms/ConversationListFragment.java b/src/org/thoughtcrime/securesms/ConversationListFragment.java index b054569c37..d39bb88a2f 100644 --- a/src/org/thoughtcrime/securesms/ConversationListFragment.java +++ b/src/org/thoughtcrime/securesms/ConversationListFragment.java @@ -64,9 +64,11 @@ import org.thoughtcrime.securesms.components.reminder.SystemSmsImportReminder; 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.loaders.ConversationListLoader; import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob; +import org.thoughtcrime.securesms.notifications.MarkReadReceiver; import org.thoughtcrime.securesms.notifications.MessageNotifier; import org.thoughtcrime.securesms.recipients.Recipients; import org.thoughtcrime.securesms.util.Util; @@ -472,14 +474,9 @@ public class ConversationListFragment extends Fragment DatabaseFactory.getThreadDatabase(getActivity()).archiveConversation(threadId); if (!read) { - List messageIds = DatabaseFactory.getThreadDatabase(getActivity()).setRead(threadId); + List messageIds = DatabaseFactory.getThreadDatabase(getActivity()).setRead(threadId); MessageNotifier.updateNotification(getActivity(), masterSecret); - - if (!messageIds.isEmpty()) { - ApplicationContext.getInstance(getActivity()) - .getJobManager() - .add(new MultiDeviceReadUpdateJob(getActivity(), messageIds)); - } + MarkReadReceiver.process(getActivity(), messageIds); } } diff --git a/src/org/thoughtcrime/securesms/database/MessagingDatabase.java b/src/org/thoughtcrime/securesms/database/MessagingDatabase.java index 3e05c2ddc7..114eff3c69 100644 --- a/src/org/thoughtcrime/securesms/database/MessagingDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MessagingDatabase.java @@ -172,7 +172,7 @@ public abstract class MessagingDatabase extends Database implements MmsSmsColumn private final long timetamp; public SyncMessageId(String address, long timetamp) { - this.address = address; + this.address = address; this.timetamp = timetamp; } @@ -184,4 +184,55 @@ public abstract class MessagingDatabase extends Database implements MmsSmsColumn return timetamp; } } + + public static class ExpirationInfo { + + private final long id; + private final long expiresIn; + private final long expireStarted; + private final boolean mms; + + public ExpirationInfo(long id, long expiresIn, long expireStarted, boolean mms) { + this.id = id; + this.expiresIn = expiresIn; + this.expireStarted = expireStarted; + this.mms = mms; + } + + public long getId() { + return id; + } + + public long getExpiresIn() { + return expiresIn; + } + + public long getExpireStarted() { + return expireStarted; + } + + public boolean isMms() { + return mms; + } + } + + public static class MarkedMessageInfo { + + private final SyncMessageId syncMessageId; + private final ExpirationInfo expirationInfo; + + public MarkedMessageInfo(SyncMessageId syncMessageId, ExpirationInfo expirationInfo) { + this.syncMessageId = syncMessageId; + this.expirationInfo = expirationInfo; + } + + public SyncMessageId getSyncMessageId() { + return syncMessageId; + } + + public ExpirationInfo getExpirationInfo() { + return expirationInfo; + } + } + } diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java index c2abe5a88d..0bcd958759 100644 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -455,21 +455,24 @@ public class MmsDatabase extends MessagingDatabase { notifyConversationListeners(threadId); } - public List setMessagesRead(long threadId) { - SQLiteDatabase database = databaseHelper.getWritableDatabase(); - String where = THREAD_ID + " = ? AND " + READ + " = 0"; - String[] selection = new String[]{String.valueOf(threadId)}; - List result = new LinkedList<>(); - Cursor cursor = null; + public List setMessagesRead(long threadId) { + SQLiteDatabase database = databaseHelper.getWritableDatabase(); + String where = THREAD_ID + " = ? AND " + READ + " = 0"; + String[] selection = new String[]{String.valueOf(threadId)}; + List result = new LinkedList<>(); + Cursor cursor = null; database.beginTransaction(); try { - cursor = database.query(TABLE_NAME, new String[] {ADDRESS, DATE_SENT, MESSAGE_BOX}, where, selection, null, null, null); + cursor = database.query(TABLE_NAME, new String[] {ID, ADDRESS, DATE_SENT, MESSAGE_BOX, EXPIRES_IN, EXPIRE_STARTED}, where, selection, null, null, null); while(cursor != null && cursor.moveToNext()) { - if (Types.isSecureType(cursor.getLong(2))) { - result.add(new SyncMessageId(cursor.getString(0), cursor.getLong(1))); + if (Types.isSecureType(cursor.getLong(3))) { + SyncMessageId syncMessageId = new SyncMessageId(cursor.getString(1), cursor.getLong(2)); + ExpirationInfo expirationInfo = new ExpirationInfo(cursor.getLong(0), cursor.getLong(4), cursor.getLong(5), true); + + result.add(new MarkedMessageInfo(syncMessageId, expirationInfo)); } } diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java index d9483a54bd..4188db1562 100644 --- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -318,20 +318,23 @@ public class SmsDatabase extends MessagingDatabase { } } - public List setMessagesRead(long threadId) { - SQLiteDatabase database = databaseHelper.getWritableDatabase(); - String where = THREAD_ID + " = ? AND " + READ + " = 0"; - String[] selection = new String[]{String.valueOf(threadId)}; - List results = new LinkedList<>(); - Cursor cursor = null; + public List setMessagesRead(long threadId) { + SQLiteDatabase database = databaseHelper.getWritableDatabase(); + String where = THREAD_ID + " = ? AND " + READ + " = 0"; + String[] selection = new String[]{String.valueOf(threadId)}; + List results = new LinkedList<>(); + Cursor cursor = null; database.beginTransaction(); try { - cursor = database.query(TABLE_NAME, new String[] {ADDRESS, DATE_SENT, TYPE}, where, selection, null, null, null); + cursor = database.query(TABLE_NAME, new String[] {ID, ADDRESS, DATE_SENT, TYPE, EXPIRES_IN, EXPIRE_STARTED}, where, selection, null, null, null); while (cursor != null && cursor.moveToNext()) { - if (Types.isSecureType(cursor.getLong(2))) { - results.add(new SyncMessageId(cursor.getString(0), cursor.getLong(1))); + if (Types.isSecureType(cursor.getLong(3))) { + SyncMessageId syncMessageId = new SyncMessageId(cursor.getString(1), cursor.getLong(2)); + ExpirationInfo expirationInfo = new ExpirationInfo(cursor.getLong(0), cursor.getLong(4), cursor.getLong(5), false); + + results.add(new MarkedMessageInfo(syncMessageId, expirationInfo)); } } diff --git a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java index aef5583537..e0021711b2 100644 --- a/src/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/src/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -29,6 +29,7 @@ import android.util.Log; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.crypto.MasterCipher; +import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.model.DisplayRecord; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; @@ -261,19 +262,19 @@ public class ThreadDatabase extends Database { notifyConversationListListeners(); } - public List setRead(long threadId) { + public List setRead(long threadId) { ContentValues contentValues = new ContentValues(1); contentValues.put(READ, 1); SQLiteDatabase db = databaseHelper.getWritableDatabase(); db.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {threadId+""}); - final List smsRecords = DatabaseFactory.getSmsDatabase(context).setMessagesRead(threadId); - final List mmsRecords = DatabaseFactory.getMmsDatabase(context).setMessagesRead(threadId); + final List smsRecords = DatabaseFactory.getSmsDatabase(context).setMessagesRead(threadId); + final List mmsRecords = DatabaseFactory.getMmsDatabase(context).setMessagesRead(threadId); notifyConversationListListeners(); - return new LinkedList() {{ + return new LinkedList() {{ addAll(smsRecords); addAll(mmsRecords); }}; diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java index efa06278cb..7ac4956584 100644 --- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java @@ -1,12 +1,14 @@ package org.thoughtcrime.securesms.jobs; import android.content.Context; +import android.util.Log; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.dependencies.TextSecureCommunicationModule; import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement; +import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.jobqueue.JobParameters; import org.whispersystems.jobqueue.requirements.NetworkRequirement; import org.whispersystems.signalservice.api.SignalServiceMessageSender; @@ -49,6 +51,11 @@ public class MultiDeviceReadUpdateJob extends MasterSecretJob implements Injecta @Override public void onRun(MasterSecret masterSecret) throws IOException, UntrustedIdentityException { + if (!TextSecurePreferences.isMultiDevice(context)) { + Log.w(TAG, "Not multi device..."); + return; + } + List readMessages = new LinkedList<>(); for (SerializableSyncMessageId messageId : messageIds) { diff --git a/src/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java b/src/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java index 58869eacfa..7d99c78781 100644 --- a/src/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java +++ b/src/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java @@ -4,14 +4,20 @@ 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.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; import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob; +import org.thoughtcrime.securesms.service.ExpiringMessageManager; import java.util.LinkedList; import java.util.List; @@ -23,8 +29,7 @@ public class MarkReadReceiver extends MasterSecretBroadcastReceiver { public static final String THREAD_IDS_EXTRA = "thread_ids"; @Override - protected void onReceive(final Context context, Intent intent, - @Nullable final MasterSecret masterSecret) + protected void onReceive(final Context context, Intent intent, @Nullable final MasterSecret masterSecret) { if (!CLEAR_ACTION.equals(intent.getAction())) return; @@ -40,25 +45,47 @@ public class MarkReadReceiver extends MasterSecretBroadcastReceiver { new AsyncTask() { @Override protected Void doInBackground(Void... params) { - List messageIdsCollection = new LinkedList<>(); + List messageIdsCollection = new LinkedList<>(); for (long threadId : threadIds) { Log.w(TAG, "Marking as read: " + threadId); - List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(threadId); + List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(threadId); messageIdsCollection.addAll(messageIds); } - MessageNotifier.updateNotification(context, masterSecret); + process(context, messageIdsCollection); - if (!messageIdsCollection.isEmpty()) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MultiDeviceReadUpdateJob(context, messageIdsCollection)); - } + MessageNotifier.updateNotification(context, masterSecret); return null; } }.execute(); } } + + public static void process(@NonNull Context context, @NonNull List markedReadMessages) { + if (markedReadMessages.isEmpty()) return; + + List syncMessageIds = new LinkedList<>(); + + for (MarkedMessageInfo messageInfo : markedReadMessages) { + scheduleDeletion(context, messageInfo.getExpirationInfo()); + syncMessageIds.add(messageInfo.getSyncMessageId()); + } + + ApplicationContext.getInstance(context) + .getJobManager() + .add(new MultiDeviceReadUpdateJob(context, syncMessageIds)); + } + + private static void scheduleDeletion(Context context, ExpirationInfo expirationInfo) { + if (expirationInfo.getExpiresIn() > 0 && expirationInfo.getExpireStarted() <= 0) { + ExpiringMessageManager expirationManager = ApplicationContext.getInstance(context).getExpiringMessageManager(); + + if (expirationInfo.isMms()) DatabaseFactory.getMmsDatabase(context).markExpireStarted(expirationInfo.getId()); + else DatabaseFactory.getSmsDatabase(context).markExpireStarted(expirationInfo.getId()); + + expirationManager.scheduleDeletion(expirationInfo.getId(), expirationInfo.isMms(), expirationInfo.getExpiresIn()); + } + } } diff --git a/src/org/thoughtcrime/securesms/notifications/MessageNotifier.java b/src/org/thoughtcrime/securesms/notifications/MessageNotifier.java index 62b0b2673c..f624c7693f 100644 --- a/src/org/thoughtcrime/securesms/notifications/MessageNotifier.java +++ b/src/org/thoughtcrime/securesms/notifications/MessageNotifier.java @@ -43,6 +43,8 @@ import org.thoughtcrime.securesms.ConversationActivity; import org.thoughtcrime.securesms.R; 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.MmsSmsDatabase; import org.thoughtcrime.securesms.database.PushDatabase; @@ -140,13 +142,8 @@ public class MessageNotifier { .getRecipientsForThreadId(threadId); if (isVisible) { - List messageIds = threads.setRead(threadId); - - if (!messageIds.isEmpty()) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MultiDeviceReadUpdateJob(context, messageIds)); - } + List messageIds = threads.setRead(threadId); + MarkReadReceiver.process(context, messageIds); } if (!TextSecurePreferences.isNotificationsEnabled(context) || diff --git a/src/org/thoughtcrime/securesms/notifications/WearReplyReceiver.java b/src/org/thoughtcrime/securesms/notifications/WearReplyReceiver.java index d28cfb5221..fd94a2188a 100644 --- a/src/org/thoughtcrime/securesms/notifications/WearReplyReceiver.java +++ b/src/org/thoughtcrime/securesms/notifications/WearReplyReceiver.java @@ -29,6 +29,7 @@ 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; @@ -83,14 +84,9 @@ public class WearReplyReceiver extends MasterSecretBroadcastReceiver { threadId = MessageSender.send(context, masterSecret, reply, -1, false); } - List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(threadId); + List messageIds = DatabaseFactory.getThreadDatabase(context).setRead(threadId); MessageNotifier.updateNotification(context, masterSecret); - - if (!messageIds.isEmpty()) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MultiDeviceReadUpdateJob(context, messageIds)); - } + MarkReadReceiver.process(context, messageIds); return null; }