From 2f46c6ca1fba65596c08bfcab24a2e47df163ef5 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Wed, 8 Mar 2017 17:38:55 -0800 Subject: [PATCH] Don't redisplay notifications after they have been dismissed Fixes #5751 Fixes #6218 // FREEBIE --- AndroidManifest.xml | 4 +- build.gradle | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../redphone/RedPhoneService.java | 2 +- .../securesms/database/DatabaseFactory.java | 14 +++- .../securesms/database/MmsDatabase.java | 15 +++- .../securesms/database/MmsSmsColumns.java | 1 + .../securesms/database/MmsSmsDatabase.java | 12 ++- .../securesms/database/SmsDatabase.java | 16 +++- .../securesms/jobs/PushDecryptJob.java | 1 - .../DeleteNotificationReceiver.java | 41 ++++++++++ .../notifications/MessageNotifier.java | 77 +++---------------- .../MultipleRecipientNotificationBuilder.java | 1 - .../notifications/NotificationItem.java | 13 +++- .../notifications/NotificationState.java | 19 +++++ .../SingleRecipientNotificationBuilder.java | 1 - .../securesms/service/WebRtcCallService.java | 2 +- .../securesms/util/DirectoryHelper.java | 4 +- 18 files changed, 141 insertions(+), 88 deletions(-) create mode 100644 src/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 40317f0e41..ec2cab5daf 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -544,9 +544,9 @@ - + - + diff --git a/build.gradle b/build.gradle index cd006fe8c7..1ff7cb8459 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:2.2.3' + classpath 'com.android.tools.build:gradle:2.3.0' classpath files('libs/gradle-witness.jar') } } @@ -189,7 +189,7 @@ dependencyVerification { android { compileSdkVersion 25 - buildToolsVersion '23.0.3' + buildToolsVersion '25.0.0' useLibrary 'org.apache.http.legacy' dexOptions { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f6f05331de..ee02693a8c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip diff --git a/src/org/thoughtcrime/redphone/RedPhoneService.java b/src/org/thoughtcrime/redphone/RedPhoneService.java index 578c09adbe..8d0675da5f 100644 --- a/src/org/thoughtcrime/redphone/RedPhoneService.java +++ b/src/org/thoughtcrime/redphone/RedPhoneService.java @@ -257,7 +257,7 @@ public class RedPhoneService extends Service implements CallStateListener { private void handleMissedCall(String remoteNumber, boolean signal) { Pair messageAndThreadId = DatabaseFactory.getSmsDatabase(this).insertMissedCall(remoteNumber); MessageNotifier.updateNotification(this, KeyCachingService.getMasterSecret(this), - false, messageAndThreadId.second, signal); + messageAndThreadId.second, signal); } private void handleAnswerCall(Intent intent) { diff --git a/src/org/thoughtcrime/securesms/database/DatabaseFactory.java b/src/org/thoughtcrime/securesms/database/DatabaseFactory.java index df6a18e3be..dc8b90fd66 100644 --- a/src/org/thoughtcrime/securesms/database/DatabaseFactory.java +++ b/src/org/thoughtcrime/securesms/database/DatabaseFactory.java @@ -75,7 +75,8 @@ public class DatabaseFactory { private static final int INTRODUCED_EXPIRE_MESSAGES_VERSION = 28; private static final int INTRODUCED_LAST_SEEN = 29; private static final int INTRODUCED_DIGEST = 30; - private static final int DATABASE_VERSION = 30; + private static final int INTRODUCED_NOTIFIED = 31; + private static final int DATABASE_VERSION = 31; private static final String DATABASE_NAME = "messages.db"; private static final Object lock = new Object(); @@ -841,6 +842,17 @@ public class DatabaseFactory { db.execSQL("ALTER TABLE groups ADD COLUMN avatar_digest BLOB"); } + if (oldVersion < INTRODUCED_NOTIFIED) { + db.execSQL("ALTER TABLE sms ADD COLUMN notified INTEGER DEFAULT 0"); + db.execSQL("ALTER TABLE mms ADD COLUMN notified INTEGER DEFAULT 0"); + + db.execSQL("DROP INDEX sms_read_and_thread_id_index"); + db.execSQL("CREATE INDEX IF NOT EXISTS sms_read_and_notified_and_thread_id_index ON sms(read,notified,thread_id)"); + + db.execSQL("DROP INDEX mms_read_and_thread_id_index"); + db.execSQL("CREATE INDEX IF NOT EXISTS mms_read_and_notified_and_thread_id_index ON mms(read,notified,thread_id)"); + } + db.setTransactionSuccessful(); db.endTransaction(); } diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java index 78b3f83fae..64ebab704d 100644 --- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -113,12 +113,12 @@ public class MmsDatabase extends MessagingDatabase { RECEIPT_COUNT + " INTEGER DEFAULT 0, " + MISMATCHED_IDENTITIES + " TEXT DEFAULT NULL, " + NETWORK_FAILURE + " TEXT DEFAULT NULL," + "d_rpt" + " INTEGER, " + SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " + EXPIRES_IN + " INTEGER DEFAULT 0, " + - EXPIRE_STARTED + " INTEGER DEFAULT 0);"; + EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " INTEGER DEFAULT 0);"; public static final String[] CREATE_INDEXS = { "CREATE INDEX IF NOT EXISTS mms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");", "CREATE INDEX IF NOT EXISTS mms_read_index ON " + TABLE_NAME + " (" + READ + ");", - "CREATE INDEX IF NOT EXISTS mms_read_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + THREAD_ID + ");", + "CREATE INDEX IF NOT EXISTS mms_read_and_notified_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + NOTIFIED + "," + THREAD_ID + ");", "CREATE INDEX IF NOT EXISTS mms_message_box_index ON " + TABLE_NAME + " (" + MESSAGE_BOX + ");", "CREATE INDEX IF NOT EXISTS mms_date_sent_index ON " + TABLE_NAME + " (" + DATE_SENT + ");", "CREATE INDEX IF NOT EXISTS mms_thread_date_index ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + ");" @@ -133,7 +133,7 @@ public class MmsDatabase extends MessagingDatabase { MESSAGE_SIZE, STATUS, TRANSACTION_ID, BODY, PART_COUNT, ADDRESS, ADDRESS_DEVICE_ID, RECEIPT_COUNT, MISMATCHED_IDENTITIES, NETWORK_FAILURE, SUBSCRIPTION_ID, - EXPIRES_IN, EXPIRE_STARTED, + EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + " AS " + AttachmentDatabase.ATTACHMENT_ID_ALIAS, AttachmentDatabase.UNIQUE_ID, AttachmentDatabase.MMS_ID, @@ -458,6 +458,15 @@ public class MmsDatabase extends MessagingDatabase { notifyConversationListeners(threadId); } + public void markAsNotified(long id) { + SQLiteDatabase database = databaseHelper.getWritableDatabase(); + ContentValues contentValues = new ContentValues(); + + contentValues.put(NOTIFIED, 1); + + database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(id)}); + } + public List setMessagesRead(long threadId) { SQLiteDatabase database = databaseHelper.getWritableDatabase(); String where = THREAD_ID + " = ? AND " + READ + " = 0"; diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java b/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java index c0dfc2fc08..ed5ebf0c04 100644 --- a/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java +++ b/src/org/thoughtcrime/securesms/database/MmsSmsColumns.java @@ -17,6 +17,7 @@ public interface MmsSmsColumns { public static final String SUBSCRIPTION_ID = "subscription_id"; public static final String EXPIRES_IN = "expires_in"; public static final String EXPIRE_STARTED = "expire_started"; + public static final String NOTIFIED = "notified"; public static class Types { protected static final long TOTAL_MASK = 0xFFFFFFFF; diff --git a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index dacb40f171..ee1526cc47 100644 --- a/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -56,7 +56,9 @@ public class MmsSmsDatabase extends Database { MmsDatabase.NETWORK_FAILURE, MmsSmsColumns.SUBSCRIPTION_ID, MmsSmsColumns.EXPIRES_IN, - MmsSmsColumns.EXPIRE_STARTED, TRANSPORT, + MmsSmsColumns.EXPIRE_STARTED, + MmsSmsColumns.NOTIFIED, + TRANSPORT, AttachmentDatabase.ATTACHMENT_ID_ALIAS, AttachmentDatabase.UNIQUE_ID, AttachmentDatabase.MMS_ID, @@ -107,13 +109,13 @@ public class MmsSmsDatabase extends Database { public Cursor getUnread() { String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC"; - String selection = MmsSmsColumns.READ + " = 0"; + String selection = MmsSmsColumns.READ + " = 0 AND " + MmsSmsColumns.NOTIFIED + " = 0"; return queryTables(PROJECTION, selection, order, null); } public int getUnreadCount(long threadId) { - String selection = MmsSmsColumns.READ + " = 0 AND " + MmsSmsColumns.THREAD_ID + " = " + threadId; + String selection = MmsSmsColumns.READ + " = 0 AND " + MmsSmsColumns.NOTIFIED + " = 0 AND " + MmsSmsColumns.THREAD_ID + " = " + threadId; Cursor cursor = queryTables(PROJECTION, selection, null, null); try { @@ -150,6 +152,7 @@ public class MmsSmsDatabase extends Database { MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, MmsDatabase.STATUS, MmsSmsColumns.RECEIPT_COUNT, MmsSmsColumns.MISMATCHED_IDENTITIES, MmsSmsColumns.SUBSCRIPTION_ID, MmsSmsColumns.EXPIRES_IN, MmsSmsColumns.EXPIRE_STARTED, + MmsSmsColumns.NOTIFIED, MmsDatabase.NETWORK_FAILURE, TRANSPORT, AttachmentDatabase.UNIQUE_ID, AttachmentDatabase.MMS_ID, @@ -177,6 +180,7 @@ public class MmsSmsDatabase extends Database { MmsDatabase.MESSAGE_SIZE, MmsDatabase.EXPIRY, MmsDatabase.STATUS, MmsSmsColumns.RECEIPT_COUNT, MmsSmsColumns.MISMATCHED_IDENTITIES, MmsSmsColumns.SUBSCRIPTION_ID, MmsSmsColumns.EXPIRES_IN, MmsSmsColumns.EXPIRE_STARTED, + MmsSmsColumns.NOTIFIED, MmsDatabase.NETWORK_FAILURE, TRANSPORT, AttachmentDatabase.UNIQUE_ID, AttachmentDatabase.MMS_ID, @@ -227,6 +231,7 @@ public class MmsSmsDatabase extends Database { mmsColumnsPresent.add(MmsDatabase.TRANSACTION_ID); mmsColumnsPresent.add(MmsDatabase.MESSAGE_SIZE); mmsColumnsPresent.add(MmsDatabase.EXPIRY); + mmsColumnsPresent.add(MmsDatabase.NOTIFIED); mmsColumnsPresent.add(MmsDatabase.STATUS); mmsColumnsPresent.add(MmsDatabase.NETWORK_FAILURE); @@ -255,6 +260,7 @@ public class MmsSmsDatabase extends Database { smsColumnsPresent.add(MmsSmsColumns.SUBSCRIPTION_ID); smsColumnsPresent.add(MmsSmsColumns.EXPIRES_IN); smsColumnsPresent.add(MmsSmsColumns.EXPIRE_STARTED); + smsColumnsPresent.add(MmsSmsColumns.NOTIFIED); smsColumnsPresent.add(SmsDatabase.TYPE); smsColumnsPresent.add(SmsDatabase.SUBJECT); smsColumnsPresent.add(SmsDatabase.DATE_SENT); diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java index fca2b66ddc..d262332e59 100644 --- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -79,12 +79,12 @@ public class SmsDatabase extends MessagingDatabase { STATUS + " INTEGER DEFAULT -1," + TYPE + " INTEGER, " + REPLY_PATH_PRESENT + " INTEGER, " + RECEIPT_COUNT + " INTEGER DEFAULT 0," + SUBJECT + " TEXT, " + BODY + " TEXT, " + MISMATCHED_IDENTITIES + " TEXT DEFAULT NULL, " + SERVICE_CENTER + " TEXT, " + SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " + - EXPIRES_IN + " INTEGER DEFAULT 0, " + EXPIRE_STARTED + " INTEGER DEFAULT 0);"; + EXPIRES_IN + " INTEGER DEFAULT 0, " + EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " DEFAULT 0);"; public static final String[] CREATE_INDEXS = { "CREATE INDEX IF NOT EXISTS sms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");", "CREATE INDEX IF NOT EXISTS sms_read_index ON " + TABLE_NAME + " (" + READ + ");", - "CREATE INDEX IF NOT EXISTS sms_read_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + THREAD_ID + ");", + "CREATE INDEX IF NOT EXISTS sms_read_and_notified_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + NOTIFIED + "," + THREAD_ID + ");", "CREATE INDEX IF NOT EXISTS sms_type_index ON " + TABLE_NAME + " (" + TYPE + ");", "CREATE INDEX IF NOT EXISTS sms_date_sent_index ON " + TABLE_NAME + " (" + DATE_SENT + ");", "CREATE INDEX IF NOT EXISTS sms_thread_date_index ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + ");" @@ -96,7 +96,8 @@ public class SmsDatabase extends MessagingDatabase { DATE_SENT + " AS " + NORMALIZED_DATE_SENT, PROTOCOL, READ, STATUS, TYPE, REPLY_PATH_PRESENT, SUBJECT, BODY, SERVICE_CENTER, RECEIPT_COUNT, - MISMATCHED_IDENTITIES, SUBSCRIPTION_ID, EXPIRES_IN, EXPIRE_STARTED + MISMATCHED_IDENTITIES, SUBSCRIPTION_ID, EXPIRES_IN, EXPIRE_STARTED, + NOTIFIED }; private static final EarlyReceiptCache earlyReceiptCache = new EarlyReceiptCache(); @@ -271,6 +272,15 @@ public class SmsDatabase extends MessagingDatabase { updateTypeBitmask(id, Types.BASE_TYPE_MASK, Types.BASE_SENT_FAILED_TYPE); } + public void markAsNotified(long id) { + SQLiteDatabase database = databaseHelper.getWritableDatabase(); + ContentValues contentValues = new ContentValues(); + + contentValues.put(NOTIFIED, 1); + + database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(id)}); + } + public void incrementDeliveryReceiptCount(SyncMessageId messageId) { SQLiteDatabase database = databaseHelper.getWritableDatabase(); Cursor cursor = null; diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index defc6f3db6..7e7a31a26a 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -111,7 +111,6 @@ public class PushDecryptJob extends ContextJob { if (!IdentityKeyUtil.hasIdentityKey(context)) { Log.w(TAG, "Skipping job, waiting for migration..."); - MessageNotifier.updateNotification(context, null, true, -2); return; } diff --git a/src/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java b/src/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java new file mode 100644 index 0000000000..311f553451 --- /dev/null +++ b/src/org/thoughtcrime/securesms/notifications/DeleteNotificationReceiver.java @@ -0,0 +1,41 @@ +package org.thoughtcrime.securesms.notifications; + + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; + +import org.thoughtcrime.securesms.database.DatabaseFactory; + +public class DeleteNotificationReceiver extends BroadcastReceiver { + + public static String DELETE_NOTIFICATION_ACTION = "org.thoughtcrime.securesms.DELETE_NOTIFICATION"; + + public static String EXTRA_IDS = "message_ids"; + public static String EXTRA_MMS = "is_mms"; + + @Override + public void onReceive(final Context context, Intent intent) { + if (DELETE_NOTIFICATION_ACTION.equals(intent.getAction())) { + MessageNotifier.clearReminder(context); + + final long[] ids = intent.getLongArrayExtra(EXTRA_IDS); + final boolean[] mms = intent.getBooleanArrayExtra(EXTRA_MMS); + + if (ids == null || mms == null || ids.length != mms.length) return; + + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + for (int i=0;i messageAndThreadId = DatabaseFactory.getSmsDatabase(this).insertMissedCall(recipient.getNumber()); MessageNotifier.updateNotification(this, KeyCachingService.getMasterSecret(this), - false, messageAndThreadId.second, signal); + messageAndThreadId.second, signal); } private void handleAnswerCall(Intent intent) { diff --git a/src/org/thoughtcrime/securesms/util/DirectoryHelper.java b/src/org/thoughtcrime/securesms/util/DirectoryHelper.java index b435876a1c..76db8bafeb 100644 --- a/src/org/thoughtcrime/securesms/util/DirectoryHelper.java +++ b/src/org/thoughtcrime/securesms/util/DirectoryHelper.java @@ -239,9 +239,9 @@ public class DirectoryHelper { if (insertResult.isPresent()) { int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); if (hour >= 9 && hour < 23) { - MessageNotifier.updateNotification(context, masterSecret, false, insertResult.get().getThreadId(), true); + MessageNotifier.updateNotification(context, masterSecret, insertResult.get().getThreadId(), true); } else { - MessageNotifier.updateNotification(context, masterSecret, false, insertResult.get().getThreadId(), false); + MessageNotifier.updateNotification(context, masterSecret, insertResult.get().getThreadId(), false); } } }