@@ -41,6 +41,7 @@ import android.view.MotionEvent
4141import android.view.OrientationEventListener
4242import android.view.View
4343import android.view.View.OnTouchListener
44+ import android.widget.Toast
4445import androidx.activity.result.contract.ActivityResultContracts
4546import androidx.annotation.DrawableRes
4647import androidx.appcompat.app.AlertDialog
@@ -311,6 +312,7 @@ class CallActivity : CallBaseActivity() {
311312 private var webSocketClient: WebSocketInstance ? = null
312313 private var webSocketConnectionHelper: WebSocketConnectionHelper ? = null
313314 private var joinRoomInitiated = false
315+ private var roomJoinRefreshes = 0
314316 private var hasMCU = false
315317 private var hasExternalSignalingServer = false
316318 private var conversationPassword: String? = null
@@ -1590,6 +1592,31 @@ class CallActivity : CallBaseActivity() {
15901592 }
15911593 }
15921594
1595+ /* *
1596+ * Joining the room for a call was rejected because the cached room session is stale (reaped by the server).
1597+ * Drops the cached session so [joinRoomAndCall] fetches a fresh one via the joinRoom API, and retries a few
1598+ * times; otherwise the call UI would show "Ringing" forever, as the calling timeout is only armed after a
1599+ * successful join.
1600+ */
1601+ private fun handleRoomJoinFailed () {
1602+ Log .d(TAG , " onMessageEvent 'roomJoinFailed'" )
1603+ if (! shouldRefreshRoomSession(currentCallStatus, roomJoinRefreshes)) {
1604+ if (currentCallStatus != = CallStatus .IN_CONVERSATION ) {
1605+ Log .e(TAG , " Joining the room for the call failed repeatedly, leaving" )
1606+ runOnUiThread {
1607+ Toast .makeText(context, R .string.nc_call_join_failed, Toast .LENGTH_LONG ).show()
1608+ finish()
1609+ }
1610+ }
1611+ return
1612+ }
1613+ roomJoinRefreshes++
1614+ Log .d(TAG , " Refreshing the room session and retrying the join ($roomJoinRefreshes /$MAX_ROOM_JOIN_REFRESHES )" )
1615+ ApplicationWideCurrentRoomHolder .getInstance().session = " "
1616+ callSession = null
1617+ joinRoomAndCall()
1618+ }
1619+
15931620 private fun callOrJoinRoomViaWebSocket () {
15941621 if (hasExternalSignalingServer) {
15951622 webSocketClient!! .joinRoomWithRoomTokenAndSession(
@@ -1900,10 +1927,13 @@ class CallActivity : CallBaseActivity() {
19001927 }
19011928 startSendingNick()
19021929 if (webSocketCommunicationEvent.getHashMap()!! [" roomToken" ] == roomToken) {
1930+ roomJoinRefreshes = 0
19031931 performCall()
19041932 }
19051933 }
19061934
1935+ " roomJoinFailed" -> handleRoomJoinFailed()
1936+
19071937 " recordingStatus" -> {
19081938 Log .d(TAG , " onMessageEvent 'recordingStatus'" )
19091939 if (webSocketCommunicationEvent.getHashMap()!! .containsKey(KEY_RECORDING_STATE )) {
@@ -3237,6 +3267,11 @@ class CallActivity : CallBaseActivity() {
32373267 internal fun isPushToTalkRelease (action : Int ): Boolean =
32383268 action == MotionEvent .ACTION_UP || action == MotionEvent .ACTION_CANCEL
32393269
3270+ private const val MAX_ROOM_JOIN_REFRESHES : Int = 2
3271+
3272+ internal fun shouldRefreshRoomSession (callStatus : CallStatus ? , refreshesDone : Int ): Boolean =
3273+ callStatus != = CallStatus .IN_CONVERSATION && refreshesDone < MAX_ROOM_JOIN_REFRESHES
3274+
32403275 private const val DELAY_ON_ERROR_STOP_THRESHOLD : Int = 16
32413276
32423277 private const val SESSION_ID_PREFFIX_END : Int = 4
0 commit comments