diff --git a/appconfig/build.gradle.kts b/appconfig/build.gradle.kts index e59799d685..17a78cdd3b 100644 --- a/appconfig/build.gradle.kts +++ b/appconfig/build.gradle.kts @@ -28,6 +28,7 @@ anvil { } dependencies { + implementation(libs.androidx.annotationjvm) implementation(libs.dagger) implementation(projects.libraries.di) implementation(projects.libraries.matrix.api) diff --git a/appconfig/src/main/kotlin/io/element/android/appconfig/NotificationConfig.kt b/appconfig/src/main/kotlin/io/element/android/appconfig/NotificationConfig.kt index 9ca4f73314..cca9f8df12 100644 --- a/appconfig/src/main/kotlin/io/element/android/appconfig/NotificationConfig.kt +++ b/appconfig/src/main/kotlin/io/element/android/appconfig/NotificationConfig.kt @@ -16,6 +16,9 @@ package io.element.android.appconfig +import android.graphics.Color +import androidx.annotation.ColorInt + object NotificationConfig { // TODO EAx Implement and set to true at some point const val SUPPORT_MARK_AS_READ_ACTION = false @@ -25,4 +28,7 @@ object NotificationConfig { // TODO EAx Implement and set to true at some point const val SUPPORT_QUICK_REPLY_ACTION = false + + @ColorInt + val NOTIFICATION_ACCENT_COLOR: Int = Color.parseColor("#FF0DBD8B") } diff --git a/changelog.d/3053.misc b/changelog.d/3053.misc new file mode 100644 index 0000000000..6a22cc363a --- /dev/null +++ b/changelog.d/3053.misc @@ -0,0 +1 @@ +Alert for incoming call even if notifications are disabled diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt index 0aace5ea43..a669126e34 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt @@ -42,6 +42,7 @@ open class NotificationSettingsStateProvider : PreviewParameterProvider, ): Notification { - val accentColor = ContextCompat.getColor(context, R.color.notification_accent_color) // Build the pending intent for when the notification is clicked val openIntent = when { threadId != null -> pendingIntentFactory.createOpenThreadPendingIntent(roomInfo, threadId) @@ -228,7 +228,6 @@ class DefaultNotificationCreator @Inject constructor( override fun createRoomInvitationNotification( inviteNotifiableEvent: InviteNotifiableEvent ): Notification { - val accentColor = ContextCompat.getColor(context, R.color.notification_accent_color) val smallIcon = CommonDrawables.ic_notification_small val channelId = notificationChannels.getChannelIdForMessage(inviteNotifiableEvent.noisy) return NotificationCompat.Builder(context, channelId) @@ -273,7 +272,6 @@ class DefaultNotificationCreator @Inject constructor( override fun createSimpleEventNotification( simpleNotifiableEvent: SimpleNotifiableEvent, ): Notification { - val accentColor = ContextCompat.getColor(context, R.color.notification_accent_color) val smallIcon = CommonDrawables.ic_notification_small val channelId = notificationChannels.getChannelIdForMessage(simpleNotifiableEvent.noisy) @@ -307,7 +305,6 @@ class DefaultNotificationCreator @Inject constructor( override fun createFallbackNotification( fallbackNotifiableEvent: FallbackNotifiableEvent, ): Notification { - val accentColor = ContextCompat.getColor(context, R.color.notification_accent_color) val smallIcon = CommonDrawables.ic_notification_small val channelId = notificationChannels.getChannelIdForMessage(false) @@ -344,7 +341,6 @@ class DefaultNotificationCreator @Inject constructor( noisy: Boolean, lastMessageTimestamp: Long ): Notification { - val accentColor = ContextCompat.getColor(context, R.color.notification_accent_color) val smallIcon = CommonDrawables.ic_notification_small val channelId = notificationChannels.getChannelIdForMessage(noisy) return NotificationCompat.Builder(context, channelId) @@ -384,7 +380,7 @@ class DefaultNotificationCreator @Inject constructor( .setContentText(stringProvider.getString(R.string.notification_test_push_notification_content)) .setSmallIcon(CommonDrawables.ic_notification_small) .setLargeIcon(getBitmap(R.drawable.element_logo_green)) - .setColor(ContextCompat.getColor(context, R.color.notification_accent_color)) + .setColor(accentColor) .setPriority(NotificationCompat.PRIORITY_MAX) .setCategory(NotificationCompat.CATEGORY_STATUS) .setAutoCancel(true) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt index fda14f294f..a553c14952 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt @@ -96,17 +96,19 @@ class DefaultPushHandler @Inject constructor( Timber.w("Unable to get a session") return } - val userPushStore = userPushStoreFactory.getOrCreate(userId) - val areNotificationsEnabled = userPushStore.getNotificationEnabledForDevice().first() - if (areNotificationsEnabled) { - val notifiableEvent = notifiableEventResolver.resolveEvent(userId, pushData.roomId, pushData.eventId) - when (notifiableEvent) { - null -> Timber.tag(loggerTag.value).w("Unable to get a notification data") - is NotifiableRingingCallEvent -> handleRingingCallEvent(notifiableEvent) - else -> onNotifiableEventReceived.onNotifiableEventReceived(notifiableEvent) + val notifiableEvent = notifiableEventResolver.resolveEvent(userId, pushData.roomId, pushData.eventId) + when (notifiableEvent) { + null -> Timber.tag(loggerTag.value).w("Unable to get a notification data") + is NotifiableRingingCallEvent -> handleRingingCallEvent(notifiableEvent) + else -> { + val userPushStore = userPushStoreFactory.getOrCreate(userId) + val areNotificationsEnabled = userPushStore.getNotificationEnabledForDevice().first() + if (areNotificationsEnabled) { + onNotifiableEventReceived.onNotifiableEventReceived(notifiableEvent) + } else { + Timber.tag(loggerTag.value).i("Notification are disabled for this device, ignore push.") + } } - } else { - Timber.tag(loggerTag.value).i("Notification are disabled for this device, ignore push.") } } catch (e: Exception) { Timber.tag(loggerTag.value).e(e, "## handleInternal() failed") diff --git a/libraries/push/impl/src/main/res/values/colors.xml b/libraries/push/impl/src/main/res/values/colors.xml deleted file mode 100644 index 64a9d928fb..0000000000 --- a/libraries/push/impl/src/main/res/values/colors.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - #368BD6 - - diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannelsTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannelsTest.kt index ec87069cd2..07eadc099e 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannelsTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/channels/NotificationChannelsTest.kt @@ -16,7 +16,6 @@ package io.element.android.libraries.push.impl.notifications.channels -import android.app.NotificationChannel import android.os.Build import androidx.core.app.NotificationChannelCompat import androidx.core.app.NotificationManagerCompat @@ -43,7 +42,6 @@ class NotificationChannelsTest { createNotificationChannels(notificationManager = notificationManager) verify { notificationManager.createNotificationChannel(any()) } - verify { notificationManager.createNotificationChannel(any()) } verify { notificationManager.deleteNotificationChannel(any()) } } @@ -55,7 +53,7 @@ class NotificationChannelsTest { assertThat(ringingChannel).isEqualTo(RINGING_CALL_NOTIFICATION_CHANNEL_ID) val normalChannel = notificationChannels.getChannelForIncomingCall(ring = false) - assertThat(normalChannel).isEqualTo(CALL_NOTIFICATION_CHANNEL_ID_V3) + assertThat(normalChannel).isEqualTo(CALL_NOTIFICATION_CHANNEL_ID) } @Test diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlerTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlerTest.kt index 9e37aae29d..4953e4d7b4 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlerTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlerTest.kt @@ -118,7 +118,7 @@ class DefaultPushHandlerTest { incrementPushCounterResult.assertions() .isCalledOnce() notifiableEventResult.assertions() - .isNeverCalled() + .isCalledOnce() onNotifiableEventReceived.assertions() .isNeverCalled() } @@ -277,6 +277,34 @@ class DefaultPushHandlerTest { onNotifiableEventReceived.assertions().isCalledOnce() } + @Test + fun `when notify call PushData is received, the incoming call will be treated as a normal notification even if notification are disabled`() = runTest { + val aPushData = PushData( + eventId = AN_EVENT_ID, + roomId = A_ROOM_ID, + unread = 0, + clientSecret = A_SECRET, + ) + val onNotifiableEventReceived = lambdaRecorder {} + val handleIncomingCallLambda = lambdaRecorder { _, _, _, _, _, _, _ -> } + val elementCallEntryPoint = FakeElementCallEntryPoint(handleIncomingCallResult = handleIncomingCallLambda) + val defaultPushHandler = createDefaultPushHandler( + elementCallEntryPoint = elementCallEntryPoint, + onNotifiableEventReceived = onNotifiableEventReceived, + notifiableEventResult = { _, _, _ -> aNotifiableCallEvent() }, + incrementPushCounterResult = {}, + userPushStore = FakeUserPushStore().apply { + setNotificationEnabledForDevice(false) + }, + pushClientSecret = FakePushClientSecret( + getUserIdFromSecretResult = { A_USER_ID } + ), + ) + defaultPushHandler.handle(aPushData) + handleIncomingCallLambda.assertions().isCalledOnce() + onNotifiableEventReceived.assertions().isNeverCalled() + } + @Test fun `when diagnostic PushData is received, the diagnostic push handler is informed `() = runTest { diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.notifications_NotificationSettingsView_null_NotificationSettingsView-Day-6_7_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.notifications_NotificationSettingsView_null_NotificationSettingsView-Day-6_7_null_12,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..c4783027f4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.notifications_NotificationSettingsView_null_NotificationSettingsView-Day-6_7_null_12,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b97743618b94a6f0e9f3e9d1e776f818deafb8e1bfb9671e85497359b2d45a95 +size 15210 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.notifications_NotificationSettingsView_null_NotificationSettingsView-Night-6_8_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.notifications_NotificationSettingsView_null_NotificationSettingsView-Night-6_8_null_12,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..612f5af55b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.notifications_NotificationSettingsView_null_NotificationSettingsView-Night-6_8_null_12,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea1f406cdc673d242f6a8920da2f15316961f9765ddb43e189ef1c057417658a +size 14762