diff --git a/CHANGES.md b/CHANGES.md index 0e2d231e26..fe88aed5ab 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,7 @@ Improvements 🙌: Bugfix 🐛: - Fixed ringtone handling (#2100 & #2246) - Messages encrypted with no way to decrypt after SDK update from 0.18 to 1.0.0 (#2252) + - Incoming call continues to ring if call is answered on another device (#1921) - Search Result | scroll jumps after pagination (#2238) Translations 🗣: diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt index 4f89763cda..5be313d719 100644 --- a/vector/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector/src/main/java/im/vector/app/VectorApplication.kt @@ -42,6 +42,7 @@ import im.vector.app.core.di.HasVectorInjector import im.vector.app.core.di.VectorComponent import im.vector.app.core.extensions.configureAndStart import im.vector.app.core.rx.RxConfig +import im.vector.app.features.call.WebRtcPeerConnectionManager import im.vector.app.features.configuration.VectorConfiguration import im.vector.app.features.disclaimer.doNotShowDisclaimerDialog import im.vector.app.features.lifecycle.VectorActivityLifecycleCallbacks @@ -89,6 +90,7 @@ class VectorApplication : @Inject lateinit var rxConfig: RxConfig @Inject lateinit var popupAlertManager: PopupAlertManager @Inject lateinit var pinLocker: PinLocker + @Inject lateinit var webRtcPeerConnectionManager: WebRtcPeerConnectionManager lateinit var vectorComponent: VectorComponent @@ -173,6 +175,7 @@ class VectorApplication : }) ProcessLifecycleOwner.get().lifecycle.addObserver(appStateHandler) ProcessLifecycleOwner.get().lifecycle.addObserver(pinLocker) + ProcessLifecycleOwner.get().lifecycle.addObserver(webRtcPeerConnectionManager) // This should be done as early as possible // initKnownEmojiHashSet(appContext) diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt index edb75441c8..445f40e5b1 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt @@ -88,6 +88,11 @@ class VectorCallViewModel @AssistedInject constructor( private val currentCallListener = object : WebRtcPeerConnectionManager.CurrentCallListener { override fun onCurrentCallChange(call: MxCall?) { + // we need to check the state + if (call == null) { + // we should dismiss, e.g handled by other session? + _viewEvents.post(VectorCallViewEvents.DismissNoCall) + } } override fun onCaptureStateChanged() { diff --git a/vector/src/main/java/im/vector/app/features/call/WebRtcPeerConnectionManager.kt b/vector/src/main/java/im/vector/app/features/call/WebRtcPeerConnectionManager.kt index c70b52b09b..86b38c1158 100644 --- a/vector/src/main/java/im/vector/app/features/call/WebRtcPeerConnectionManager.kt +++ b/vector/src/main/java/im/vector/app/features/call/WebRtcPeerConnectionManager.kt @@ -19,10 +19,14 @@ package im.vector.app.features.call import android.content.Context import android.hardware.camera2.CameraManager import androidx.core.content.getSystemService +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent import im.vector.app.ActiveSessionDataSource import im.vector.app.core.services.BluetoothHeadsetReceiver import im.vector.app.core.services.CallService import im.vector.app.core.services.WiredHeadsetStateReceiver +import im.vector.app.push.fcm.FcmHelper import io.reactivex.disposables.Disposable import io.reactivex.subjects.PublishSubject import io.reactivex.subjects.ReplaySubject @@ -72,7 +76,7 @@ import javax.inject.Singleton class WebRtcPeerConnectionManager @Inject constructor( private val context: Context, private val activeSessionDataSource: ActiveSessionDataSource -) : CallsListener { +) : CallsListener, LifecycleObserver { private val currentSession: Session? get() = activeSessionDataSource.currentValue?.orNull() @@ -170,6 +174,8 @@ class WebRtcPeerConnectionManager @Inject constructor( private var currentCaptureMode: CaptureFormat = CaptureFormat.HD + private var isInBackground: Boolean = true + var capturerIsInError = false set(value) { field = value @@ -201,6 +207,16 @@ class WebRtcPeerConnectionManager @Inject constructor( } } + @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) + fun entersForeground() { + isInBackground = false + } + + @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) + fun entersBackground() { + isInBackground = true + } + var currentCall: CallContext? = null set(value) { field = value @@ -702,6 +718,18 @@ class WebRtcPeerConnectionManager @Inject constructor( ) callContext.offerSdp = callInviteContent.offer + + // If this is received while in background, the app will not sync, + // and thus won't be able to received events. For example if the call is + // accepted on an other session this device will continue ringing + if (isInBackground) { + if (FcmHelper.isPushSupported()) { + // only for push version as fdroid version is already doing it? + currentSession?.startAutomaticBackgroundSync(30, 0) + } else { + // Maybe increase sync freq? but how to set back to default values? + } + } } private fun createAnswer() { @@ -849,6 +877,16 @@ class WebRtcPeerConnectionManager @Inject constructor( Timber.v("## VOIP onCallManagedByOtherSession: $callId") currentCall = null CallService.onNoActiveCall(context) + + // did we start background sync? so we should stop it + if (isInBackground) { + if (FcmHelper.isPushSupported()) { + currentSession?.stopAnyBackgroundSync() + } else { + // for fdroid we should not stop, it should continue syncing + // maybe we should restore default timeout/delay though? + } + } } private inner class StreamObserver(val callContext: CallContext) : PeerConnection.Observer {