From 0f3662cd82c5b47451c9357bec92671887a5264f Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Fri, 24 Feb 2023 12:32:27 +0100 Subject: [PATCH] restrict deletion of "Recording available" notification ...for preparation to replace Dialog that was openend in ChatController. It will be replaced by Notification Actions. The dialog was not opened when already being in a chat, because remapChatController only moved the currentChatController to top so to won't be initialized again. That's why the dialog didn't pop up for this case. As a solution, the actions should be available directly inside the notification. For this, it must be avoided that the "recording available" notification is closed whenever the chat is opened. Signed-off-by: Marcel Hibbe --- .../nextcloud/talk/jobs/NotificationWorker.kt | 125 +++++++++++++----- .../nextcloud/talk/utils/NotificationUtils.kt | 4 +- .../nextcloud/talk/utils/bundle/BundleKeys.kt | 1 + 3 files changed, 98 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt index 3c595aac2..4be297f76 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt @@ -85,6 +85,7 @@ 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_NOTIFICATION_ID import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_RECORDING_NOTIFICATION +import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_RESTRICT_DELETION import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_TIMESTAMP import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SYSTEM_NOTIFICATION_ID @@ -413,44 +414,17 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor } else { pushMessage.subject = ncNotification.subject.orEmpty() } - - if ("recording" == ncNotification.objectType) { - conversationType = "recording" - } } @Suppress("MagicNumber") private fun showNotification(intent: Intent) { - val largeIcon: Bitmap - val priority = NotificationCompat.PRIORITY_HIGH - val smallIcon: Int = R.drawable.ic_logo - - var category: String = "" + var category = "" when (pushMessage.type) { TYPE_CHAT, TYPE_ROOM, TYPE_RECORDING -> category = Notification.CATEGORY_MESSAGE TYPE_CALL -> category = Notification.CATEGORY_CALL else -> Log.e(TAG, "unknown pushMessage.type") } - when (conversationType) { - "recording" -> { - largeIcon = ContextCompat.getDrawable(context!!, R.drawable.ic_baseline_videocam_24)?.toBitmap()!! - } - "one2one" -> { - pushMessage.subject = "" - largeIcon = ContextCompat.getDrawable(context!!, R.drawable.ic_people_group_black_24px)?.toBitmap()!! - } - "group" -> - largeIcon = ContextCompat.getDrawable(context!!, R.drawable.ic_people_group_black_24px)?.toBitmap()!! - "public" -> largeIcon = ContextCompat.getDrawable(context!!, R.drawable.ic_link_black_24px)?.toBitmap()!! - else -> // assuming one2one - largeIcon = if (TYPE_CHAT == pushMessage.type || TYPE_ROOM == pushMessage.type) { - ContextCompat.getDrawable(context!!, R.drawable.ic_comment)?.toBitmap()!! - } else { - ContextCompat.getDrawable(context!!, R.drawable.ic_call_black_24dp)?.toBitmap()!! - } - } - // Use unique request code to make sure that a new PendingIntent gets created for each notification // See https://github.com/nextcloud/talk-android/issues/2111 val requestCode = System.currentTimeMillis().toInt() @@ -474,10 +448,10 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor } val notificationBuilder = NotificationCompat.Builder(context!!, "1") - .setLargeIcon(largeIcon) - .setSmallIcon(smallIcon) + .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(category) - .setPriority(priority) + .setLargeIcon(getLargeIcon()) + .setSmallIcon(R.drawable.ic_logo) .setContentTitle(contentTitle) .setContentText(contentText) .setSubText(baseUrl) @@ -492,6 +466,11 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor // could be an ID or a TOKEN notificationInfoBundle.putString(KEY_ROOM_TOKEN, pushMessage.id) notificationInfoBundle.putLong(KEY_NOTIFICATION_ID, pushMessage.notificationId!!) + + if (pushMessage.type == TYPE_RECORDING) { + notificationInfoBundle.putBoolean(KEY_NOTIFICATION_RESTRICT_DELETION, true) + } + notificationBuilder.setExtras(notificationInfoBundle) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -530,6 +509,15 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor addMarkAsReadAction(notificationBuilder, systemNotificationId) } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && + TYPE_RECORDING == pushMessage.type && + pushMessage.notificationUser != null + ) { + prepareChatNotification(notificationBuilder, activeStatusBarNotification, systemNotificationId) + // addDiscardRecordingAvailableAction(notificationBuilder, systemNotificationId) + // addShareRecordingToChatAction(notificationBuilder, systemNotificationId) + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && TYPE_RECORDING == pushMessage.type && pushMessage.notificationUser != null // null @@ -539,6 +527,34 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor sendNotification(systemNotificationId, notificationBuilder.build()) } + private fun getLargeIcon(): Bitmap { + val largeIcon: Bitmap + if (pushMessage.type == "recording") { + largeIcon = ContextCompat.getDrawable(context!!, R.drawable.ic_baseline_videocam_24)?.toBitmap()!! + } else { + when (conversationType) { + "one2one" -> { + pushMessage.subject = "" + largeIcon = + ContextCompat.getDrawable(context!!, R.drawable.ic_people_group_black_24px)?.toBitmap()!! + } + "group" -> + largeIcon = + ContextCompat.getDrawable(context!!, R.drawable.ic_people_group_black_24px)?.toBitmap()!! + "public" -> + largeIcon = + ContextCompat.getDrawable(context!!, R.drawable.ic_link_black_24px)?.toBitmap()!! + else -> // assuming one2one + largeIcon = if (TYPE_CHAT == pushMessage.type || TYPE_ROOM == pushMessage.type) { + ContextCompat.getDrawable(context!!, R.drawable.ic_comment)?.toBitmap()!! + } else { + ContextCompat.getDrawable(context!!, R.drawable.ic_call_black_24dp)?.toBitmap()!! + } + } + } + return largeIcon + } + private fun calculateCRC32(s: String): Long { val crc32 = CRC32() crc32.update(s.toByteArray()) @@ -646,6 +662,51 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor notificationBuilder.addAction(replyAction) } + // @RequiresApi(api = Build.VERSION_CODES.N) + // private fun addDiscardRecordingAvailableAction(notificationBuilder: NotificationCompat.Builder, + // systemNotificationId: + // Int) { + // val replyLabel = context!!.resources.getString(R.string.nc_reply) + // val remoteInput = RemoteInput.Builder(NotificationUtils.KEY_DIRECT_REPLY) + // .setLabel(replyLabel) + // .build() + // + // val replyPendingIntent = buildIntentForAction( + // DirectReplyReceiver::class.java, + // systemNotificationId, + // 0 + // ) + // val replyAction = NotificationCompat.Action.Builder(R.drawable.ic_reply, replyLabel, replyPendingIntent) + // .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY) + // .setShowsUserInterface(false) + // .setAllowGeneratedReplies(true) + // .addRemoteInput(remoteInput) + // .build() + // notificationBuilder.addAction(replyAction) + // } + // + // @RequiresApi(api = Build.VERSION_CODES.N) + // private fun addShareRecordingToChatAction(notificationBuilder: NotificationCompat.Builder, systemNotificationId: + // Int) { + // val replyLabel = context!!.resources.getString(R.string.nc_reply) + // val remoteInput = RemoteInput.Builder(NotificationUtils.KEY_DIRECT_REPLY) + // .setLabel(replyLabel) + // .build() + // + // val replyPendingIntent = buildIntentForAction( + // DirectReplyReceiver::class.java, + // systemNotificationId, + // 0 + // ) + // val replyAction = NotificationCompat.Action.Builder(R.drawable.ic_reply, replyLabel, replyPendingIntent) + // .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY) + // .setShowsUserInterface(false) + // .setAllowGeneratedReplies(true) + // .addRemoteInput(remoteInput) + // .build() + // notificationBuilder.addAction(replyAction) + // } + @RequiresApi(api = Build.VERSION_CODES.N) private fun getStyle(person: Person, style: NotificationCompat.MessagingStyle?): NotificationCompat.MessagingStyle { val newStyle = NotificationCompat.MessagingStyle(person) @@ -860,6 +921,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor }) } } + private fun createMainActivityIntent(): Intent { val intent = Intent(context, MainActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK @@ -870,6 +932,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor intent.putExtras(bundle) return intent } + private fun getIntentToOpenConversation(): PendingIntent? { val intent = Intent(context, MainActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK diff --git a/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.kt index c2745cd51..a5682d959 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.kt @@ -267,7 +267,9 @@ object NotificationUtils { fun cancelExistingNotificationsForRoom(context: Context?, conversationUser: User, roomTokenOrId: String) { scanNotifications(context, conversationUser) { notificationManager, statusBarNotification, notification -> - if (roomTokenOrId == notification.extras.getString(BundleKeys.KEY_ROOM_TOKEN)) { + if (roomTokenOrId == notification.extras.getString(BundleKeys.KEY_ROOM_TOKEN) && + !notification.extras.getBoolean(BundleKeys.KEY_NOTIFICATION_RESTRICT_DELETION) + ) { notificationManager.cancel(statusBarNotification.id) } } diff --git a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt index 6083f3001..63c740bc8 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt @@ -83,4 +83,5 @@ object BundleKeys { const val KEY_SWITCH_TO_ROOM_AND_START_CALL = "KEY_SWITCH_TO_ROOM_AND_START_CALL" const val KEY_IS_BREAKOUT_ROOM = "KEY_IS_BREAKOUT_ROOM" const val KEY_NOTIFICATION_RECORDING_NOTIFICATION = "KEY_NOTIFICATION_RECORDING_NOTIFICATION" + const val KEY_NOTIFICATION_RESTRICT_DELETION = "KEY_NOTIFICATION_RESTRICT_DELETION" }