Update incoming call notification content to "📹 Incoming call"
This commit is contained in:
parent
639c1bac00
commit
8edffc5167
14 changed files with 85 additions and 9 deletions
|
|
@ -30,6 +30,7 @@ interface ElementCallEntryPoint {
|
||||||
* @param avatarUrl The avatar url of the room or DM.
|
* @param avatarUrl The avatar url of the room or DM.
|
||||||
* @param timestamp The timestamp of the event that started the call.
|
* @param timestamp The timestamp of the event that started the call.
|
||||||
* @param notificationChannelId The id of the notification channel to use for the call notification.
|
* @param notificationChannelId The id of the notification channel to use for the call notification.
|
||||||
|
* @param textContent The text content of the notification. If null the default content from the system will be used.
|
||||||
*/
|
*/
|
||||||
fun handleIncomingCall(
|
fun handleIncomingCall(
|
||||||
callType: CallType.RoomCall,
|
callType: CallType.RoomCall,
|
||||||
|
|
@ -40,5 +41,6 @@ interface ElementCallEntryPoint {
|
||||||
avatarUrl: String?,
|
avatarUrl: String?,
|
||||||
timestamp: Long,
|
timestamp: Long,
|
||||||
notificationChannelId: String,
|
notificationChannelId: String,
|
||||||
|
textContent: String?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ class DefaultElementCallEntryPoint @Inject constructor(
|
||||||
avatarUrl: String?,
|
avatarUrl: String?,
|
||||||
timestamp: Long,
|
timestamp: Long,
|
||||||
notificationChannelId: String,
|
notificationChannelId: String,
|
||||||
|
textContent: String?,
|
||||||
) {
|
) {
|
||||||
val incomingCallNotificationData = CallNotificationData(
|
val incomingCallNotificationData = CallNotificationData(
|
||||||
sessionId = callType.sessionId,
|
sessionId = callType.sessionId,
|
||||||
|
|
@ -54,6 +55,7 @@ class DefaultElementCallEntryPoint @Inject constructor(
|
||||||
avatarUrl = avatarUrl,
|
avatarUrl = avatarUrl,
|
||||||
timestamp = timestamp,
|
timestamp = timestamp,
|
||||||
notificationChannelId = notificationChannelId,
|
notificationChannelId = notificationChannelId,
|
||||||
|
textContent = textContent,
|
||||||
)
|
)
|
||||||
activeCallManager.registerIncomingCall(notificationData = incomingCallNotificationData)
|
activeCallManager.registerIncomingCall(notificationData = incomingCallNotificationData)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,4 +25,5 @@ data class CallNotificationData(
|
||||||
val avatarUrl: String?,
|
val avatarUrl: String?,
|
||||||
val notificationChannelId: String,
|
val notificationChannelId: String,
|
||||||
val timestamp: Long,
|
val timestamp: Long,
|
||||||
|
val textContent: String?,
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ class RingingCallNotificationCreator @Inject constructor(
|
||||||
roomAvatarUrl: String?,
|
roomAvatarUrl: String?,
|
||||||
notificationChannelId: String,
|
notificationChannelId: String,
|
||||||
timestamp: Long,
|
timestamp: Long,
|
||||||
|
textContent: String?,
|
||||||
): Notification? {
|
): Notification? {
|
||||||
val matrixClient = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return null
|
val matrixClient = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return null
|
||||||
val imageLoader = imageLoaderHolder.get(matrixClient)
|
val imageLoader = imageLoaderHolder.get(matrixClient)
|
||||||
|
|
@ -84,7 +85,8 @@ class RingingCallNotificationCreator @Inject constructor(
|
||||||
senderName = senderDisplayName,
|
senderName = senderDisplayName,
|
||||||
avatarUrl = roomAvatarUrl,
|
avatarUrl = roomAvatarUrl,
|
||||||
notificationChannelId = notificationChannelId,
|
notificationChannelId = notificationChannelId,
|
||||||
timestamp = timestamp
|
timestamp = timestamp,
|
||||||
|
textContent = textContent,
|
||||||
)
|
)
|
||||||
|
|
||||||
val declineIntent = PendingIntentCompat.getBroadcast(
|
val declineIntent = PendingIntentCompat.getBroadcast(
|
||||||
|
|
@ -120,6 +122,10 @@ class RingingCallNotificationCreator @Inject constructor(
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.setShowWhen(false)
|
.setShowWhen(false)
|
||||||
.apply {
|
.apply {
|
||||||
|
if (textContent != null) {
|
||||||
|
setContentText(textContent)
|
||||||
|
// Else the content text is set by the style (will be "Incoming call")
|
||||||
|
}
|
||||||
if (ringtoneUri != null) {
|
if (ringtoneUri != null) {
|
||||||
setSound(ringtoneUri, AudioManager.STREAM_RING)
|
setSound(ringtoneUri, AudioManager.STREAM_RING)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,7 @@ internal fun IncomingCallScreenPreview() = ElementPreview {
|
||||||
avatarUrl = null,
|
avatarUrl = null,
|
||||||
notificationChannelId = "incoming_call",
|
notificationChannelId = "incoming_call",
|
||||||
timestamp = 0L,
|
timestamp = 0L,
|
||||||
|
textContent = null,
|
||||||
),
|
),
|
||||||
onAnswer = {},
|
onAnswer = {},
|
||||||
onCancel = {},
|
onCancel = {},
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,8 @@ class DefaultActiveCallManager @Inject constructor(
|
||||||
senderDisplayName = notificationData.senderName ?: notificationData.senderId.value,
|
senderDisplayName = notificationData.senderName ?: notificationData.senderId.value,
|
||||||
roomAvatarUrl = notificationData.avatarUrl,
|
roomAvatarUrl = notificationData.avatarUrl,
|
||||||
notificationChannelId = notificationData.notificationChannelId,
|
notificationChannelId = notificationData.notificationChannelId,
|
||||||
timestamp = notificationData.timestamp
|
timestamp = notificationData.timestamp,
|
||||||
|
textContent = notificationData.textContent,
|
||||||
) ?: return
|
) ?: return
|
||||||
runCatching {
|
runCatching {
|
||||||
notificationManagerCompat.notify(
|
notificationManagerCompat.notify(
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ class DefaultElementCallEntryPointTest {
|
||||||
avatarUrl = "avatarUrl",
|
avatarUrl = "avatarUrl",
|
||||||
timestamp = 0,
|
timestamp = 0,
|
||||||
notificationChannelId = "notificationChannelId",
|
notificationChannelId = "notificationChannelId",
|
||||||
|
textContent = "textContent",
|
||||||
)
|
)
|
||||||
|
|
||||||
registerIncomingCallLambda.assertions().isCalledOnce()
|
registerIncomingCallLambda.assertions().isCalledOnce()
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ class RingingCallNotificationCreatorTest {
|
||||||
roomAvatarUrl = "https://example.com/avatar.jpg",
|
roomAvatarUrl = "https://example.com/avatar.jpg",
|
||||||
notificationChannelId = "channelId",
|
notificationChannelId = "channelId",
|
||||||
timestamp = 0L,
|
timestamp = 0L,
|
||||||
|
textContent = "textContent",
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createRingingCallNotificationCreator(
|
private fun createRingingCallNotificationCreator(
|
||||||
|
|
|
||||||
|
|
@ -22,4 +22,5 @@ dependencies {
|
||||||
implementation(projects.features.call.impl)
|
implementation(projects.features.call.impl)
|
||||||
implementation(projects.libraries.matrix.api)
|
implementation(projects.libraries.matrix.api)
|
||||||
implementation(projects.libraries.matrix.test)
|
implementation(projects.libraries.matrix.test)
|
||||||
|
implementation(projects.tests.testutils)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ fun aCallNotificationData(
|
||||||
avatarUrl: String? = AN_AVATAR_URL,
|
avatarUrl: String? = AN_AVATAR_URL,
|
||||||
notificationChannelId: String = "channel_id",
|
notificationChannelId: String = "channel_id",
|
||||||
timestamp: Long = 0L,
|
timestamp: Long = 0L,
|
||||||
|
textContent: String? = null,
|
||||||
): CallNotificationData = CallNotificationData(
|
): CallNotificationData = CallNotificationData(
|
||||||
sessionId = sessionId,
|
sessionId = sessionId,
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
|
|
@ -40,4 +41,5 @@ fun aCallNotificationData(
|
||||||
avatarUrl = avatarUrl,
|
avatarUrl = avatarUrl,
|
||||||
notificationChannelId = notificationChannelId,
|
notificationChannelId = notificationChannelId,
|
||||||
timestamp = timestamp,
|
timestamp = timestamp,
|
||||||
|
textContent = textContent,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,20 @@ import io.element.android.features.call.api.CallType
|
||||||
import io.element.android.features.call.api.ElementCallEntryPoint
|
import io.element.android.features.call.api.ElementCallEntryPoint
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
|
||||||
class FakeElementCallEntryPoint(
|
class FakeElementCallEntryPoint(
|
||||||
var startCallResult: (CallType) -> Unit = {},
|
var startCallResult: (CallType) -> Unit = { lambdaError() },
|
||||||
var handleIncomingCallResult: (CallType.RoomCall, EventId, UserId, String?, String?, String?, String) -> Unit = { _, _, _, _, _, _, _ -> }
|
var handleIncomingCallResult: (
|
||||||
|
CallType.RoomCall,
|
||||||
|
EventId,
|
||||||
|
UserId,
|
||||||
|
String?,
|
||||||
|
String?,
|
||||||
|
String?,
|
||||||
|
String,
|
||||||
|
String?,
|
||||||
|
) -> Unit = { _, _, _, _, _, _, _, _ -> lambdaError() }
|
||||||
) : ElementCallEntryPoint {
|
) : ElementCallEntryPoint {
|
||||||
override fun startCall(callType: CallType) {
|
override fun startCall(callType: CallType) {
|
||||||
startCallResult(callType)
|
startCallResult(callType)
|
||||||
|
|
@ -28,8 +38,18 @@ class FakeElementCallEntryPoint(
|
||||||
senderName: String?,
|
senderName: String?,
|
||||||
avatarUrl: String?,
|
avatarUrl: String?,
|
||||||
timestamp: Long,
|
timestamp: Long,
|
||||||
notificationChannelId: String
|
notificationChannelId: String,
|
||||||
|
textContent: String?,
|
||||||
) {
|
) {
|
||||||
handleIncomingCallResult(callType, eventId, senderId, roomName, senderName, avatarUrl, notificationChannelId)
|
handleIncomingCallResult(
|
||||||
|
callType,
|
||||||
|
eventId,
|
||||||
|
senderId,
|
||||||
|
roomName,
|
||||||
|
senderName,
|
||||||
|
avatarUrl,
|
||||||
|
notificationChannelId,
|
||||||
|
textContent,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ class DefaultPushHandler @Inject constructor(
|
||||||
avatarUrl = notifiableEvent.roomAvatarUrl,
|
avatarUrl = notifiableEvent.roomAvatarUrl,
|
||||||
timestamp = notifiableEvent.timestamp,
|
timestamp = notifiableEvent.timestamp,
|
||||||
notificationChannelId = notificationChannels.getChannelForIncomingCall(ring = true),
|
notificationChannelId = notificationChannels.getChannelForIncomingCall(ring = true),
|
||||||
|
textContent = notifiableEvent.description,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,17 @@ class DefaultPushHandlerTest {
|
||||||
unread = 0,
|
unread = 0,
|
||||||
clientSecret = A_SECRET,
|
clientSecret = A_SECRET,
|
||||||
)
|
)
|
||||||
val handleIncomingCallLambda = lambdaRecorder<CallType.RoomCall, EventId, UserId, String?, String?, String?, String, Unit> { _, _, _, _, _, _, _ -> }
|
val handleIncomingCallLambda = lambdaRecorder<
|
||||||
|
CallType.RoomCall,
|
||||||
|
EventId,
|
||||||
|
UserId,
|
||||||
|
String?,
|
||||||
|
String?,
|
||||||
|
String?,
|
||||||
|
String,
|
||||||
|
String?,
|
||||||
|
Unit,
|
||||||
|
> { _, _, _, _, _, _, _, _ -> }
|
||||||
val elementCallEntryPoint = FakeElementCallEntryPoint(handleIncomingCallResult = handleIncomingCallLambda)
|
val elementCallEntryPoint = FakeElementCallEntryPoint(handleIncomingCallResult = handleIncomingCallLambda)
|
||||||
val onNotifiableEventReceived = lambdaRecorder<NotifiableEvent, Unit> {}
|
val onNotifiableEventReceived = lambdaRecorder<NotifiableEvent, Unit> {}
|
||||||
val defaultPushHandler = createDefaultPushHandler(
|
val defaultPushHandler = createDefaultPushHandler(
|
||||||
|
|
@ -266,7 +276,17 @@ class DefaultPushHandlerTest {
|
||||||
clientSecret = A_SECRET,
|
clientSecret = A_SECRET,
|
||||||
)
|
)
|
||||||
val onNotifiableEventReceived = lambdaRecorder<NotifiableEvent, Unit> {}
|
val onNotifiableEventReceived = lambdaRecorder<NotifiableEvent, Unit> {}
|
||||||
val handleIncomingCallLambda = lambdaRecorder<CallType.RoomCall, EventId, UserId, String?, String?, String?, String, Unit> { _, _, _, _, _, _, _ -> }
|
val handleIncomingCallLambda = lambdaRecorder<
|
||||||
|
CallType.RoomCall,
|
||||||
|
EventId,
|
||||||
|
UserId,
|
||||||
|
String?,
|
||||||
|
String?,
|
||||||
|
String?,
|
||||||
|
String,
|
||||||
|
String?,
|
||||||
|
Unit,
|
||||||
|
> { _, _, _, _, _, _, _, _ -> }
|
||||||
val elementCallEntryPoint = FakeElementCallEntryPoint(handleIncomingCallResult = handleIncomingCallLambda)
|
val elementCallEntryPoint = FakeElementCallEntryPoint(handleIncomingCallResult = handleIncomingCallLambda)
|
||||||
val defaultPushHandler = createDefaultPushHandler(
|
val defaultPushHandler = createDefaultPushHandler(
|
||||||
elementCallEntryPoint = elementCallEntryPoint,
|
elementCallEntryPoint = elementCallEntryPoint,
|
||||||
|
|
@ -294,7 +314,17 @@ class DefaultPushHandlerTest {
|
||||||
clientSecret = A_SECRET,
|
clientSecret = A_SECRET,
|
||||||
)
|
)
|
||||||
val onNotifiableEventReceived = lambdaRecorder<NotifiableEvent, Unit> {}
|
val onNotifiableEventReceived = lambdaRecorder<NotifiableEvent, Unit> {}
|
||||||
val handleIncomingCallLambda = lambdaRecorder<CallType.RoomCall, EventId, UserId, String?, String?, String?, String, Unit> { _, _, _, _, _, _, _ -> }
|
val handleIncomingCallLambda = lambdaRecorder<
|
||||||
|
CallType.RoomCall,
|
||||||
|
EventId,
|
||||||
|
UserId,
|
||||||
|
String?,
|
||||||
|
String?,
|
||||||
|
String?,
|
||||||
|
String,
|
||||||
|
String?,
|
||||||
|
Unit,
|
||||||
|
> { _, _, _, _, _, _, _, _ -> }
|
||||||
val elementCallEntryPoint = FakeElementCallEntryPoint(handleIncomingCallResult = handleIncomingCallLambda)
|
val elementCallEntryPoint = FakeElementCallEntryPoint(handleIncomingCallResult = handleIncomingCallLambda)
|
||||||
val defaultPushHandler = createDefaultPushHandler(
|
val defaultPushHandler = createDefaultPushHandler(
|
||||||
elementCallEntryPoint = elementCallEntryPoint,
|
elementCallEntryPoint = elementCallEntryPoint,
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,13 @@ inline fun <reified T1, reified T2, reified T3, reified T4, reified T5, reified
|
||||||
return LambdaSevenParamsRecorder(ensureNeverCalled, block)
|
return LambdaSevenParamsRecorder(ensureNeverCalled, block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun <reified T1, reified T2, reified T3, reified T4, reified T5, reified T6, reified T7, reified T8, reified R> lambdaRecorder(
|
||||||
|
ensureNeverCalled: Boolean = false,
|
||||||
|
noinline block: (T1, T2, T3, T4, T5, T6, T7, T8) -> R
|
||||||
|
): LambdaEightParamsRecorder<T1, T2, T3, T4, T5, T6, T7, T8, R> {
|
||||||
|
return LambdaEightParamsRecorder(ensureNeverCalled, block)
|
||||||
|
}
|
||||||
|
|
||||||
inline fun <reified R> lambdaAnyRecorder(
|
inline fun <reified R> lambdaAnyRecorder(
|
||||||
ensureNeverCalled: Boolean = false,
|
ensureNeverCalled: Boolean = false,
|
||||||
noinline block: (List<Any?>) -> R
|
noinline block: (List<Any?>) -> R
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue