Skip to content

Commit 3ba11db

Browse files
authored
Add extra logs the 'send call notification' flow (#4819)
1 parent 800a331 commit 3ba11db

File tree

6 files changed

+76
-19
lines changed

6 files changed

+76
-19
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,19 @@ import kotlinx.parcelize.Parcelize
1515

1616
sealed interface CallType : NodeInputs, Parcelable {
1717
@Parcelize
18-
data class ExternalUrl(val url: String) : CallType
18+
data class ExternalUrl(val url: String) : CallType {
19+
override fun toString(): String {
20+
return "ExternalUrl"
21+
}
22+
}
1923

2024
@Parcelize
2125
data class RoomCall(
2226
val sessionId: SessionId,
2327
val roomId: RoomId,
24-
) : CallType
28+
) : CallType {
29+
override fun toString(): String {
30+
return "RoomCall(sessionId=$sessionId, roomId=$roomId)"
31+
}
32+
}
2533
}

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

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import kotlinx.coroutines.launch
5050
import kotlinx.serialization.json.contentOrNull
5151
import kotlinx.serialization.json.jsonObject
5252
import kotlinx.serialization.json.jsonPrimitive
53+
import timber.log.Timber
5354
import java.util.UUID
5455

5556
class CallScreenPresenter @AssistedInject constructor(
@@ -213,6 +214,7 @@ class CallScreenPresenter @AssistedInject constructor(
213214
theme = theme,
214215
).getOrThrow()
215216
callWidgetDriver.value = result.driver
217+
Timber.d("Call widget driver initialized for sessionId: ${inputs.sessionId}, roomId: ${inputs.roomId}")
216218
result.url
217219
}
218220
}
@@ -223,10 +225,12 @@ class CallScreenPresenter @AssistedInject constructor(
223225
private fun HandleMatrixClientSyncState() {
224226
val coroutineScope = rememberCoroutineScope()
225227
DisposableEffect(Unit) {
226-
val client = (callType as? CallType.RoomCall)?.sessionId?.let {
227-
matrixClientsProvider.getOrNull(it)
228-
} ?: return@DisposableEffect onDispose { }
228+
val roomCallType = callType as? CallType.RoomCall ?: return@DisposableEffect onDispose {}
229+
val client = matrixClientsProvider.getOrNull(roomCallType.sessionId) ?: return@DisposableEffect onDispose {
230+
Timber.w("No MatrixClient found for sessionId, can't send call notification: ${roomCallType.sessionId}")
231+
}
229232
coroutineScope.launch {
233+
Timber.d("Observing sync state in-call for sessionId: ${roomCallType.sessionId}")
230234
client.syncService().syncState
231235
.collect { state ->
232236
if (state == SyncState.Running) {
@@ -237,19 +241,37 @@ class CallScreenPresenter @AssistedInject constructor(
237241
}
238242
}
239243
onDispose {
244+
Timber.d("Stopped observing sync state in-call for sessionId: ${roomCallType.sessionId}")
240245
// Make sure we mark the call as ended in the app state
241246
appForegroundStateService.updateIsInCallState(false)
242247
}
243248
}
244249
}
245250

246251
private suspend fun MatrixClient.notifyCallStartIfNeeded(roomId: RoomId) {
247-
if (!notifiedCallStart) {
248-
val activeRoomForSession = activeRoomsHolder.getActiveRoomMatching(sessionId, roomId)
249-
val sendCallNotificationResult = activeRoomForSession?.sendCallNotificationIfNeeded()
250-
?: getJoinedRoom(roomId)?.use { it.sendCallNotificationIfNeeded() }
251-
sendCallNotificationResult?.onSuccess { notifiedCallStart = true }
252+
if (notifiedCallStart) return
253+
254+
val activeRoomForSession = activeRoomsHolder.getActiveRoomMatching(sessionId, roomId)
255+
val sendCallNotificationResult = if (activeRoomForSession != null) {
256+
Timber.d("Notifying call start for room $roomId. Has room call: ${activeRoomForSession.info().hasRoomCall}")
257+
activeRoomForSession.sendCallNotificationIfNeeded()
258+
} else {
259+
// Instantiate the room from the session and roomId and send the notification
260+
getJoinedRoom(roomId)?.use { room ->
261+
Timber.d("Notifying call start for room $roomId. Has room call: ${room.info().hasRoomCall}")
262+
room.sendCallNotificationIfNeeded()
263+
} ?: run {
264+
Timber.w("No room found for session $sessionId and room $roomId, skipping call notification.")
265+
return
266+
}
252267
}
268+
269+
sendCallNotificationResult.fold(
270+
onSuccess = { notifiedCallStart = true },
271+
onFailure = { error ->
272+
Timber.e(error, "Failed to send call notification for room $roomId.")
273+
}
274+
)
253275
}
254276

255277
private fun parseMessage(message: String): WidgetMessage? {

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,13 @@ internal fun CallScreenView(
134134
AsyncData.Uninitialized,
135135
is AsyncData.Loading ->
136136
ProgressDialog(text = stringResource(id = CommonStrings.common_please_wait))
137-
is AsyncData.Failure ->
137+
is AsyncData.Failure -> {
138+
Timber.e(state.urlState.error, "WebView failed to load URL: ${state.urlState.error.message}")
138139
ErrorDialog(
139140
content = state.urlState.error.message.orEmpty(),
140141
onSubmit = { state.eventSink(CallScreenEvents.Hangup) },
141142
)
143+
}
142144
is AsyncData.Success -> Unit
143145
}
144146
}
@@ -242,6 +244,20 @@ private fun WebView.setup(
242244
ConsoleMessage.MessageLevel.WARNING -> Log.WARN
243245
else -> Log.DEBUG
244246
}
247+
248+
val message = buildString {
249+
append(consoleMessage.sourceId())
250+
append(":")
251+
append(consoleMessage.lineNumber())
252+
append(" ")
253+
append(consoleMessage.message())
254+
}
255+
256+
if (message.contains("password=")) {
257+
// Avoid logging any messages that contain "password" to prevent leaking sensitive information
258+
return true
259+
}
260+
245261
Timber.tag("WebView").log(
246262
priority = priority,
247263
message = buildString {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class ElementCallActivity :
9797

9898
pictureInPicturePresenter.setPipView(this)
9999

100+
Timber.d("Created ElementCallActivity with call type: ${webViewTarget.value}")
101+
100102
setContent {
101103
val pipState = pictureInPicturePresenter.present()
102104
ListenToAndroidEvents(pipState)

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ class DefaultActiveCallManager @Inject constructor(
183183
Timber.tag(tag).w("Call type $callType does not match the active call type, ignoring")
184184
return
185185
}
186+
187+
Timber.tag(tag).d("Hung up call: $callType")
188+
186189
cancelIncomingCallNotification()
187190
if (activeWakeLock?.isHeld == true) {
188191
Timber.tag(tag).d("Releasing partial wakelock after hang up")
@@ -193,6 +196,8 @@ class DefaultActiveCallManager @Inject constructor(
193196
}
194197

195198
override suspend fun joinedCall(callType: CallType) = mutex.withLock {
199+
Timber.tag(tag).d("Joined call: $callType")
200+
196201
cancelIncomingCallNotification()
197202
if (activeWakeLock?.isHeld == true) {
198203
Timber.tag(tag).d("Releasing partial wakelock after joining call")

features/roomcall/impl/src/main/kotlin/io/element/android/features/roomcall/impl/RoomCallStatePresenter.kt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,18 @@ class RoomCallStatePresenter @Inject constructor(
4646
(currentCall as? CurrentCall.RoomCall)?.roomId == room.roomId
4747
}
4848
}
49-
val callState = when {
50-
isAvailable.not() -> RoomCallState.Unavailable
51-
roomInfo.hasRoomCall -> RoomCallState.OnGoing(
52-
canJoinCall = canJoinCall,
53-
isUserInTheCall = isUserInTheCall,
54-
isUserLocallyInTheCall = isUserLocallyInTheCall,
55-
)
56-
else -> RoomCallState.StandBy(canStartCall = canJoinCall)
49+
val callState by remember {
50+
derivedStateOf {
51+
when {
52+
isAvailable.not() -> RoomCallState.Unavailable
53+
roomInfo.hasRoomCall -> RoomCallState.OnGoing(
54+
canJoinCall = canJoinCall,
55+
isUserInTheCall = isUserInTheCall,
56+
isUserLocallyInTheCall = isUserLocallyInTheCall,
57+
)
58+
else -> RoomCallState.StandBy(canStartCall = canJoinCall)
59+
}
60+
}
5761
}
5862
return callState
5963
}

0 commit comments

Comments
 (0)