From afbd4672e6381680f215de1d67bb1a4e7de274c8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 30 Mar 2023 14:18:23 +0200 Subject: [PATCH] Show basic notification when push is recieve --- .../android/x/intent/IntentProviderImpl.kt | 36 +++++++++++++++++++ .../libraries/push/impl/PushersManager.kt | 4 +-- .../libraries/push/impl/VectorPushHandler.kt | 3 ++ .../push/impl/intent/IntentProvider.kt | 26 ++++++++++++++ .../notifications/NotificationDisplayer.kt | 14 ++++++-- .../NotificationDrawerManager.kt | 10 ++++-- .../impl/notifications/NotificationFactory.kt | 4 +++ .../notifications/NotificationRenderer.kt | 9 +++++ .../impl/notifications/NotificationUtils.kt | 33 ++++++++++++----- .../impl/src/main/res/values/temporary.xml | 1 + 10 files changed, 124 insertions(+), 16 deletions(-) create mode 100644 app/src/main/kotlin/io/element/android/x/intent/IntentProviderImpl.kt create mode 100644 libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt diff --git a/app/src/main/kotlin/io/element/android/x/intent/IntentProviderImpl.kt b/app/src/main/kotlin/io/element/android/x/intent/IntentProviderImpl.kt new file mode 100644 index 0000000000..f7b96f3aad --- /dev/null +++ b/app/src/main/kotlin/io/element/android/x/intent/IntentProviderImpl.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.x.intent + +import android.content.Context +import android.content.Intent +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.di.ApplicationContext +import io.element.android.libraries.push.impl.intent.IntentProvider +import io.element.android.x.MainActivity +import javax.inject.Inject + +// TODO EAx change to deep-link. +@ContributesBinding(AppScope::class) +class IntentProviderImpl @Inject constructor( + @ApplicationContext private val context: Context, +) : IntentProvider { + override fun getMainIntent(): Intent { + return Intent(context, MainActivity::class.java) + } +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/PushersManager.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/PushersManager.kt index 8a713585b6..b4952f35b4 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/PushersManager.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/PushersManager.kt @@ -67,7 +67,7 @@ class PushersManager @Inject constructor( val client = matrixAuthenticationService.restoreSession(SessionId(sessionData.userId)).getOrNull() client ?: return@forEach client.pushersService().setHttpPusher(createHttpPusher(pushKey, gateway, sessionData.userId)) - // Close sessions? + // TODO EAx Close sessions } } @@ -76,7 +76,7 @@ class PushersManager @Inject constructor( // Register the pusher for the session val client = matrixAuthenticationService.restoreSession(userId).getOrNull() ?: return client.pushersService().setHttpPusher(createHttpPusher(pushKey, PushConfig.pusher_http_url, userId.value)) - // Close sessions? + // TODO EAx Close sessions } private suspend fun createHttpPusher( diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/VectorPushHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/VectorPushHandler.kt index f6a4b5d83d..0357e40a0a 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/VectorPushHandler.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/VectorPushHandler.kt @@ -142,9 +142,12 @@ class VectorPushHandler @Inject constructor( eventId = pushData.eventId, ) + // TODO Remove Timber.w("Notification: $notificationData") // TODO Display notification + notificationDrawerManager.displayTemporaryNotification() + /* TODO EAx - get the event - display the notif diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt new file mode 100644 index 0000000000..936ccfcbde --- /dev/null +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.push.impl.intent + +import android.content.Intent + +interface IntentProvider { + /** + * Provide an intent to start the application + */ + fun getMainIntent(): Intent +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDisplayer.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDisplayer.kt index 7f9ec73343..838356b370 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDisplayer.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDisplayer.kt @@ -16,20 +16,28 @@ package io.element.android.libraries.push.impl.notifications +import android.Manifest import android.app.Notification import android.content.Context +import android.content.pm.PackageManager +import androidx.core.app.ActivityCompat import androidx.core.app.NotificationManagerCompat import io.element.android.libraries.di.ApplicationContext import timber.log.Timber import javax.inject.Inject -class NotificationDisplayer @Inject constructor( - @ApplicationContext context: Context, -) { +const val TEMPORARY_ID = 101 +class NotificationDisplayer @Inject constructor( + @ApplicationContext private val context: Context, +) { private val notificationManager = NotificationManagerCompat.from(context) fun showNotificationMessage(tag: String?, id: Int, notification: Notification) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { + Timber.w("Not allowed to notify.") + return + } notificationManager.notify(tag, id, notification) } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDrawerManager.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDrawerManager.kt index c40680a1fd..1bf3e68f7f 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDrawerManager.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDrawerManager.kt @@ -41,7 +41,6 @@ import javax.inject.Inject @SingleIn(AppScope::class) class NotificationDrawerManager @Inject constructor( @ApplicationContext context: Context, - private val notificationDisplayer: NotificationDisplayer, private val pushDataStore: PushDataStore, // private val activeSessionDataSource: ActiveSessionDataSource, private val notifiableEventProcessor: NotifiableEventProcessor, @@ -154,7 +153,7 @@ class NotificationDrawerManager @Inject constructor( val newSettings = pushDataStore.useCompleteNotificationFormat() if (newSettings != useCompleteNotificationFormat) { // Settings has changed, remove all current notifications - notificationDisplayer.cancelAllNotifications() + notificationRenderer.cancelAllNotifications() useCompleteNotificationFormat = newSettings } } @@ -232,6 +231,13 @@ class NotificationDrawerManager @Inject constructor( return resolvedEvent.shouldIgnoreMessageEventInRoom(currentRoomId, currentThreadId) } + /** + * Temporary notification for EAx + */ + fun displayTemporaryNotification() { + notificationRenderer.displayTemporaryNotification() + } + companion object { const val SUMMARY_NOTIFICATION_ID = 0 const val ROOM_MESSAGES_NOTIFICATION_ID = 1 diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationFactory.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationFactory.kt index f935a36366..5a3f008963 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationFactory.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationFactory.kt @@ -105,6 +105,10 @@ class NotificationFactory @Inject constructor( ) } } + + fun createTemporaryNotification(): Notification { + return notificationUtils.createTemporaryNotification() + } } sealed interface RoomNotification { diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt index 8b5fa70365..e0fc44cca0 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt @@ -104,6 +104,15 @@ class NotificationRenderer @Inject constructor( } } } + + fun cancelAllNotifications() { + notificationDisplayer.cancelAllNotifications() + } + + fun displayTemporaryNotification() { + val notification = notificationFactory.createTemporaryNotification() + notificationDisplayer.showNotificationMessage(null, TEMPORARY_ID, notification) + } } private fun List>.groupByType(): GroupedNotificationEvents { diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationUtils.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationUtils.kt index bfa80908bf..3fce6e0d84 100755 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationUtils.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationUtils.kt @@ -45,6 +45,7 @@ import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.di.SingleIn import io.element.android.libraries.push.impl.R +import io.element.android.libraries.push.impl.intent.IntentProvider import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiableEvent import io.element.android.services.toolbox.api.strings.StringProvider @@ -61,6 +62,7 @@ class NotificationUtils @Inject constructor( private val stringProvider: StringProvider, private val clock: SystemClock, private val actionIds: NotificationActionIds, + private val intentProvider: IntentProvider, private val buildMeta: BuildMeta, ) { @@ -107,6 +109,10 @@ class NotificationUtils @Inject constructor( private val notificationManager = NotificationManagerCompat.from(context) + init { + createNotificationChannels() + } + /* ========================================================================================== * Channel names * ========================================================================================== */ @@ -114,7 +120,7 @@ class NotificationUtils @Inject constructor( /** * Create notification channels. */ - fun createNotificationChannels() { + private fun createNotificationChannels() { if (!supportNotificationChannels()) { return } @@ -650,14 +656,6 @@ class NotificationUtils @Inject constructor( ) } - fun showNotificationMessage(tag: String?, id: Int, notification: Notification) { - notificationManager.notify(tag, id, notification) - } - - fun cancelNotificationMessage(tag: String?, id: Int) { - notificationManager.cancel(tag, id) - } - /** * Cancel the foreground notification service. */ @@ -705,6 +703,23 @@ class NotificationUtils @Inject constructor( ) } + fun createTemporaryNotification(): Notification { + val contentIntent = intentProvider.getMainIntent() + val pendingIntent = PendingIntent.getActivity(context, 0, contentIntent, PendingIntentCompat.FLAG_IMMUTABLE) + + return NotificationCompat.Builder(context, NOISY_NOTIFICATION_CHANNEL_ID) + .setContentTitle(buildMeta.applicationName) + .setContentText(stringProvider.getString(R.string.notification_new_messages_temporary)) + .setSmallIcon(R.drawable.ic_notification) + .setLargeIcon(getBitmap(context, R.drawable.element_logo_green)) + .setColor(ContextCompat.getColor(context, R.color.notification_accent_color)) + .setPriority(NotificationCompat.PRIORITY_MAX) + .setCategory(NotificationCompat.CATEGORY_STATUS) + .setAutoCancel(true) + .setContentIntent(pendingIntent) + .build() + } + private fun getBitmap(context: Context, @DrawableRes drawableRes: Int): Bitmap? { val drawable = ResourcesCompat.getDrawable(context.resources, drawableRes, null) ?: return null val canvas = Canvas() diff --git a/libraries/push/impl/src/main/res/values/temporary.xml b/libraries/push/impl/src/main/res/values/temporary.xml index b560669f57..e7b8618cc2 100644 --- a/libraries/push/impl/src/main/res/values/temporary.xml +++ b/libraries/push/impl/src/main/res/values/temporary.xml @@ -25,6 +25,7 @@ Silent notifications Call New Messages + You have new message(s) Mark as read Join Reject