diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c57c8280b58afc10875034b3ec6b06122d528a0f..1ff5d5f8e4ed14a8daa50b2e09478323e7b872cc 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -331,6 +331,14 @@ + + + + + + diff --git a/res/drawable-hdpi/ic_reply_white_24dp.png b/res/drawable-hdpi/ic_reply_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..0424c2bd6d6eaa5fcd3398f71b6e230ffc1caa7b Binary files /dev/null and b/res/drawable-hdpi/ic_reply_white_24dp.png differ diff --git a/res/drawable-mdpi/ic_reply_white_24dp.png b/res/drawable-mdpi/ic_reply_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..862114b82dafbbf8ca125d02ce7b723e901cf396 Binary files /dev/null and b/res/drawable-mdpi/ic_reply_white_24dp.png differ diff --git a/res/drawable-xhdpi/ic_reply_white_24dp.png b/res/drawable-xhdpi/ic_reply_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..885623e4d0bb82cbb39424905a689b9bc6af22c1 Binary files /dev/null and b/res/drawable-xhdpi/ic_reply_white_24dp.png differ diff --git a/res/drawable-xxhdpi/ic_reply_white_24dp.png b/res/drawable-xxhdpi/ic_reply_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..de0dad2047bd788a1a8fb8481e55a65bb3f80058 Binary files /dev/null and b/res/drawable-xxhdpi/ic_reply_white_24dp.png differ diff --git a/res/drawable-xxxhdpi/ic_reply_white_24dp.png b/res/drawable-xxxhdpi/ic_reply_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..ed85f50ab94bb216b8369d51e06458591d6a6d5f Binary files /dev/null and b/res/drawable-xxxhdpi/ic_reply_white_24dp.png differ diff --git a/res/values/strings.xml b/res/values/strings.xml index 340ff8e701d2e25717dfc05723234404aa6afabb..9992d6110d5eebee25f39238e4d2e8a712cbcb6d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -426,6 +426,7 @@ Failed to deliver message. Error delivering message. Mark all as read + Delete all Mark read Media message Message received by %s. diff --git a/src/org/smssecure/smssecure/notifications/DeleteMessageReceiver.java b/src/org/smssecure/smssecure/notifications/DeleteMessageReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..eecca4d90893de6e7df98778039d12db836bfc71 --- /dev/null +++ b/src/org/smssecure/smssecure/notifications/DeleteMessageReceiver.java @@ -0,0 +1,60 @@ +package org.smssecure.smssecure.notifications; + +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; +import android.support.annotation.Nullable; +import android.support.v4.app.NotificationManagerCompat; +import android.util.Log; + +import org.smssecure.smssecure.crypto.MasterSecret; +import org.smssecure.smssecure.database.DatabaseFactory; + +public class DeleteMessageReceiver extends MasterSecretBroadcastReceiver { + + private static final String TAG = DeleteMessageReceiver.class.getSimpleName(); + public static final String DELETE_ACTION = "org.smssecure.smssecure.notifications.DELETE_MSGS"; + public static final String MSG_IDS_EXTRA = "msg_ids"; + public static final String MSG_IS_MMS_EXTRA = "msg_is_mms"; + 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) + { + if (!DELETE_ACTION.equals(intent.getAction())) + return; + + final long[] messageIds = intent.getLongArrayExtra(MSG_IDS_EXTRA); + final boolean[] messageIsMms = intent.getBooleanArrayExtra(MSG_IS_MMS_EXTRA); + final long[] threadIds = intent.getLongArrayExtra(THREAD_IDS_EXTRA); + + if (messageIds == null || messageIsMms == null || threadIds == null || + messageIds.length != messageIsMms.length){ + Log.e(TAG, "Bad extras received"); + return; + } + + NotificationManagerCompat.from(context).cancel(intent.getIntExtra(NOTIFICATION_ID_EXTRA, -1)); + + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + for (int i = 0; i < messageIds.length; i++) { + if (messageIsMms[i]) { + DatabaseFactory.getMmsDatabase(context).delete(messageIds[i]); + } else { + DatabaseFactory.getSmsDatabase(context).deleteMessage(messageIds[i]); + } + } + for (long threadId : threadIds) { + DatabaseFactory.getThreadDatabase(context).setRead(threadId); + } + + MessageNotifier.updateNotification(context, masterSecret); + return null; + } + }.execute(); + } +} diff --git a/src/org/smssecure/smssecure/notifications/MessageNotifier.java b/src/org/smssecure/smssecure/notifications/MessageNotifier.java index df873880253d34cd017a4b32da1f7619647f3d70..14a2cf9b660d3bee125f1f8e3678abfd49593cbf 100644 --- a/src/org/smssecure/smssecure/notifications/MessageNotifier.java +++ b/src/org/smssecure/smssecure/notifications/MessageNotifier.java @@ -295,7 +295,8 @@ public class MessageNotifier { builder.addActions(masterSecret, notificationState.getMarkAsReadIntent(context, notificationId), notificationState.getQuickReplyIntent(context, notifications.get(0).getRecipients()), - notificationState.getRemoteReplyIntent(context, notifications.get(0).getRecipients())); + notificationState.getRemoteReplyIntent(context, notifications.get(0).getRecipients()), + notificationState.getDeleteMessageIntent(context, notificationId)); ListIterator iterator = notifications.listIterator(notifications.size()); @@ -333,7 +334,8 @@ public class MessageNotifier { long timestamp = notifications.get(0).getTimestamp(); if (timestamp != 0) builder.setWhen(timestamp); - builder.addActions(notificationState.getMarkAsReadIntent(context, SUMMARY_NOTIFICATION_ID)); + builder.addActions(notificationState.getMarkAsReadIntent(context, SUMMARY_NOTIFICATION_ID), + notificationState.getDeleteMessageIntent(context, SUMMARY_NOTIFICATION_ID)); ListIterator iterator = notifications.listIterator(0); diff --git a/src/org/smssecure/smssecure/notifications/MultipleRecipientNotificationBuilder.java b/src/org/smssecure/smssecure/notifications/MultipleRecipientNotificationBuilder.java index 721f796f32e423c2f4681ddfb0de0de0436def15..b7d757734477a74f6c7a9891ef01931adb378a8e 100644 --- a/src/org/smssecure/smssecure/notifications/MultipleRecipientNotificationBuilder.java +++ b/src/org/smssecure/smssecure/notifications/MultipleRecipientNotificationBuilder.java @@ -47,12 +47,17 @@ public class MultipleRecipientNotificationBuilder extends AbstractNotificationBu } } - public void addActions(PendingIntent markAsReadIntent) { - NotificationCompat.Action markAllAsReadAction = new NotificationCompat.Action(R.drawable.check, + public void addActions(PendingIntent markAsReadIntent, PendingIntent deleteAllIntent) { + NotificationCompat.Action markAllAsReadAction = new NotificationCompat.Action(R.drawable.ic_check_white_24dp, context.getString(R.string.MessageNotifier_mark_all_as_read), markAsReadIntent); + NotificationCompat.Action deleteAllAction = new NotificationCompat.Action(R.drawable.ic_delete_white_24dp, + context.getString(R.string.MessageNotifier_delete_all), + deleteAllIntent); addAction(markAllAsReadAction); - extend(new NotificationCompat.WearableExtender().addAction(markAllAsReadAction)); + addAction(deleteAllAction); + extend(new NotificationCompat.WearableExtender().addAction(markAllAsReadAction) + .addAction(deleteAllAction)); } public void addMessageBody(@NonNull Recipient sender, @Nullable CharSequence body) { diff --git a/src/org/smssecure/smssecure/notifications/NotificationState.java b/src/org/smssecure/smssecure/notifications/NotificationState.java index e2c6b99acd688b7d23661472f1d810f20b19a4a2..d0b43bfc13c393b4ece00985d65b1a9a9f3dc9d9 100644 --- a/src/org/smssecure/smssecure/notifications/NotificationState.java +++ b/src/org/smssecure/smssecure/notifications/NotificationState.java @@ -102,7 +102,6 @@ public class NotificationState { int index = 0; for (long thread : threads) { - Log.w("NotificationState", "Added thread: " + thread); threadArray[index++] = thread; } @@ -115,6 +114,33 @@ public class NotificationState { return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } + public PendingIntent getDeleteMessageIntent(Context context, int notificationId){ + + long[] idArray = new long[notificationCount]; + boolean[] isMmsArray = new boolean[notificationCount]; + long[] threadArray = new long[threads.size()]; + int index = 0; + + for (NotificationItem notificationItem : notifications) { + isMmsArray[index] = notificationItem.isMms(); + idArray[index++] = notificationItem.getId(); + } + index = 0; + for (long thread : threads) { + threadArray[index++] = thread; + } + + Intent intent = new Intent(DeleteMessageReceiver.DELETE_ACTION); + intent.setClass(context, DeleteMessageReceiver.class); + intent.setData((Uri.parse("custom://"+System.currentTimeMillis()))); + intent.putExtra(DeleteMessageReceiver.MSG_IDS_EXTRA, idArray); + intent.putExtra(DeleteMessageReceiver.MSG_IS_MMS_EXTRA, isMmsArray); + intent.putExtra(DeleteMessageReceiver.THREAD_IDS_EXTRA, threadArray); + intent.putExtra(DeleteMessageReceiver.NOTIFICATION_ID_EXTRA, notificationId); + + return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } + public PendingIntent getRemoteReplyIntent(Context context, Recipients recipients) { if (threads.size() != 1) throw new AssertionError("We only support replies to single thread notifications!"); @@ -130,7 +156,7 @@ public class NotificationState { public PendingIntent getQuickReplyIntent(Context context, Recipients recipients) { 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 intent = new Intent(context, ConversationPopupActivity.class); intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.getIds()); intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, (long)threads.toArray()[0]); intent.setData((Uri.parse("custom://"+System.currentTimeMillis()))); diff --git a/src/org/smssecure/smssecure/notifications/SingleRecipientNotificationBuilder.java b/src/org/smssecure/smssecure/notifications/SingleRecipientNotificationBuilder.java index 8f4d0e0eacd5c339b7d6ab5841452133ffcbc9bd..4fda318fdf598864994e1b97f2903a9a5311e6ba 100644 --- a/src/org/smssecure/smssecure/notifications/SingleRecipientNotificationBuilder.java +++ b/src/org/smssecure/smssecure/notifications/SingleRecipientNotificationBuilder.java @@ -102,19 +102,23 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil public void addActions(@Nullable MasterSecret masterSecret, @NonNull PendingIntent markReadIntent, @NonNull PendingIntent quickReplyIntent, - @NonNull PendingIntent wearableReplyIntent) + @NonNull PendingIntent wearableReplyIntent, + @NonNull PendingIntent deleteIntent) { - Action markAsReadAction = new Action(R.drawable.check, + Action markAsReadAction = new Action(R.drawable.ic_check_white_24dp, context.getString(R.string.MessageNotifier_mark_read), markReadIntent); + Action deleteAction = new Action(R.drawable.ic_delete_white_24dp, + context.getString(R.string.delete), + deleteIntent); if (masterSecret != null) { - Action replyAction = new Action(R.drawable.ic_reply_white_36dp, + Action replyAction = new Action(R.drawable.ic_reply_white_24dp, context.getString(R.string.MessageNotifier_reply), quickReplyIntent); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - replyAction = new Action.Builder(R.drawable.ic_reply_white_36dp, + replyAction = new Action.Builder(R.drawable.ic_reply_white_24dp, context.getString(R.string.MessageNotifier_reply), wearableReplyIntent) .addRemoteInput(new RemoteInput.Builder(MessageNotifier.EXTRA_REMOTE_REPLY) @@ -131,13 +135,17 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil addAction(markAsReadAction); addAction(replyAction); + addAction(deleteAction); extend(new NotificationCompat.WearableExtender().addAction(markAsReadAction) - .addAction(wearableReplyAction)); + .addAction(wearableReplyAction) + .addAction(deleteAction)); } else { addAction(markAsReadAction); + addAction(deleteAction); - extend(new NotificationCompat.WearableExtender().addAction(markAsReadAction)); + extend(new NotificationCompat.WearableExtender().addAction(markAsReadAction) + .addAction(deleteAction)); } }