From dbec5ad53cdeb07ae71759b85ca64a8a9c1b2e11 Mon Sep 17 00:00:00 2001 From: Harris Date: Mon, 16 Aug 2021 14:05:49 +1000 Subject: [PATCH 1/7] fix: fixing the message dismissal of notifications for threads upon activity resume. using media send activity's camera intent for consistency --- .../conversation/v2/ConversationActivityV2.kt | 14 +++----- .../v2/utilities/AttachmentManager.java | 36 +++++-------------- .../mediasend/MediaSendActivity.java | 13 ++++--- .../notifications/DefaultMessageNotifier.java | 3 +- .../utilities/TextSecurePreferences.kt | 2 +- 5 files changed, 23 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 4a86d5edc5..58e9697414 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -241,7 +241,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe searchBottomBar.setEventListener(this) setUpSearchResultObserver() scrollToFirstUnreadMessageIfNeeded() - markAllAsRead() showOrHideInputIfNeeded() if (this.thread.isOpenGroupRecipient) { val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID) @@ -255,6 +254,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe override fun onResume() { super.onResume() ApplicationContext.getInstance(this).messageNotifier.setVisibleThread(threadID) + markAllAsRead() } override fun onPause() { @@ -498,7 +498,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } else { MarkReadReceiver.process(this, messages) } - ApplicationContext.getInstance(this).messageNotifier.updateNotification(this, threadID) + ApplicationContext.getInstance(this).messageNotifier.updateNotification(this, false, 0) } override fun inputBarHeightChanged(newValue: Int) { @@ -977,7 +977,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } private fun showCamera() { - attachmentManager.capturePhoto(this, ConversationActivityV2.TAKE_PHOTO) + attachmentManager.capturePhoto(this, ConversationActivityV2.TAKE_PHOTO, thread); } override fun onAttachmentChanged() { @@ -1006,11 +1006,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val uri = intent?.data ?: return prepMediaForSending(uri, AttachmentManager.MediaType.DOCUMENT).addListener(mediaPreppedListener) } - TAKE_PHOTO -> { - if (resultCode != RESULT_OK) { return } - val uri = attachmentManager.captureUri ?: return - prepMediaForSending(uri, AttachmentManager.MediaType.IMAGE).addListener(mediaPreppedListener) - } PICK_GIF -> { intent ?: return val uri = intent.data ?: return @@ -1019,7 +1014,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val height = intent.getIntExtra(GiphyActivity.EXTRA_HEIGHT, 0) prepMediaForSending(uri, type, width, height).addListener(mediaPreppedListener) } - PICK_FROM_LIBRARY -> { + PICK_FROM_LIBRARY, + TAKE_PHOTO -> { intent ?: return val body = intent.getStringExtra(MediaSendActivity.EXTRA_MESSAGE) val media = intent.getParcelableArrayListExtra(MediaSendActivity.EXTRA_MEDIA) ?: return diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/AttachmentManager.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/AttachmentManager.java index d1d7e0b81c..dd90b699e3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/AttachmentManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/AttachmentManager.java @@ -25,7 +25,6 @@ import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; -import android.provider.MediaStore; import android.provider.OpenableColumns; import android.text.TextUtils; import android.util.Pair; @@ -34,9 +33,12 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.session.libsignal.utilities.NoExternalStorageException; -import org.thoughtcrime.securesms.giph.ui.GiphyActivity; +import org.session.libsession.utilities.recipients.Recipient; +import org.session.libsignal.utilities.ListenableFuture; import org.session.libsignal.utilities.Log; +import org.session.libsignal.utilities.SettableFuture; +import org.session.libsignal.utilities.guava.Optional; +import org.thoughtcrime.securesms.giph.ui.GiphyActivity; import org.thoughtcrime.securesms.mediasend.MediaSendActivity; import org.thoughtcrime.securesms.mms.AudioSlide; import org.thoughtcrime.securesms.mms.DocumentSlide; @@ -50,16 +52,8 @@ import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.mms.VideoSlide; import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.providers.BlobProvider; -import org.session.libsignal.utilities.ExternalStorageUtil; -import org.thoughtcrime.securesms.util.FileProviderUtil; import org.thoughtcrime.securesms.util.MediaUtil; -import org.session.libsignal.utilities.guava.Optional; -import org.session.libsession.utilities.recipients.Recipient; -import org.session.libsignal.utilities.ListenableFuture; -import org.session.libsignal.utilities.SettableFuture; - -import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.LinkedList; @@ -67,8 +61,6 @@ import java.util.List; import network.loki.messenger.R; -import static android.provider.MediaStore.EXTRA_OUTPUT; - public class AttachmentManager { private final static String TAG = AttachmentManager.class.getSimpleName(); @@ -278,25 +270,15 @@ public class AttachmentManager { return captureUri; } - public void capturePhoto(Activity activity, int requestCode) { + public void capturePhoto(Activity activity, int requestCode, Recipient recipient) { Permissions.with(activity) .request(Manifest.permission.CAMERA) .withPermanentDenialDialog(activity.getString(R.string.AttachmentManager_signal_requires_the_camera_permission_in_order_to_take_photos_but_it_has_been_permanently_denied)) .withRationaleDialog(activity.getString(R.string.ConversationActivity_to_capture_photos_and_video_allow_signal_access_to_the_camera),R.drawable.ic_baseline_photo_camera_24) .onAllGranted(() -> { - try { - File captureFile = File.createTempFile("conversation-capture", ".jpg", ExternalStorageUtil.getImageDir(activity)); - Uri captureUri = FileProviderUtil.getUriFor(context, captureFile); - Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - captureIntent.putExtra(EXTRA_OUTPUT, captureUri); - captureIntent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - if (captureIntent.resolveActivity(activity.getPackageManager()) != null) { - Log.d(TAG, "captureUri path is " + captureUri.getPath()); - this.captureUri = captureUri; - activity.startActivityForResult(captureIntent, requestCode); - } - } catch (IOException | NoExternalStorageException e) { - throw new RuntimeException("Error creating image capture intent.", e); + Intent captureIntent = MediaSendActivity.buildCameraIntent(activity, recipient); + if (captureIntent.resolveActivity(activity.getPackageManager()) != null) { + activity.startActivityForResult(captureIntent, requestCode); } }) .execute(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendActivity.java b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendActivity.java index d2b36a6892..3e9fd7905e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/MediaSendActivity.java @@ -20,19 +20,18 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.ViewModelProvider; +import org.session.libsession.utilities.Address; import org.session.libsession.utilities.MediaTypes; +import org.session.libsession.utilities.Util; +import org.session.libsession.utilities.concurrent.SimpleTask; +import org.session.libsession.utilities.recipients.Recipient; +import org.session.libsignal.utilities.Log; import org.session.libsignal.utilities.guava.Optional; import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity; -import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.scribbles.ImageEditorFragment; -import org.session.libsession.utilities.Address; -import org.session.libsession.utilities.recipients.Recipient; -import org.session.libsession.utilities.concurrent.SimpleTask; -import org.session.libsession.utilities.Util; - import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -87,7 +86,7 @@ public class MediaSendActivity extends PassphraseRequiredActionBarActivity imple } /** - * Get an intent to launch the media send flow starting with the picker. + * Get an intent to launch the media send flow starting with the camera. */ public static Intent buildCameraIntent(@NonNull Context context, @NonNull Recipient recipient) { Intent intent = buildGalleryIntent(context, recipient, ""); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index e7f8e8e5c8..616b17799d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -90,8 +90,9 @@ public class DefaultMessageNotifier implements MessageNotifier { private static final String TAG = DefaultMessageNotifier.class.getSimpleName(); - public static final String EXTRA_REMOTE_REPLY = "extra_remote_reply"; + public static final String EXTRA_REMOTE_REPLY = "extra_remote_reply"; public static final String LATEST_MESSAGE_ID_TAG = "extra_latest_message_id"; + public static final String EXTRA_THREAD_ID = "extra_thread_id"; private static final int FOREGROUND_ID = 313399; private static final int SUMMARY_NOTIFICATION_ID = 1338; diff --git a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt index 7ac0feae6d..cef0b9315f 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt @@ -380,7 +380,7 @@ object TextSecurePreferences { @JvmStatic fun isInThreadNotifications(context: Context): Boolean { - return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, true) + return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, false) } @JvmStatic From 1f3db80d369a2770ace7a7c47889195f62e84b0b Mon Sep 17 00:00:00 2001 From: Harris Date: Wed, 18 Aug 2021 12:15:49 +1000 Subject: [PATCH 2/7] fix: only show notification settings if the contact is not muted and a group --- .../securesms/conversation/v2/menus/ConversationMenuHelper.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index 70e4737846..395d68bf34 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -92,6 +92,9 @@ object ConversationMenuHelper { inflater.inflate(R.menu.menu_conversation_muted, menu) } else { inflater.inflate(R.menu.menu_conversation_unmuted, menu) + } + + if (thread.isGroupRecipient && !thread.isMuted) { inflater.inflate(R.menu.menu_conversation_notification_settings, menu) } From 975076cb5cdaef0739cf3aa2c8755144eb62317b Mon Sep 17 00:00:00 2001 From: Harris Date: Thu, 19 Aug 2021 12:14:21 +1000 Subject: [PATCH 3/7] fix: bundled notification no longer notifies on mentions only --- .../notifications/DefaultMessageNotifier.java | 14 +++++++++++++- .../MultipleRecipientNotificationBuilder.java | 6 +++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index 616b17799d..a8257a2401 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -315,7 +315,7 @@ public class DefaultMessageNotifier implements MessageNotifier { List notifications = notificationState.getNotifications(); Recipient recipient = notifications.get(0).getRecipient(); int notificationId = (int) (SUMMARY_NOTIFICATION_ID + (bundled ? notifications.get(0).getThreadId() : 0)); - String messageIdTag = String.valueOf(notifications.get(0).getId()); + String messageIdTag = String.valueOf(notifications.get(0).getTimestamp()); NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); for (StatusBarNotification notification: notificationManager.getActiveNotifications()) { @@ -402,6 +402,16 @@ public class DefaultMessageNotifier implements MessageNotifier { builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY); builder.setAutoCancel(true); + String messageIdTag = String.valueOf(notifications.get(0).getTimestamp()); + + NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); + for (StatusBarNotification notification: notificationManager.getActiveNotifications()) { + if (notification.getId() == SUMMARY_NOTIFICATION_ID + && messageIdTag.equals(notification.getNotification().extras.getString(LATEST_MESSAGE_ID_TAG))) { + return; + } + } + long timestamp = notifications.get(0).getTimestamp(); if (timestamp != 0) builder.setWhen(timestamp); @@ -421,6 +431,8 @@ public class DefaultMessageNotifier implements MessageNotifier { MentionUtilities.highlightMentions(notifications.get(0).getText(), notifications.get(0).getThreadId(), context)); } + builder.putStringExtra(LATEST_MESSAGE_ID_TAG, messageIdTag); + Notification notification = builder.build(); NotificationManagerCompat.from(context).notify(SUMMARY_NOTIFICATION_ID, builder.build()); Log.i(TAG, "Posted notification. " + notification.toString()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java index 24374ddd0f..15b62df3c9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java @@ -16,8 +16,8 @@ import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; import org.session.libsession.utilities.recipients.Recipient; import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.home.HomeActivity; import org.thoughtcrime.securesms.database.SessionContactDatabase; +import org.thoughtcrime.securesms.home.HomeActivity; import java.util.LinkedList; import java.util.List; @@ -72,6 +72,10 @@ public class MultipleRecipientNotificationBuilder extends AbstractNotificationBu extend(new NotificationCompat.WearableExtender().addAction(markAllAsReadAction)); } + public void putStringExtra(String key, String value) { + extras.putString(key,value); + } + public void addMessageBody(@NonNull Recipient sender, Recipient threadRecipient, @Nullable CharSequence body) { String displayName = sender.toShortString(); if (threadRecipient.isOpenGroupRecipient()) { From ef8cdf312778eb32d54cc265dced08c4fb355b6d Mon Sep 17 00:00:00 2001 From: Harris Date: Thu, 19 Aug 2021 12:24:28 +1000 Subject: [PATCH 4/7] fix: handle bundling properly with the messageIdTag check --- .../securesms/notifications/DefaultMessageNotifier.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index a8257a2401..577c3af5c2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -319,8 +319,8 @@ public class DefaultMessageNotifier implements MessageNotifier { NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); for (StatusBarNotification notification: notificationManager.getActiveNotifications()) { - - if (messageIdTag.equals(notification.getNotification().extras.getString(LATEST_MESSAGE_ID_TAG))) { + if ( (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && notification.isAppGroup() == bundled) + && messageIdTag.equals(notification.getNotification().extras.getString(LATEST_MESSAGE_ID_TAG))) { return; } } From 7ac340b3cae9304d6aacbff429915f78444fbdf2 Mon Sep 17 00:00:00 2001 From: Harris Date: Thu, 19 Aug 2021 13:44:38 +1000 Subject: [PATCH 5/7] refactor: remove unused constant --- .../securesms/notifications/DefaultMessageNotifier.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index 577c3af5c2..32745723e8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -92,7 +92,6 @@ public class DefaultMessageNotifier implements MessageNotifier { public static final String EXTRA_REMOTE_REPLY = "extra_remote_reply"; public static final String LATEST_MESSAGE_ID_TAG = "extra_latest_message_id"; - public static final String EXTRA_THREAD_ID = "extra_thread_id"; private static final int FOREGROUND_ID = 313399; private static final int SUMMARY_NOTIFICATION_ID = 1338; From 021d81ab98c6e2319e6884cb3f3915914678ed24 Mon Sep 17 00:00:00 2001 From: Harris Date: Thu, 19 Aug 2021 13:45:57 +1000 Subject: [PATCH 6/7] refactor: alignment --- .../securesms/notifications/DefaultMessageNotifier.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index 32745723e8..552f7200ef 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -93,8 +93,8 @@ public class DefaultMessageNotifier implements MessageNotifier { public static final String EXTRA_REMOTE_REPLY = "extra_remote_reply"; public static final String LATEST_MESSAGE_ID_TAG = "extra_latest_message_id"; - private static final int FOREGROUND_ID = 313399; - private static final int SUMMARY_NOTIFICATION_ID = 1338; + private static final int FOREGROUND_ID = 313399; + private static final int SUMMARY_NOTIFICATION_ID = 1338; private static final int PENDING_MESSAGES_ID = 1111; private static final String NOTIFICATION_GROUP = "messages"; private static final long MIN_AUDIBLE_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(2); From b7ead5778ee35ee9b6aed21f1a2365da17696856 Mon Sep 17 00:00:00 2001 From: Harris Date: Thu, 19 Aug 2021 14:16:54 +1000 Subject: [PATCH 7/7] refactor: revert inThreadNotification pref to default true --- .../org/session/libsession/utilities/TextSecurePreferences.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt index cef0b9315f..7ac0feae6d 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt @@ -380,7 +380,7 @@ object TextSecurePreferences { @JvmStatic fun isInThreadNotifications(context: Context): Boolean { - return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, false) + return getBooleanPreference(context, IN_THREAD_NOTIFICATION_PREF, true) } @JvmStatic