Skip to content

Commit

Permalink
Update incoming call notification content to "📹 Incoming call"
Browse files Browse the repository at this point in the history
  • Loading branch information
bmarty committed Feb 4, 2025
1 parent c5f3b34 commit 7878f97
Show file tree
Hide file tree
Showing 14 changed files with 85 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface ElementCallEntryPoint {
* @param avatarUrl The avatar url of the room or DM.
* @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 textContent The text content of the notification. If null the default content from the system will be used.
*/
fun handleIncomingCall(
callType: CallType.RoomCall,
Expand All @@ -40,5 +41,6 @@ interface ElementCallEntryPoint {
avatarUrl: String?,
timestamp: Long,
notificationChannelId: String,
textContent: String?,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class DefaultElementCallEntryPoint @Inject constructor(
avatarUrl: String?,
timestamp: Long,
notificationChannelId: String,
textContent: String?,
) {
val incomingCallNotificationData = CallNotificationData(
sessionId = callType.sessionId,
Expand All @@ -54,6 +55,7 @@ class DefaultElementCallEntryPoint @Inject constructor(
avatarUrl = avatarUrl,
timestamp = timestamp,
notificationChannelId = notificationChannelId,
textContent = textContent,
)
activeCallManager.registerIncomingCall(notificationData = incomingCallNotificationData)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ data class CallNotificationData(
val avatarUrl: String?,
val notificationChannelId: String,
val timestamp: Long,
val textContent: String?,
) : Parcelable
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class RingingCallNotificationCreator @Inject constructor(
roomAvatarUrl: String?,
notificationChannelId: String,
timestamp: Long,
textContent: String?,
): Notification? {
val matrixClient = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return null
val imageLoader = imageLoaderHolder.get(matrixClient)
Expand All @@ -84,7 +85,8 @@ class RingingCallNotificationCreator @Inject constructor(
senderName = senderDisplayName,
avatarUrl = roomAvatarUrl,
notificationChannelId = notificationChannelId,
timestamp = timestamp
timestamp = timestamp,
textContent = textContent,
)

val declineIntent = PendingIntentCompat.getBroadcast(
Expand Down Expand Up @@ -120,6 +122,10 @@ class RingingCallNotificationCreator @Inject constructor(
.setOngoing(true)
.setShowWhen(false)
.apply {
if (textContent != null) {
setContentText(textContent)
// Else the content text is set by the style (will be "Incoming call")
}
if (ringtoneUri != null) {
setSound(ringtoneUri, AudioManager.STREAM_RING)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ internal fun IncomingCallScreenPreview() = ElementPreview {
avatarUrl = null,
notificationChannelId = "incoming_call",
timestamp = 0L,
textContent = null,
),
onAnswer = {},
onCancel = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ class DefaultActiveCallManager @Inject constructor(
senderDisplayName = notificationData.senderName ?: notificationData.senderId.value,
roomAvatarUrl = notificationData.avatarUrl,
notificationChannelId = notificationData.notificationChannelId,
timestamp = notificationData.timestamp
timestamp = notificationData.timestamp,
textContent = notificationData.textContent,
) ?: return
runCatching {
notificationManagerCompat.notify(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class DefaultElementCallEntryPointTest {
avatarUrl = "avatarUrl",
timestamp = 0,
notificationChannelId = "notificationChannelId",
textContent = "textContent",
)

registerIncomingCallLambda.assertions().isCalledOnce()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class RingingCallNotificationCreatorTest {
roomAvatarUrl = "https://example.com/avatar.jpg",
notificationChannelId = "channelId",
timestamp = 0L,
textContent = "textContent",
)

private fun createRingingCallNotificationCreator(
Expand Down
1 change: 1 addition & 0 deletions features/call/test/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ dependencies {
implementation(projects.features.call.impl)
implementation(projects.libraries.matrix.api)
implementation(projects.libraries.matrix.test)
implementation(projects.tests.testutils)
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ fun aCallNotificationData(
avatarUrl: String? = AN_AVATAR_URL,
notificationChannelId: String = "channel_id",
timestamp: Long = 0L,
textContent: String? = null,
): CallNotificationData = CallNotificationData(
sessionId = sessionId,
roomId = roomId,
Expand All @@ -40,4 +41,5 @@ fun aCallNotificationData(
avatarUrl = avatarUrl,
notificationChannelId = notificationChannelId,
timestamp = timestamp,
textContent = textContent,
)
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,20 @@ import io.element.android.features.call.api.CallType
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.UserId
import io.element.android.tests.testutils.lambda.lambdaError

class FakeElementCallEntryPoint(
var startCallResult: (CallType) -> Unit = {},
var handleIncomingCallResult: (CallType.RoomCall, EventId, UserId, String?, String?, String?, String) -> Unit = { _, _, _, _, _, _, _ -> }
var startCallResult: (CallType) -> Unit = { lambdaError() },
var handleIncomingCallResult: (
CallType.RoomCall,
EventId,
UserId,
String?,
String?,
String?,
String,
String?,
) -> Unit = { _, _, _, _, _, _, _, _ -> lambdaError() }
) : ElementCallEntryPoint {
override fun startCall(callType: CallType) {
startCallResult(callType)
Expand All @@ -28,8 +38,18 @@ class FakeElementCallEntryPoint(
senderName: String?,
avatarUrl: String?,
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,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class DefaultPushHandler @Inject constructor(
avatarUrl = notifiableEvent.roomAvatarUrl,
timestamp = notifiableEvent.timestamp,
notificationChannelId = notificationChannels.getChannelForIncomingCall(ring = true),
textContent = notifiableEvent.description,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,17 @@ class DefaultPushHandlerTest {
unread = 0,
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 onNotifiableEventReceived = lambdaRecorder<NotifiableEvent, Unit> {}
val defaultPushHandler = createDefaultPushHandler(
Expand Down Expand Up @@ -266,7 +276,17 @@ class DefaultPushHandlerTest {
clientSecret = A_SECRET,
)
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 defaultPushHandler = createDefaultPushHandler(
elementCallEntryPoint = elementCallEntryPoint,
Expand Down Expand Up @@ -294,7 +314,17 @@ class DefaultPushHandlerTest {
clientSecret = A_SECRET,
)
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 defaultPushHandler = createDefaultPushHandler(
elementCallEntryPoint = elementCallEntryPoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ inline fun <reified T1, reified T2, reified T3, reified T4, reified T5, reified
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(
ensureNeverCalled: Boolean = false,
noinline block: (List<Any?>) -> R
Expand Down

0 comments on commit 7878f97

Please sign in to comment.