VoIP: PSTN support was done too early
This commit is contained in:
parent
109a9e816b
commit
96b02d3154
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2021 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package im.vector.app.features.call.webrtc
|
|
||||||
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import org.matrix.android.sdk.api.session.Session
|
|
||||||
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
|
|
||||||
|
|
||||||
private const val PSTN_VECTOR_KEY = "im.vector.protocol.pstn"
|
|
||||||
private const val PSTN_MATRIX_KEY = "m.protocol.pstn"
|
|
||||||
|
|
||||||
suspend fun Session.getSupportedPSTN(maxTries: Int): String? {
|
|
||||||
val thirdPartyProtocols: Map<String, ThirdPartyProtocol> = try {
|
|
||||||
thirdPartyService().getThirdPartyProtocols()
|
|
||||||
} catch (failure: Throwable) {
|
|
||||||
if (maxTries == 1) {
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
// Wait for 10s before trying again
|
|
||||||
delay(10_000L)
|
|
||||||
return getSupportedPSTN(maxTries - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return when {
|
|
||||||
thirdPartyProtocols.containsKey(PSTN_VECTOR_KEY) -> PSTN_VECTOR_KEY
|
|
||||||
thirdPartyProtocols.containsKey(PSTN_MATRIX_KEY) -> PSTN_MATRIX_KEY
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.call.webrtc
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
private const val PSTN_VECTOR_KEY = "im.vector.protocol.pstn"
|
||||||
|
private const val PSTN_MATRIX_KEY = "m.protocol.pstn"
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class PSTNProtocolChecker @Inject constructor() {
|
||||||
|
|
||||||
|
private var alreadyChecked = AtomicBoolean(false)
|
||||||
|
|
||||||
|
private val pstnSupportListeners = emptyList<WebRtcCallManager.PSTNSupportListener>().toMutableList()
|
||||||
|
fun addPstnSupportListener(listener: WebRtcCallManager.PSTNSupportListener) {
|
||||||
|
pstnSupportListeners.add(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removePstnSupportListener(listener: WebRtcCallManager.PSTNSupportListener) {
|
||||||
|
pstnSupportListeners.remove(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
var supportedPSTNProtocol: String? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun checkForPSTNSupportIfNeeded(currentSession: Session?) {
|
||||||
|
if (alreadyChecked.get()) return
|
||||||
|
GlobalScope.checkForPSTNSupport(currentSession)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CoroutineScope.checkForPSTNSupport(currentSession: Session?) = launch {
|
||||||
|
try {
|
||||||
|
supportedPSTNProtocol = currentSession?.getSupportedPSTN(3)
|
||||||
|
alreadyChecked.set(true)
|
||||||
|
if (supportedPSTNProtocol != null) {
|
||||||
|
pstnSupportListeners.forEach {
|
||||||
|
tryOrNull { it.onPSTNSupportUpdated() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
Timber.v("Fail to get supported PSTN, will check again next time.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun Session.getSupportedPSTN(maxTries: Int): String? {
|
||||||
|
val thirdPartyProtocols: Map<String, ThirdPartyProtocol> = try {
|
||||||
|
thirdPartyService().getThirdPartyProtocols()
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
if (maxTries == 1) {
|
||||||
|
throw failure
|
||||||
|
} else {
|
||||||
|
// Wait for 10s before trying again
|
||||||
|
delay(10_000L)
|
||||||
|
return getSupportedPSTN(maxTries - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return when {
|
||||||
|
thirdPartyProtocols.containsKey(PSTN_VECTOR_KEY) -> PSTN_VECTOR_KEY
|
||||||
|
thirdPartyProtocols.containsKey(PSTN_MATRIX_KEY) -> PSTN_MATRIX_KEY
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,7 +59,8 @@ import javax.inject.Singleton
|
||||||
@Singleton
|
@Singleton
|
||||||
class WebRtcCallManager @Inject constructor(
|
class WebRtcCallManager @Inject constructor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val activeSessionDataSource: ActiveSessionDataSource
|
private val activeSessionDataSource: ActiveSessionDataSource,
|
||||||
|
private val pstnProtocolChecker: PSTNProtocolChecker
|
||||||
) : CallListener, LifecycleObserver {
|
) : CallListener, LifecycleObserver {
|
||||||
|
|
||||||
private val currentSession: Session?
|
private val currentSession: Session?
|
||||||
|
@ -74,13 +75,19 @@ class WebRtcCallManager @Inject constructor(
|
||||||
fun onPSTNSupportUpdated()
|
fun onPSTNSupportUpdated()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val pstnSupportListeners = emptyList<PSTNSupportListener>().toMutableList()
|
val supportedPSTNProtocol: String?
|
||||||
|
get() = pstnProtocolChecker.supportedPSTNProtocol
|
||||||
|
|
||||||
|
val supportsPSTNProtocol: Boolean
|
||||||
|
get() = supportedPSTNProtocol != null
|
||||||
|
|
||||||
|
|
||||||
fun addPstnSupportListener(listener: PSTNSupportListener) {
|
fun addPstnSupportListener(listener: PSTNSupportListener) {
|
||||||
pstnSupportListeners.add(listener)
|
pstnProtocolChecker.addPstnSupportListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removePstnSupportListener(listener: PSTNSupportListener) {
|
fun removePstnSupportListener(listener: PSTNSupportListener) {
|
||||||
pstnSupportListeners.remove(listener)
|
pstnProtocolChecker.removePstnSupportListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val currentCallsListeners = CopyOnWriteArrayList<CurrentCallListener>()
|
private val currentCallsListeners = CopyOnWriteArrayList<CurrentCallListener>()
|
||||||
|
@ -104,30 +111,16 @@ class WebRtcCallManager @Inject constructor(
|
||||||
private var peerConnectionFactory: PeerConnectionFactory? = null
|
private var peerConnectionFactory: PeerConnectionFactory? = null
|
||||||
private val executor = Executors.newSingleThreadExecutor()
|
private val executor = Executors.newSingleThreadExecutor()
|
||||||
private val dispatcher = executor.asCoroutineDispatcher()
|
private val dispatcher = executor.asCoroutineDispatcher()
|
||||||
var supportedPSTNProtocol: String? = null
|
|
||||||
private set
|
|
||||||
|
|
||||||
val supportsPSTNProtocol: Boolean
|
|
||||||
get() = supportedPSTNProtocol != null
|
|
||||||
|
|
||||||
private val rootEglBase by lazy { EglUtils.rootEglBase }
|
private val rootEglBase by lazy { EglUtils.rootEglBase }
|
||||||
|
|
||||||
private var isInBackground: Boolean = true
|
private var isInBackground: Boolean = true
|
||||||
|
|
||||||
init {
|
|
||||||
GlobalScope.launch {
|
|
||||||
supportedPSTNProtocol = currentSession?.getSupportedPSTN(3)
|
|
||||||
if (supportedPSTNProtocol != null) {
|
|
||||||
pstnSupportListeners.forEach {
|
|
||||||
tryOrNull { it.onPSTNSupportUpdated() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||||
fun entersForeground() {
|
fun entersForeground() {
|
||||||
isInBackground = false
|
isInBackground = false
|
||||||
|
checkForPSTNSupportIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
|
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
|
||||||
|
@ -167,6 +160,10 @@ class WebRtcCallManager @Inject constructor(
|
||||||
return callsByCallId.values.toList()
|
return callsByCallId.values.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun checkForPSTNSupportIfNeeded() {
|
||||||
|
pstnProtocolChecker.checkForPSTNSupportIfNeeded(currentSession)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a set of all advertised call during the lifetime of the app.
|
* @return a set of all advertised call during the lifetime of the app.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -177,6 +177,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
// Inform the SDK that the room is displayed
|
// Inform the SDK that the room is displayed
|
||||||
session.onRoomDisplayed(initialState.roomId)
|
session.onRoomDisplayed(initialState.roomId)
|
||||||
callManager.addPstnSupportListener(this)
|
callManager.addPstnSupportListener(this)
|
||||||
|
callManager.checkForPSTNSupportIfNeeded()
|
||||||
chatEffectManager.delegate = this
|
chatEffectManager.delegate = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue