Add call-link specific network error handling.

Co-authored-by: Greyson Parrelli <greyson@signal.org>
This commit is contained in:
Alex Hart
2026-05-26 14:12:37 -03:00
committed by Michelle Tang
parent 1864534174
commit f5f686fece
3 changed files with 69 additions and 0 deletions
@@ -0,0 +1,53 @@
/*
* Copyright 2025 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.service.webrtc
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.components.webrtc.EglBaseWrapper
import org.thoughtcrime.securesms.events.WebRtcViewModel
import org.thoughtcrime.securesms.ringrtc.RemotePeer
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState
/**
* Process actions when the network is unavailable during a call link.
* Unlike groups, call links do not create a group call object while waiting for the network.
*/
class CallLinkNetworkUnavailableActionProcessor(
actionProcessorFactory: MultiPeerActionProcessorFactory,
webRtcInteractor: WebRtcInteractor
) : GroupNetworkUnavailableActionProcessor(actionProcessorFactory, webRtcInteractor, TAG) {
companion object {
private val TAG = Log.tag(CallLinkNetworkUnavailableActionProcessor::class.java)
}
override fun handlePreJoinCall(currentState: WebRtcServiceState, remotePeer: RemotePeer): WebRtcServiceState {
Log.i(TAG, "handlePreJoinCall():")
val connectivityManager = context.getSystemService(android.content.Context.CONNECTIVITY_SERVICE) as android.net.ConnectivityManager
val activeNetworkInfo = connectivityManager.activeNetworkInfo
if (activeNetworkInfo != null && activeNetworkInfo.isConnected) {
val processor = getActionProcessorFactory().createPreJoinActionProcessor(webRtcInteractor)
return processor.handlePreJoinCall(currentState.builder().actionProcessor(processor).build(), remotePeer)
}
return currentState.builder()
.changeCallInfoState()
.callState(WebRtcViewModel.State.NETWORK_FAILURE)
.groupCallState(WebRtcViewModel.GroupCallState.DISCONNECTED)
.build()
}
override fun handleCancelPreJoinCall(currentState: WebRtcServiceState): WebRtcServiceState {
Log.i(TAG, "handleCancelPreJoinCall():")
WebRtcVideoUtil.deinitializeVideo(currentState)
EglBaseWrapper.releaseEglBase(RemotePeer.GROUP_CALL_ID.longValue())
return WebRtcServiceState(IdleActionProcessor(webRtcInteractor))
}
}
@@ -39,6 +39,18 @@ public class GroupNetworkUnavailableActionProcessor extends WebRtcActionProcesso
this.actionProcessorFactory = actionProcessorFactory;
}
protected GroupNetworkUnavailableActionProcessor(@NonNull MultiPeerActionProcessorFactory actionProcessorFactory,
@NonNull WebRtcInteractor webRtcInteractor,
@NonNull String tag)
{
super(webRtcInteractor, tag);
this.actionProcessorFactory = actionProcessorFactory;
}
protected @NonNull MultiPeerActionProcessorFactory getActionProcessorFactory() {
return actionProcessorFactory;
}
@Override
protected @NonNull WebRtcServiceState handleIsInCallQuery(@NonNull WebRtcServiceState currentState, @Nullable ResultReceiver resultReceiver) {
if (resultReceiver != null) {
@@ -44,5 +44,9 @@ sealed interface MultiPeerActionProcessorFactory {
override fun createConnectedActionProcessor(webRtcInteractor: WebRtcInteractor): GroupConnectedActionProcessor {
return CallLinkConnectedActionProcessor(this, webRtcInteractor)
}
override fun createNetworkUnavailableActionProcessor(webRtcInteractor: WebRtcInteractor): GroupNetworkUnavailableActionProcessor {
return CallLinkNetworkUnavailableActionProcessor(this, webRtcInteractor)
}
}
}