Skip to content

Commit 6362e01

Browse files
authored
Merge pull request #4231 from element-hq/feature/bma/incomingCallAvatar
Update incoming call notification content to "📹 Incoming call"
2 parents c5f3b34 + 7878f97 commit 6362e01

File tree

14 files changed

+85
-9
lines changed

14 files changed

+85
-9
lines changed

features/call/api/src/main/kotlin/io/element/android/features/call/api/ElementCallEntryPoint.kt

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ interface ElementCallEntryPoint {
3030
* @param avatarUrl The avatar url of the room or DM.
3131
* @param timestamp The timestamp of the event that started the call.
3232
* @param notificationChannelId The id of the notification channel to use for the call notification.
33+
* @param textContent The text content of the notification. If null the default content from the system will be used.
3334
*/
3435
fun handleIncomingCall(
3536
callType: CallType.RoomCall,
@@ -40,5 +41,6 @@ interface ElementCallEntryPoint {
4041
avatarUrl: String?,
4142
timestamp: Long,
4243
notificationChannelId: String,
44+
textContent: String?,
4345
)
4446
}

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/DefaultElementCallEntryPoint.kt

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class DefaultElementCallEntryPoint @Inject constructor(
4343
avatarUrl: String?,
4444
timestamp: Long,
4545
notificationChannelId: String,
46+
textContent: String?,
4647
) {
4748
val incomingCallNotificationData = CallNotificationData(
4849
sessionId = callType.sessionId,
@@ -54,6 +55,7 @@ class DefaultElementCallEntryPoint @Inject constructor(
5455
avatarUrl = avatarUrl,
5556
timestamp = timestamp,
5657
notificationChannelId = notificationChannelId,
58+
textContent = textContent,
5759
)
5860
activeCallManager.registerIncomingCall(notificationData = incomingCallNotificationData)
5961
}

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/notifications/CallNotificationData.kt

+1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ data class CallNotificationData(
2525
val avatarUrl: String?,
2626
val notificationChannelId: String,
2727
val timestamp: Long,
28+
val textContent: String?,
2829
) : Parcelable

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/notifications/RingingCallNotificationCreator.kt

+7-1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class RingingCallNotificationCreator @Inject constructor(
6363
roomAvatarUrl: String?,
6464
notificationChannelId: String,
6565
timestamp: Long,
66+
textContent: String?,
6667
): Notification? {
6768
val matrixClient = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return null
6869
val imageLoader = imageLoaderHolder.get(matrixClient)
@@ -84,7 +85,8 @@ class RingingCallNotificationCreator @Inject constructor(
8485
senderName = senderDisplayName,
8586
avatarUrl = roomAvatarUrl,
8687
notificationChannelId = notificationChannelId,
87-
timestamp = timestamp
88+
timestamp = timestamp,
89+
textContent = textContent,
8890
)
8991

9092
val declineIntent = PendingIntentCompat.getBroadcast(
@@ -120,6 +122,10 @@ class RingingCallNotificationCreator @Inject constructor(
120122
.setOngoing(true)
121123
.setShowWhen(false)
122124
.apply {
125+
if (textContent != null) {
126+
setContentText(textContent)
127+
// Else the content text is set by the style (will be "Incoming call")
128+
}
123129
if (ringtoneUri != null) {
124130
setSound(ringtoneUri, AudioManager.STREAM_RING)
125131
}

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/IncomingCallScreen.kt

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ internal fun IncomingCallScreenPreview() = ElementPreview {
173173
avatarUrl = null,
174174
notificationChannelId = "incoming_call",
175175
timestamp = 0L,
176+
textContent = null,
176177
),
177178
onAnswer = {},
178179
onCancel = {},

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/ActiveCallManager.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ class DefaultActiveCallManager @Inject constructor(
160160
senderDisplayName = notificationData.senderName ?: notificationData.senderId.value,
161161
roomAvatarUrl = notificationData.avatarUrl,
162162
notificationChannelId = notificationData.notificationChannelId,
163-
timestamp = notificationData.timestamp
163+
timestamp = notificationData.timestamp,
164+
textContent = notificationData.textContent,
164165
) ?: return
165166
runCatching {
166167
notificationManagerCompat.notify(

features/call/impl/src/test/kotlin/io/element/android/features/call/DefaultElementCallEntryPointTest.kt

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class DefaultElementCallEntryPointTest {
5454
avatarUrl = "avatarUrl",
5555
timestamp = 0,
5656
notificationChannelId = "notificationChannelId",
57+
textContent = "textContent",
5758
)
5859

5960
registerIncomingCallLambda.assertions().isCalledOnce()

features/call/impl/src/test/kotlin/io/element/android/features/call/notifications/RingingCallNotificationCreatorTest.kt

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class RingingCallNotificationCreatorTest {
7373
roomAvatarUrl = "https://example.com/avatar.jpg",
7474
notificationChannelId = "channelId",
7575
timestamp = 0L,
76+
textContent = "textContent",
7677
)
7778

7879
private fun createRingingCallNotificationCreator(

features/call/test/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ dependencies {
2222
implementation(projects.features.call.impl)
2323
implementation(projects.libraries.matrix.api)
2424
implementation(projects.libraries.matrix.test)
25+
implementation(projects.tests.testutils)
2526
}

features/call/test/src/main/kotlin/io/element/android/features/call/test/CallNotificationData.kt

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ fun aCallNotificationData(
3030
avatarUrl: String? = AN_AVATAR_URL,
3131
notificationChannelId: String = "channel_id",
3232
timestamp: Long = 0L,
33+
textContent: String? = null,
3334
): CallNotificationData = CallNotificationData(
3435
sessionId = sessionId,
3536
roomId = roomId,
@@ -40,4 +41,5 @@ fun aCallNotificationData(
4041
avatarUrl = avatarUrl,
4142
notificationChannelId = notificationChannelId,
4243
timestamp = timestamp,
44+
textContent = textContent,
4345
)

features/call/test/src/main/kotlin/io/element/android/features/call/test/FakeElementCallEntryPoint.kt

+24-4
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,20 @@ import io.element.android.features.call.api.CallType
1111
import io.element.android.features.call.api.ElementCallEntryPoint
1212
import io.element.android.libraries.matrix.api.core.EventId
1313
import io.element.android.libraries.matrix.api.core.UserId
14+
import io.element.android.tests.testutils.lambda.lambdaError
1415

1516
class FakeElementCallEntryPoint(
16-
var startCallResult: (CallType) -> Unit = {},
17-
var handleIncomingCallResult: (CallType.RoomCall, EventId, UserId, String?, String?, String?, String) -> Unit = { _, _, _, _, _, _, _ -> }
17+
var startCallResult: (CallType) -> Unit = { lambdaError() },
18+
var handleIncomingCallResult: (
19+
CallType.RoomCall,
20+
EventId,
21+
UserId,
22+
String?,
23+
String?,
24+
String?,
25+
String,
26+
String?,
27+
) -> Unit = { _, _, _, _, _, _, _, _ -> lambdaError() }
1828
) : ElementCallEntryPoint {
1929
override fun startCall(callType: CallType) {
2030
startCallResult(callType)
@@ -28,8 +38,18 @@ class FakeElementCallEntryPoint(
2838
senderName: String?,
2939
avatarUrl: String?,
3040
timestamp: Long,
31-
notificationChannelId: String
41+
notificationChannelId: String,
42+
textContent: String?,
3243
) {
33-
handleIncomingCallResult(callType, eventId, senderId, roomName, senderName, avatarUrl, notificationChannelId)
44+
handleIncomingCallResult(
45+
callType,
46+
eventId,
47+
senderId,
48+
roomName,
49+
senderName,
50+
avatarUrl,
51+
notificationChannelId,
52+
textContent,
53+
)
3454
}
3555
}

libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class DefaultPushHandler @Inject constructor(
129129
avatarUrl = notifiableEvent.roomAvatarUrl,
130130
timestamp = notifiableEvent.timestamp,
131131
notificationChannelId = notificationChannels.getChannelForIncomingCall(ring = true),
132+
textContent = notifiableEvent.description,
132133
)
133134
}
134135
}

libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandlerTest.kt

+33-3
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,17 @@ class DefaultPushHandlerTest {
238238
unread = 0,
239239
clientSecret = A_SECRET,
240240
)
241-
val handleIncomingCallLambda = lambdaRecorder<CallType.RoomCall, EventId, UserId, String?, String?, String?, String, Unit> { _, _, _, _, _, _, _ -> }
241+
val handleIncomingCallLambda = lambdaRecorder<
242+
CallType.RoomCall,
243+
EventId,
244+
UserId,
245+
String?,
246+
String?,
247+
String?,
248+
String,
249+
String?,
250+
Unit,
251+
> { _, _, _, _, _, _, _, _ -> }
242252
val elementCallEntryPoint = FakeElementCallEntryPoint(handleIncomingCallResult = handleIncomingCallLambda)
243253
val onNotifiableEventReceived = lambdaRecorder<NotifiableEvent, Unit> {}
244254
val defaultPushHandler = createDefaultPushHandler(
@@ -266,7 +276,17 @@ class DefaultPushHandlerTest {
266276
clientSecret = A_SECRET,
267277
)
268278
val onNotifiableEventReceived = lambdaRecorder<NotifiableEvent, Unit> {}
269-
val handleIncomingCallLambda = lambdaRecorder<CallType.RoomCall, EventId, UserId, String?, String?, String?, String, Unit> { _, _, _, _, _, _, _ -> }
279+
val handleIncomingCallLambda = lambdaRecorder<
280+
CallType.RoomCall,
281+
EventId,
282+
UserId,
283+
String?,
284+
String?,
285+
String?,
286+
String,
287+
String?,
288+
Unit,
289+
> { _, _, _, _, _, _, _, _ -> }
270290
val elementCallEntryPoint = FakeElementCallEntryPoint(handleIncomingCallResult = handleIncomingCallLambda)
271291
val defaultPushHandler = createDefaultPushHandler(
272292
elementCallEntryPoint = elementCallEntryPoint,
@@ -294,7 +314,17 @@ class DefaultPushHandlerTest {
294314
clientSecret = A_SECRET,
295315
)
296316
val onNotifiableEventReceived = lambdaRecorder<NotifiableEvent, Unit> {}
297-
val handleIncomingCallLambda = lambdaRecorder<CallType.RoomCall, EventId, UserId, String?, String?, String?, String, Unit> { _, _, _, _, _, _, _ -> }
317+
val handleIncomingCallLambda = lambdaRecorder<
318+
CallType.RoomCall,
319+
EventId,
320+
UserId,
321+
String?,
322+
String?,
323+
String?,
324+
String,
325+
String?,
326+
Unit,
327+
> { _, _, _, _, _, _, _, _ -> }
298328
val elementCallEntryPoint = FakeElementCallEntryPoint(handleIncomingCallResult = handleIncomingCallLambda)
299329
val defaultPushHandler = createDefaultPushHandler(
300330
elementCallEntryPoint = elementCallEntryPoint,

tests/testutils/src/main/kotlin/io/element/android/tests/testutils/lambda/LambdaRecorder.kt

+7
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ inline fun <reified T1, reified T2, reified T3, reified T4, reified T5, reified
8383
return LambdaSevenParamsRecorder(ensureNeverCalled, block)
8484
}
8585

86+
inline fun <reified T1, reified T2, reified T3, reified T4, reified T5, reified T6, reified T7, reified T8, reified R> lambdaRecorder(
87+
ensureNeverCalled: Boolean = false,
88+
noinline block: (T1, T2, T3, T4, T5, T6, T7, T8) -> R
89+
): LambdaEightParamsRecorder<T1, T2, T3, T4, T5, T6, T7, T8, R> {
90+
return LambdaEightParamsRecorder(ensureNeverCalled, block)
91+
}
92+
8693
inline fun <reified R> lambdaAnyRecorder(
8794
ensureNeverCalled: Boolean = false,
8895
noinline block: (List<Any?>) -> R

0 commit comments

Comments
 (0)