From f977b566a5caa39355241c3e0f809bcd50c8033c Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Thu, 7 Jul 2022 17:48:03 +0200 Subject: [PATCH 1/8] Implement mark as read via notification Resolves #2164 Signed-off-by: Andy Scherzinger --- app/src/main/AndroidManifest.xml | 1 + .../talk/jobs/NotificationWorker.java | 35 +++++ .../talk/receivers/MarkAsReadReceiver.kt | 125 ++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9e1b27e5c..be6102c29 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -199,6 +199,7 @@ + = Build.VERSION_CODES.S) { + intentFlag = PendingIntent.FLAG_MUTABLE|PendingIntent.FLAG_UPDATE_CURRENT; + } else { + intentFlag = PendingIntent.FLAG_UPDATE_CURRENT; + } + PendingIntent pendingIntent = + PendingIntent.getBroadcast(context, systemNotificationId, actualIntent, intentFlag); + + NotificationCompat.Action action = + new NotificationCompat.Action.Builder(R.drawable.ic_eye, label, pendingIntent) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ) + .setShowsUserInterface(false) + .build(); + + notificationBuilder.addAction(action); + } + @RequiresApi(api = Build.VERSION_CODES.N) private void addReplyAction(NotificationCompat.Builder notificationBuilder, int systemNotificationId) { String replyLabel = context.getResources().getString(R.string.nc_reply); diff --git a/app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt b/app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt new file mode 100644 index 000000000..8a5814ca3 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt @@ -0,0 +1,125 @@ +/* + * Nextcloud Talk application + * + * @author Andy Scherzinger + * @author Dariusz Olszewski + * Copyright (C) 2022 Andy Scherzinger + * Copyright (C) 2022 Dariusz Olszewski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.nextcloud.talk.receivers + +import android.app.NotificationManager +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.os.Build +import android.util.Log +import androidx.annotation.RequiresApi +import autodagger.AutoInjector +import com.nextcloud.talk.api.NcApi +import com.nextcloud.talk.application.NextcloudTalkApplication +import com.nextcloud.talk.models.database.UserEntity +import com.nextcloud.talk.models.json.generic.GenericOverall +import com.nextcloud.talk.utils.ApiUtils +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_MESSAGE_ID +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SYSTEM_NOTIFICATION_ID +import com.nextcloud.talk.utils.database.user.UserUtils +import io.reactivex.Observer +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.Disposable +import io.reactivex.schedulers.Schedulers +import javax.inject.Inject + +@AutoInjector(NextcloudTalkApplication::class) +class MarkAsReadReceiver : BroadcastReceiver() { + + @Inject + lateinit var userUtils: UserUtils + + @Inject + lateinit var ncApi: NcApi + + lateinit var context: Context + lateinit var currentUser: UserEntity + private var systemNotificationId: Int? = null + private var roomToken: String? = null + private var messageId: Int = 0 + + init { + NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) + } + + override fun onReceive(receiveContext: Context, intent: Intent?) { + context = receiveContext + + // NOTE - systemNotificationId is an internal ID used on the device only. + // It is NOT the same as the notification ID used in communication with the server. + systemNotificationId = intent!!.getIntExtra(KEY_SYSTEM_NOTIFICATION_ID, 0) + roomToken = intent.getStringExtra(KEY_ROOM_TOKEN) + messageId = intent.getIntExtra(KEY_MESSAGE_ID, 0) + + val id = intent.getLongExtra(KEY_INTERNAL_USER_ID, userUtils.currentUser!!.id) + currentUser = userUtils.getUserWithId(id) + + markAsRead() + } + + private fun markAsRead() { + val credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token) + val apiVersion = ApiUtils.getChatApiVersion(currentUser, intArrayOf(1)) + val url = ApiUtils.getUrlForSetChatReadMarker( + apiVersion, + currentUser.baseUrl, + roomToken + ) + + ncApi.setChatReadMarker(credentials, url, messageId) + ?.subscribeOn(Schedulers.io()) + ?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribe(object : Observer { + override fun onSubscribe(d: Disposable) { + // unused atm + } + + @RequiresApi(Build.VERSION_CODES.N) + override fun onNext(genericOverall: GenericOverall) { + cancelNotification(systemNotificationId!!) + } + + @RequiresApi(Build.VERSION_CODES.N) + override fun onError(e: Throwable) { + Log.e(TAG, "Failed to send reply", e) + } + + override fun onComplete() { + // unused atm + } + }) + } + + @RequiresApi(Build.VERSION_CODES.N) + private fun cancelNotification(notificationId: Int) { + val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.cancel(notificationId) + } + + companion object { + const val TAG = "MarkAsReadReceiver" + } +} From 7243142676fa7957d6535072274f0f167d77a479 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sun, 10 Jul 2022 22:27:30 +0200 Subject: [PATCH 2/8] Mark as read - use message ID retrieved from server Minimal set of changes, to be cleaned-up. Signed-off-by: Dariusz Olszewski --- .../java/com/nextcloud/talk/jobs/NotificationWorker.java | 6 +++++- .../talk/models/json/push/DecryptedPushMessage.kt | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java index 6d6c0cc2a..b16aca901 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java @@ -247,6 +247,8 @@ public class NotificationWorker extends Worker { } } + decryptedPushMessage.setObjectId(notification.getObjectId()); + showNotification(intent); } @@ -427,7 +429,9 @@ public class NotificationWorker extends Worker { actualIntent.putExtra(BundleKeys.INSTANCE.getKEY_SYSTEM_NOTIFICATION_ID(), systemNotificationId); actualIntent.putExtra(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), decryptedPushMessage.getId()); if (decryptedPushMessage.getNotificationId() != null) { - actualIntent.putExtra(BundleKeys.KEY_MESSAGE_ID, decryptedPushMessage.getNotificationId().intValue()); + // TODO - improve parsing when server returns unexpected objectId + int messageId = Integer.parseInt(decryptedPushMessage.getObjectId().split("/")[1]); + actualIntent.putExtra(BundleKeys.KEY_MESSAGE_ID, messageId); } int intentFlag; diff --git a/app/src/main/java/com/nextcloud/talk/models/json/push/DecryptedPushMessage.kt b/app/src/main/java/com/nextcloud/talk/models/json/push/DecryptedPushMessage.kt index a992f8bda..001305b51 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/push/DecryptedPushMessage.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/push/DecryptedPushMessage.kt @@ -62,10 +62,13 @@ data class DecryptedPushMessage( var text: String?, @JsonIgnore - var timestamp: Long + var timestamp: Long, + + @JsonIgnore + var objectId: String? ) : Parcelable { // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' - constructor() : this(null, null, "", null, 0, null, false, false, false, null, null, 0) + constructor() : this(null, null, "", null, 0, null, false, false, false, null, null, 0, null) override fun equals(other: Any?): Boolean { if (this === other) return true @@ -88,6 +91,7 @@ data class DecryptedPushMessage( if (notificationUser != other.notificationUser) return false if (text != other.text) return false if (timestamp != other.timestamp) return false + if (objectId != other.objectId) return false return true } @@ -105,6 +109,7 @@ data class DecryptedPushMessage( result = 31 * result + (notificationUser?.hashCode() ?: 0) result = 31 * result + (text?.hashCode() ?: 0) result = 31 * result + (timestamp?.hashCode() ?: 0) + result = 31 * result + (objectId?.hashCode() ?: 0) return result } } From c3a31da6a9441ec4a5d61bbf6e697b2154df412a Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sun, 10 Jul 2022 23:20:01 +0200 Subject: [PATCH 3/8] Mark as read - extract buildIntentForAction function Signed-off-by: Dariusz Olszewski --- .../talk/jobs/NotificationWorker.java | 47 +++++++------------ 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java index b16aca901..a6ff894b0 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java @@ -417,22 +417,16 @@ public class NotificationWorker extends Worker { notificationBuilder.setStyle(getStyle(person.build(), style)); } - private void addMarkAsReadAction(NotificationCompat.Builder notificationBuilder, int systemNotificationId) { - String label = context.getResources().getString(R.string.nc_mark_as_read); - - // Build a PendingIntent for the reply action - Intent actualIntent = new Intent(context, MarkAsReadReceiver.class); + private PendingIntent buildIntentForAction(Class cls, int systemNotificationId, int messageId) { + Intent actualIntent = new Intent(context, cls); // NOTE - systemNotificationId is an internal ID used on the device only. // It is NOT the same as the notification ID used in communication with the server. - actualIntent.putExtra(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), Objects.requireNonNull(signatureVerification.getUserEntity()).getId()); actualIntent.putExtra(BundleKeys.INSTANCE.getKEY_SYSTEM_NOTIFICATION_ID(), systemNotificationId); + actualIntent.putExtra(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), + Objects.requireNonNull(signatureVerification.getUserEntity()).getId()); actualIntent.putExtra(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), decryptedPushMessage.getId()); - if (decryptedPushMessage.getNotificationId() != null) { - // TODO - improve parsing when server returns unexpected objectId - int messageId = Integer.parseInt(decryptedPushMessage.getObjectId().split("/")[1]); - actualIntent.putExtra(BundleKeys.KEY_MESSAGE_ID, messageId); - } + actualIntent.putExtra(BundleKeys.KEY_MESSAGE_ID, messageId); int intentFlag; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { @@ -440,8 +434,18 @@ public class NotificationWorker extends Worker { } else { intentFlag = PendingIntent.FLAG_UPDATE_CURRENT; } - PendingIntent pendingIntent = - PendingIntent.getBroadcast(context, systemNotificationId, actualIntent, intentFlag); + + return PendingIntent.getBroadcast(context, systemNotificationId, actualIntent, intentFlag); + } + + private void addMarkAsReadAction(NotificationCompat.Builder notificationBuilder, int systemNotificationId) { + String label = context.getResources().getString(R.string.nc_mark_as_read); + + // TODO - improve parsing when server returns unexpected objectId + int messageId = Integer.parseInt(decryptedPushMessage.getObjectId().split("/")[1]); + + // Build a PendingIntent for the mark as read action + PendingIntent pendingIntent = buildIntentForAction(MarkAsReadReceiver.class, systemNotificationId, messageId); NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_eye, label, pendingIntent) @@ -461,22 +465,7 @@ public class NotificationWorker extends Worker { .build(); // Build a PendingIntent for the reply action - Intent actualIntent = new Intent(context, DirectReplyReceiver.class); - - // NOTE - systemNotificationId is an internal ID used on the device only. - // It is NOT the same as the notification ID used in communication with the server. - actualIntent.putExtra(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), Objects.requireNonNull(signatureVerification.getUserEntity()).getId()); - actualIntent.putExtra(BundleKeys.INSTANCE.getKEY_SYSTEM_NOTIFICATION_ID(), systemNotificationId); - actualIntent.putExtra(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), decryptedPushMessage.getId()); - - int intentFlag; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - intentFlag = PendingIntent.FLAG_MUTABLE|PendingIntent.FLAG_UPDATE_CURRENT; - } else { - intentFlag = PendingIntent.FLAG_UPDATE_CURRENT; - } - PendingIntent replyPendingIntent = - PendingIntent.getBroadcast(context, systemNotificationId, actualIntent, intentFlag); + PendingIntent replyPendingIntent = buildIntentForAction(DirectReplyReceiver.class, systemNotificationId, 0); NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder(R.drawable.ic_reply, replyLabel, replyPendingIntent) From 9a247b48ac6ab7e44b282837312a78347d712ecf Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sun, 10 Jul 2022 23:20:36 +0200 Subject: [PATCH 4/8] Mark as read - correct error message Signed-off-by: Dariusz Olszewski --- .../java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt b/app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt index 8a5814ca3..46095f852 100644 --- a/app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt +++ b/app/src/main/java/com/nextcloud/talk/receivers/MarkAsReadReceiver.kt @@ -104,7 +104,7 @@ class MarkAsReadReceiver : BroadcastReceiver() { @RequiresApi(Build.VERSION_CODES.N) override fun onError(e: Throwable) { - Log.e(TAG, "Failed to send reply", e) + Log.e(TAG, "Failed to set chat read marker", e) } override fun onComplete() { From f91d45e2db3e03c74ed26216e73907d24ed1aa98 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Mon, 11 Jul 2022 19:58:32 +0200 Subject: [PATCH 5/8] Improve message id parsing Signed-off-by: Andy Scherzinger --- .../talk/jobs/NotificationWorker.java | 82 +++++++++++++------ 1 file changed, 58 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java index a6ff894b0..4f53ad220 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java @@ -134,8 +134,10 @@ public class NotificationWorker extends Worker { ArbitraryStorageEntity arbitraryStorageEntity; - if ((arbitraryStorageEntity = arbitraryStorageUtils.getStorageSetting(userEntity.getId(), - "important_conversation", intent.getExtras().getString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN()))) != null) { + if ((arbitraryStorageEntity = arbitraryStorageUtils.getStorageSetting( + userEntity.getId(), + "important_conversation", + intent.getExtras().getString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN()))) != null) { importantConversation = Boolean.parseBoolean(arbitraryStorageEntity.getValue()); } @@ -202,8 +204,9 @@ public class NotificationWorker extends Worker { if (notification.getMessageRichParameters() != null && notification.getMessageRichParameters().size() > 0) { - decryptedPushMessage.setText(ChatUtils.Companion.getParsedMessage(notification.getMessageRich(), - notification.getMessageRichParameters())); + decryptedPushMessage.setText(ChatUtils.Companion.getParsedMessage( + notification.getMessageRich(), + notification.getMessageRichParameters())); } else { decryptedPushMessage.setText(notification.getMessage()); } @@ -335,10 +338,13 @@ public class NotificationWorker extends Worker { } Bundle notificationInfo = new Bundle(); - notificationInfo.putLong(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), signatureVerification.getUserEntity().getId()); + notificationInfo.putLong(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), + signatureVerification.getUserEntity().getId()); // could be an ID or a TOKEN - notificationInfo.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), decryptedPushMessage.getId()); - notificationInfo.putLong(BundleKeys.INSTANCE.getKEY_NOTIFICATION_ID(), decryptedPushMessage.getNotificationId()); + notificationInfo.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), + decryptedPushMessage.getId()); + notificationInfo.putLong(BundleKeys.INSTANCE.getKEY_NOTIFICATION_ID(), + decryptedPushMessage.getNotificationId()); notificationBuilder.setExtras(notificationInfo); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -439,21 +445,28 @@ public class NotificationWorker extends Worker { } private void addMarkAsReadAction(NotificationCompat.Builder notificationBuilder, int systemNotificationId) { - String label = context.getResources().getString(R.string.nc_mark_as_read); + if (decryptedPushMessage.getObjectId() != null) { + try { + int messageId = parseMessageId(decryptedPushMessage.getObjectId()); - // TODO - improve parsing when server returns unexpected objectId - int messageId = Integer.parseInt(decryptedPushMessage.getObjectId().split("/")[1]); + // Build a PendingIntent for the mark as read action + PendingIntent pendingIntent = buildIntentForAction(MarkAsReadReceiver.class, + systemNotificationId, + messageId); - // Build a PendingIntent for the mark as read action - PendingIntent pendingIntent = buildIntentForAction(MarkAsReadReceiver.class, systemNotificationId, messageId); + NotificationCompat.Action action = + new NotificationCompat.Action.Builder(R.drawable.ic_eye, + context.getResources().getString(R.string.nc_mark_as_read), + pendingIntent) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ) + .setShowsUserInterface(false) + .build(); - NotificationCompat.Action action = - new NotificationCompat.Action.Builder(R.drawable.ic_eye, label, pendingIntent) - .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ) - .setShowsUserInterface(false) - .build(); - - notificationBuilder.addAction(action); + notificationBuilder.addAction(action); + } catch (NumberFormatException nfe) { + Log.e(TAG, "Failed to parse messageId from objectId, skip adding mark-as-read action.", nfe); + } + } } @RequiresApi(api = Build.VERSION_CODES.N) @@ -489,13 +502,25 @@ public class NotificationWorker extends Worker { newStyle.setGroupConversation(!conversationType.equals("one2one")); if (style != null) { - style.getMessages().forEach(message -> newStyle.addMessage(new MessagingStyle.Message(message.getText(), message.getTimestamp(), message.getPerson()))); + style.getMessages().forEach(message -> newStyle.addMessage( + new MessagingStyle.Message(message.getText(), + message.getTimestamp(), + message.getPerson()))); } newStyle.addMessage(decryptedPushMessage.getText(), decryptedPushMessage.getTimestamp(), person); return newStyle; } + private int parseMessageId(@NonNull String objectId) throws NumberFormatException { + String[] objectIdParts = objectId.split("/"); + if (objectIdParts.length < 2) { + throw new NumberFormatException("Invalid objectId, doesn't contain at least one '/'"); + } else { + return Integer.parseInt(objectIdParts[1]); + } + } + private void sendNotification(int notificationId, Notification notification) { NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); notificationManager.notify(notificationId, notification); @@ -564,12 +589,20 @@ public class NotificationWorker extends Worker { decryptedPushMessage.setTimestamp(System.currentTimeMillis()); if (decryptedPushMessage.getDelete()) { - NotificationUtils.INSTANCE.cancelExistingNotificationWithId(context, signatureVerification.getUserEntity(), decryptedPushMessage.getNotificationId()); + NotificationUtils.INSTANCE.cancelExistingNotificationWithId( + context, + signatureVerification.getUserEntity(), + decryptedPushMessage.getNotificationId()); } else if (decryptedPushMessage.getDeleteAll()) { - NotificationUtils.INSTANCE.cancelAllNotificationsForAccount(context, signatureVerification.getUserEntity()); + NotificationUtils.INSTANCE.cancelAllNotificationsForAccount( + context, + signatureVerification.getUserEntity()); } else if (decryptedPushMessage.getDeleteMultiple()) { for (long notificationId : decryptedPushMessage.getNotificationIds()) { - NotificationUtils.INSTANCE.cancelExistingNotificationWithId(context, signatureVerification.getUserEntity(), notificationId); + NotificationUtils.INSTANCE.cancelExistingNotificationWithId( + context, + signatureVerification.getUserEntity(), + notificationId); } } else { credentials = ApiUtils.getCredentials(signatureVerification.getUserEntity().getUsername(), @@ -596,7 +629,8 @@ public class NotificationWorker extends Worker { bundle.putString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), decryptedPushMessage.getId()); - bundle.putParcelable(BundleKeys.INSTANCE.getKEY_USER_ENTITY(), signatureVerification.getUserEntity()); + bundle.putParcelable(BundleKeys.INSTANCE.getKEY_USER_ENTITY(), + signatureVerification.getUserEntity()); bundle.putBoolean(BundleKeys.INSTANCE.getKEY_FROM_NOTIFICATION_START_CALL(), startACall); From 97ea95c30fdfe3a2a72b3e6b5a6015b09404b8a2 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Mon, 11 Jul 2022 21:46:54 +0200 Subject: [PATCH 6/8] Mark as read - SpotBugs Signed-off-by: Dariusz Olszewski --- .../com/nextcloud/talk/jobs/NotificationWorker.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java index 4f53ad220..c94fe9247 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java @@ -499,7 +499,7 @@ public class NotificationWorker extends Worker { MessagingStyle newStyle = new MessagingStyle(person); newStyle.setConversationTitle(decryptedPushMessage.getSubject()); - newStyle.setGroupConversation(!conversationType.equals("one2one")); + newStyle.setGroupConversation(!"one2one".equals(conversationType)); if (style != null) { style.getMessages().forEach(message -> newStyle.addMessage( @@ -512,7 +512,7 @@ public class NotificationWorker extends Worker { return newStyle; } - private int parseMessageId(@NonNull String objectId) throws NumberFormatException { + private int parseMessageId(@NonNull String objectId) { String[] objectIdParts = objectId.split("/"); if (objectIdParts.length < 2) { throw new NumberFormatException("Invalid objectId, doesn't contain at least one '/'"); @@ -531,7 +531,7 @@ public class NotificationWorker extends Worker { return; } - if (!notification.category.equals(Notification.CATEGORY_CALL) || !muteCall) { + if (!Notification.CATEGORY_CALL.equals(notification.category) || !muteCall) { Uri soundUri = NotificationUtils.INSTANCE.getMessageRingtoneUri(context, appPreferences); if (soundUri != null && !ApplicationWideCurrentRoomHolder.getInstance().isInCall() && (DoNotDisturbUtils.INSTANCE.shouldPlaySound() || importantConversation)) { @@ -611,14 +611,14 @@ public class NotificationWorker extends Worker { ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(new JavaNetCookieJar(new CookieManager())).build()).build().create(NcApi.class); - boolean shouldShowNotification = decryptedPushMessage.getApp().equals("spreed"); + boolean shouldShowNotification = "spreed".equals(decryptedPushMessage.getApp()); if (shouldShowNotification) { Intent intent; Bundle bundle = new Bundle(); - boolean startACall = decryptedPushMessage.getType().equals("call"); + boolean startACall = "call".equals(decryptedPushMessage.getType()); if (startACall) { intent = new Intent(context, CallActivity.class); } else { From f5fce7c9c965578bc5afffe79b447c3a6836be0d Mon Sep 17 00:00:00 2001 From: drone Date: Mon, 11 Jul 2022 19:52:47 +0000 Subject: [PATCH 7/8] Drone: update FindBugs results to reflect reduced error/warning count [skip ci] Signed-off-by: drone --- scripts/analysis/findbugs-results.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/analysis/findbugs-results.txt b/scripts/analysis/findbugs-results.txt index 09df92759..05b9b66ff 100644 --- a/scripts/analysis/findbugs-results.txt +++ b/scripts/analysis/findbugs-results.txt @@ -1 +1 @@ -166 \ No newline at end of file +162 \ No newline at end of file From dafa1bfb2e7ce9887ef66f5b487db2f2b5b05b05 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Mon, 11 Jul 2022 22:06:08 +0200 Subject: [PATCH 8/8] Mark as read - reduce scope of try/catch NumberFormatException is expected only inside parseMessageId. To avoid masking other errors accidentally, seems better to have try/catch only around parseMessageId call. Signed-off-by: Dariusz Olszewski --- .../talk/jobs/NotificationWorker.java | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java index c94fe9247..4491edd13 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java @@ -446,26 +446,28 @@ public class NotificationWorker extends Worker { private void addMarkAsReadAction(NotificationCompat.Builder notificationBuilder, int systemNotificationId) { if (decryptedPushMessage.getObjectId() != null) { + int messageId = 0; try { - int messageId = parseMessageId(decryptedPushMessage.getObjectId()); - - // Build a PendingIntent for the mark as read action - PendingIntent pendingIntent = buildIntentForAction(MarkAsReadReceiver.class, - systemNotificationId, - messageId); - - NotificationCompat.Action action = - new NotificationCompat.Action.Builder(R.drawable.ic_eye, - context.getResources().getString(R.string.nc_mark_as_read), - pendingIntent) - .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ) - .setShowsUserInterface(false) - .build(); - - notificationBuilder.addAction(action); + messageId = parseMessageId(decryptedPushMessage.getObjectId()); } catch (NumberFormatException nfe) { Log.e(TAG, "Failed to parse messageId from objectId, skip adding mark-as-read action.", nfe); + return; } + + // Build a PendingIntent for the mark as read action + PendingIntent pendingIntent = buildIntentForAction(MarkAsReadReceiver.class, + systemNotificationId, + messageId); + + NotificationCompat.Action action = + new NotificationCompat.Action.Builder(R.drawable.ic_eye, + context.getResources().getString(R.string.nc_mark_as_read), + pendingIntent) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ) + .setShowsUserInterface(false) + .build(); + + notificationBuilder.addAction(action); } }