Create PendingIntentFactory
This commit is contained in:
parent
0677b10de3
commit
4c10c8fdf9
6 changed files with 117 additions and 84 deletions
|
|
@ -24,9 +24,7 @@ import android.app.Activity
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
|
|
@ -40,37 +38,31 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import io.element.android.libraries.androidutils.system.startNotificationChannelSettingsIntent
|
import io.element.android.libraries.androidutils.system.startNotificationChannelSettingsIntent
|
||||||
import io.element.android.libraries.androidutils.uri.createIgnoredUri
|
|
||||||
import io.element.android.libraries.core.meta.BuildMeta
|
import io.element.android.libraries.core.meta.BuildMeta
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.di.ApplicationContext
|
import io.element.android.libraries.di.ApplicationContext
|
||||||
import io.element.android.libraries.di.SingleIn
|
import io.element.android.libraries.di.SingleIn
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
import io.element.android.libraries.matrix.api.core.ThreadId
|
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||||
import io.element.android.libraries.push.impl.R
|
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.factories.PendingIntentFactory
|
||||||
import io.element.android.libraries.push.impl.notifications.factories.AcceptInvitationActionFactory
|
import io.element.android.libraries.push.impl.notifications.factories.action.AcceptInvitationActionFactory
|
||||||
import io.element.android.libraries.push.impl.notifications.factories.MarkAsReadActionFactory
|
import io.element.android.libraries.push.impl.notifications.factories.action.MarkAsReadActionFactory
|
||||||
import io.element.android.libraries.push.impl.notifications.factories.QuickReplyActionFactory
|
import io.element.android.libraries.push.impl.notifications.factories.action.QuickReplyActionFactory
|
||||||
import io.element.android.libraries.push.impl.notifications.factories.RejectInvitationActionFactory
|
import io.element.android.libraries.push.impl.notifications.factories.action.RejectInvitationActionFactory
|
||||||
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
|
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
|
||||||
import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiableEvent
|
import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiableEvent
|
||||||
import io.element.android.services.toolbox.api.strings.StringProvider
|
import io.element.android.services.toolbox.api.strings.StringProvider
|
||||||
import io.element.android.services.toolbox.api.systemclock.SystemClock
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
// TODO EAx Split into factories
|
|
||||||
@SingleIn(AppScope::class)
|
@SingleIn(AppScope::class)
|
||||||
class NotificationUtils @Inject constructor(
|
class NotificationUtils @Inject constructor(
|
||||||
@ApplicationContext private val context: Context,
|
@ApplicationContext private val context: Context,
|
||||||
// private val vectorPreferences: VectorPreferences,
|
// private val vectorPreferences: VectorPreferences,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val clock: SystemClock,
|
|
||||||
private val actionIds: NotificationActionIds,
|
|
||||||
private val intentProvider: IntentProvider,
|
|
||||||
private val buildMeta: BuildMeta,
|
private val buildMeta: BuildMeta,
|
||||||
|
private val pendingIntentFactory: PendingIntentFactory,
|
||||||
private val markAsReadActionFactory: MarkAsReadActionFactory,
|
private val markAsReadActionFactory: MarkAsReadActionFactory,
|
||||||
private val quickReplyActionFactory: QuickReplyActionFactory,
|
private val quickReplyActionFactory: QuickReplyActionFactory,
|
||||||
private val rejectInvitationActionFactory: RejectInvitationActionFactory,
|
private val rejectInvitationActionFactory: RejectInvitationActionFactory,
|
||||||
|
|
@ -237,9 +229,9 @@ class NotificationUtils @Inject constructor(
|
||||||
threadId != null &&
|
threadId != null &&
|
||||||
true
|
true
|
||||||
/** TODO EAx vectorPreferences.areThreadMessagesEnabled() */
|
/** TODO EAx vectorPreferences.areThreadMessagesEnabled() */
|
||||||
-> buildOpenThreadIntent(roomInfo, threadId)
|
-> pendingIntentFactory.createOpenThreadPendingIntent(roomInfo, threadId)
|
||||||
|
|
||||||
else -> buildOpenRoomIntent(roomInfo.sessionId, roomInfo.roomId)
|
else -> pendingIntentFactory.createOpenRoomPendingIntent(roomInfo.sessionId, roomInfo.roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
val smallIcon = R.drawable.ic_notification
|
val smallIcon = R.drawable.ic_notification
|
||||||
|
|
@ -306,7 +298,7 @@ class NotificationUtils @Inject constructor(
|
||||||
if (largeIcon != null) {
|
if (largeIcon != null) {
|
||||||
setLargeIcon(largeIcon)
|
setLargeIcon(largeIcon)
|
||||||
}
|
}
|
||||||
setDeleteIntent(getDismissRoomPendingIntent(roomInfo.sessionId, roomInfo.roomId))
|
setDeleteIntent(pendingIntentFactory.createDismissRoomPendingIntent(roomInfo.sessionId, roomInfo.roomId))
|
||||||
}
|
}
|
||||||
.setTicker(tickerText)
|
.setTicker(tickerText)
|
||||||
.build()
|
.build()
|
||||||
|
|
@ -351,7 +343,6 @@ class NotificationUtils @Inject constructor(
|
||||||
vectorPreferences.getNotificationRingTone()?.let {
|
vectorPreferences.getNotificationRingTone()?.let {
|
||||||
setSound(it)
|
setSound(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
setLights(accentColor, 500, 500)
|
setLights(accentColor, 500, 500)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -379,7 +370,7 @@ class NotificationUtils @Inject constructor(
|
||||||
.setSmallIcon(smallIcon)
|
.setSmallIcon(smallIcon)
|
||||||
.setColor(accentColor)
|
.setColor(accentColor)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setContentIntent(buildOpenRoomIntent(simpleNotifiableEvent.sessionId, simpleNotifiableEvent.roomId))
|
.setContentIntent(pendingIntentFactory.createOpenRoomPendingIntent(simpleNotifiableEvent.sessionId, simpleNotifiableEvent.roomId))
|
||||||
.apply {
|
.apply {
|
||||||
if (simpleNotifiableEvent.noisy) {
|
if (simpleNotifiableEvent.noisy) {
|
||||||
// Compat
|
// Compat
|
||||||
|
|
@ -388,7 +379,6 @@ class NotificationUtils @Inject constructor(
|
||||||
vectorPreferences.getNotificationRingTone()?.let {
|
vectorPreferences.getNotificationRingTone()?.let {
|
||||||
setSound(it)
|
setSound(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
setLights(accentColor, 500, 500)
|
setLights(accentColor, 500, 500)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -399,28 +389,6 @@ class NotificationUtils @Inject constructor(
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildOpenSessionIntent(sessionId: SessionId): PendingIntent? {
|
|
||||||
return getPendingIntent(sessionId = sessionId, roomId = null, threadId = null)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildOpenRoomIntent(sessionId: SessionId, roomId: RoomId): PendingIntent? {
|
|
||||||
return getPendingIntent(sessionId = sessionId, roomId = roomId, threadId = null)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildOpenThreadIntent(roomInfo: RoomEventGroupInfo, threadId: ThreadId?): PendingIntent? {
|
|
||||||
return getPendingIntent(sessionId = roomInfo.sessionId, roomId = roomInfo.roomId, threadId = threadId)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPendingIntent(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): PendingIntent? {
|
|
||||||
val intent = intentProvider.getViewIntent(sessionId = sessionId, roomId = roomId, threadId = threadId)
|
|
||||||
return PendingIntent.getActivity(
|
|
||||||
context,
|
|
||||||
clock.epochMillis().toInt(),
|
|
||||||
intent,
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the summary notification.
|
* Build the summary notification.
|
||||||
*/
|
*/
|
||||||
|
|
@ -463,38 +431,11 @@ class NotificationUtils @Inject constructor(
|
||||||
priority = NotificationCompat.PRIORITY_LOW
|
priority = NotificationCompat.PRIORITY_LOW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.setContentIntent(buildOpenSessionIntent(sessionId))
|
.setContentIntent(pendingIntentFactory.createOpenSessionPendingIntent(sessionId))
|
||||||
.setDeleteIntent(getDismissSummaryPendingIntent(sessionId))
|
.setDeleteIntent(pendingIntentFactory.createDismissSummaryPendingIntent(sessionId))
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDismissSummaryPendingIntent(sessionId: SessionId): PendingIntent {
|
|
||||||
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
|
||||||
intent.action = actionIds.dismissSummary
|
|
||||||
intent.data = createIgnoredUri("deleteSummary?${sessionId.value}")
|
|
||||||
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId)
|
|
||||||
return PendingIntent.getBroadcast(
|
|
||||||
context,
|
|
||||||
0,
|
|
||||||
intent,
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getDismissRoomPendingIntent(sessionId: SessionId, roomId: RoomId): PendingIntent {
|
|
||||||
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
|
||||||
intent.action = actionIds.dismissRoom
|
|
||||||
intent.data = createIgnoredUri("deleteRoom?${sessionId.value}&${roomId.value}")
|
|
||||||
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId)
|
|
||||||
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
|
|
||||||
return PendingIntent.getBroadcast(
|
|
||||||
context,
|
|
||||||
clock.epochMillis().toInt(),
|
|
||||||
intent,
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel the foreground notification service.
|
* Cancel the foreground notification service.
|
||||||
*/
|
*/
|
||||||
|
|
@ -520,14 +461,6 @@ class NotificationUtils @Inject constructor(
|
||||||
Timber.w("Not allowed to notify.")
|
Timber.w("Not allowed to notify.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val testActionIntent = Intent(context, TestNotificationReceiver::class.java)
|
|
||||||
testActionIntent.action = actionIds.diagnostic
|
|
||||||
val testPendingIntent = PendingIntent.getBroadcast(
|
|
||||||
context,
|
|
||||||
0,
|
|
||||||
testActionIntent,
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
||||||
)
|
|
||||||
notificationManager.notify(
|
notificationManager.notify(
|
||||||
"DIAGNOSTIC",
|
"DIAGNOSTIC",
|
||||||
888,
|
888,
|
||||||
|
|
@ -540,7 +473,7 @@ class NotificationUtils @Inject constructor(
|
||||||
.setPriority(NotificationCompat.PRIORITY_MAX)
|
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||||
.setCategory(NotificationCompat.CATEGORY_STATUS)
|
.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setContentIntent(testPendingIntent)
|
.setContentIntent(pendingIntentFactory.createTestPendingIntent())
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* 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.notifications.factories
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import io.element.android.libraries.androidutils.uri.createIgnoredUri
|
||||||
|
import io.element.android.libraries.di.ApplicationContext
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||||
|
import io.element.android.libraries.push.impl.intent.IntentProvider
|
||||||
|
import io.element.android.libraries.push.impl.notifications.NotificationActionIds
|
||||||
|
import io.element.android.libraries.push.impl.notifications.NotificationBroadcastReceiver
|
||||||
|
import io.element.android.libraries.push.impl.notifications.RoomEventGroupInfo
|
||||||
|
import io.element.android.libraries.push.impl.notifications.TestNotificationReceiver
|
||||||
|
import io.element.android.services.toolbox.api.systemclock.SystemClock
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class PendingIntentFactory @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
|
private val intentProvider: IntentProvider,
|
||||||
|
private val clock: SystemClock,
|
||||||
|
private val actionIds: NotificationActionIds,
|
||||||
|
) {
|
||||||
|
fun createOpenSessionPendingIntent(sessionId: SessionId): PendingIntent? {
|
||||||
|
return createPendingIntent(sessionId = sessionId, roomId = null, threadId = null)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createOpenRoomPendingIntent(sessionId: SessionId, roomId: RoomId): PendingIntent? {
|
||||||
|
return createPendingIntent(sessionId = sessionId, roomId = roomId, threadId = null)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createOpenThreadPendingIntent(roomInfo: RoomEventGroupInfo, threadId: ThreadId?): PendingIntent? {
|
||||||
|
return createPendingIntent(sessionId = roomInfo.sessionId, roomId = roomInfo.roomId, threadId = threadId)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createPendingIntent(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): PendingIntent? {
|
||||||
|
val intent = intentProvider.getViewIntent(sessionId = sessionId, roomId = roomId, threadId = threadId)
|
||||||
|
return PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
clock.epochMillis().toInt(),
|
||||||
|
intent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createDismissSummaryPendingIntent(sessionId: SessionId): PendingIntent {
|
||||||
|
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||||
|
intent.action = actionIds.dismissSummary
|
||||||
|
intent.data = createIgnoredUri("deleteSummary?${sessionId.value}")
|
||||||
|
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId)
|
||||||
|
return PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
intent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createDismissRoomPendingIntent(sessionId: SessionId, roomId: RoomId): PendingIntent {
|
||||||
|
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
|
||||||
|
intent.action = actionIds.dismissRoom
|
||||||
|
intent.data = createIgnoredUri("deleteRoom?${sessionId.value}&${roomId.value}")
|
||||||
|
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId)
|
||||||
|
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId)
|
||||||
|
return PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
clock.epochMillis().toInt(),
|
||||||
|
intent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createTestPendingIntent(): PendingIntent? {
|
||||||
|
val testActionIntent = Intent(context, TestNotificationReceiver::class.java)
|
||||||
|
testActionIntent.action = actionIds.diagnostic
|
||||||
|
return PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
testActionIntent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.notifications.factories
|
package io.element.android.libraries.push.impl.notifications.factories.action
|
||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.notifications.factories
|
package io.element.android.libraries.push.impl.notifications.factories.action
|
||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.notifications.factories
|
package io.element.android.libraries.push.impl.notifications.factories.action
|
||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.push.impl.notifications.factories
|
package io.element.android.libraries.push.impl.notifications.factories.action
|
||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
Loading…
Add table
Add a link
Reference in a new issue