Added 30 secs timeout to call update dialog
This commit is contained in:
parent
74cd0f1bf8
commit
932a3a7265
5 changed files with 71 additions and 19 deletions
|
@ -29,6 +29,7 @@ import android.view.ViewGroup
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import java.util.*
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.call.viewmodels.CallsViewModel
|
||||
import org.linphone.activities.call.viewmodels.ControlsViewModel
|
||||
|
@ -47,6 +48,8 @@ class ControlsFragment : Fragment() {
|
|||
private lateinit var controlsViewModel: ControlsViewModel
|
||||
private lateinit var sharedViewModel: SharedCallViewModel
|
||||
|
||||
private var dialog: Dialog? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
|
@ -87,7 +90,11 @@ class ControlsFragment : Fragment() {
|
|||
|
||||
callsViewModel.callUpdateEvent.observe(viewLifecycleOwner, Observer {
|
||||
it.consume { call ->
|
||||
showCallUpdateDialog(call)
|
||||
if (call.state == Call.State.StreamsRunning) {
|
||||
dialog?.dismiss()
|
||||
} else if (call.state == Call.State.UpdatedByRemote) {
|
||||
showCallUpdateDialog(call)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -132,18 +139,18 @@ class ControlsFragment : Fragment() {
|
|||
|
||||
private fun showCallUpdateDialog(call: Call) {
|
||||
val viewModel = DialogViewModel(AppUtils.getString(R.string.call_video_update_requested_dialog))
|
||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||
dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||
|
||||
viewModel.showCancelButton({
|
||||
callsViewModel.answerCallUpdateRequest(call, false)
|
||||
dialog.dismiss()
|
||||
dialog?.dismiss()
|
||||
}, getString(R.string.dialog_decline))
|
||||
|
||||
viewModel.showOkButton({
|
||||
callsViewModel.answerCallUpdateRequest(call, true)
|
||||
dialog.dismiss()
|
||||
dialog?.dismiss()
|
||||
}, getString(R.string.dialog_accept))
|
||||
|
||||
dialog.show()
|
||||
dialog?.show()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@ package org.linphone.activities.call.viewmodels
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import java.util.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.contact.GenericContactViewModel
|
||||
import org.linphone.core.Call
|
||||
|
@ -54,6 +59,8 @@ open class CallViewModel(val call: Call) : GenericContactViewModel(call.remoteAd
|
|||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
private var timer: Timer? = null
|
||||
|
||||
private val listener = object : CallListenerStub() {
|
||||
override fun onStateChanged(call: Call, state: Call.State, message: String) {
|
||||
if (call != this@CallViewModel.call) return
|
||||
|
@ -61,6 +68,7 @@ open class CallViewModel(val call: Call) : GenericContactViewModel(call.remoteAd
|
|||
isPaused.value = state == Call.State.Paused
|
||||
|
||||
if (state == Call.State.End || state == Call.State.Released || state == Call.State.Error) {
|
||||
timer?.cancel()
|
||||
callEndedEvent.value = Event(true)
|
||||
|
||||
if (state == Call.State.Error) {
|
||||
|
@ -68,6 +76,13 @@ open class CallViewModel(val call: Call) : GenericContactViewModel(call.remoteAd
|
|||
}
|
||||
} else if (call.state == Call.State.Connected) {
|
||||
callConnectedEvent.value = Event(true)
|
||||
} else if (call.state == Call.State.StreamsRunning) {
|
||||
// Stop call update timer once user has accepted or declined call update
|
||||
timer?.cancel()
|
||||
} else if (call.state == Call.State.UpdatedByRemote) {
|
||||
// User has 30 secs to accept or decline call update
|
||||
// Dialog to accept or decline is handled by CallsViewModel & ControlsFragment
|
||||
startTimer(call)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,4 +118,20 @@ open class CallViewModel(val call: Call) : GenericContactViewModel(call.remoteAd
|
|||
if (call.core.conferenceSize <= 1) call.core.leaveConference()
|
||||
}
|
||||
}
|
||||
|
||||
private fun startTimer(call: Call) {
|
||||
timer?.cancel()
|
||||
|
||||
timer = Timer("Call update timeout")
|
||||
timer?.schedule(object : TimerTask() {
|
||||
override fun run() {
|
||||
// Decline call update
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.Main) {
|
||||
coreContext.answerCallUpdateRequest(call, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 30000)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,17 +76,20 @@ class CallsViewModel : ViewModel() {
|
|||
} else if (state == Call.State.Resuming) {
|
||||
removeCallFromPausedListIfPresent(call)
|
||||
} else if (call.state == Call.State.UpdatedByRemote) {
|
||||
// If the correspondent proposes video while audio call,
|
||||
// If the correspondent asks to turn on video while audio call,
|
||||
// defer update until user has chosen whether to accept it or not
|
||||
val remoteVideo = call.remoteParams?.videoEnabled() ?: false
|
||||
val localVideo = call.currentParams.videoEnabled()
|
||||
val autoAccept = call.core.videoActivationPolicy.automaticallyAccept
|
||||
if (remoteVideo && !localVideo && !autoAccept) {
|
||||
call.deferUpdate()
|
||||
// TODO: start 30 secs timer and decline update if no answer when it triggers
|
||||
callUpdateEvent.value = Event(call)
|
||||
}
|
||||
} else {
|
||||
if (state == Call.State.StreamsRunning) {
|
||||
callUpdateEvent.value = Event(call)
|
||||
}
|
||||
|
||||
if (call.conference != null) {
|
||||
addCallToConferenceListIfNotAlreadyInIt(call)
|
||||
} else {
|
||||
|
@ -126,16 +129,7 @@ class CallsViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
fun answerCallUpdateRequest(call: Call, accept: Boolean) {
|
||||
val core = call.core
|
||||
val params = core.createCallParams(call)
|
||||
|
||||
if (accept) {
|
||||
params?.enableVideo(true)
|
||||
core.enableVideoCapture(true)
|
||||
core.enableVideoDisplay(true)
|
||||
}
|
||||
|
||||
call.acceptUpdate(params)
|
||||
coreContext.answerCallUpdateRequest(call, accept)
|
||||
}
|
||||
|
||||
fun pauseConference() {
|
||||
|
|
|
@ -22,6 +22,10 @@ package org.linphone.activities.call.viewmodels
|
|||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.*
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.core.AudioDevice
|
||||
|
@ -119,8 +123,12 @@ class ControlsFadingViewModel : ViewModel() {
|
|||
timer = Timer("Hide UI controls scheduler")
|
||||
timer?.schedule(object : TimerTask() {
|
||||
override fun run() {
|
||||
val videoEnabled = coreContext.isVideoCallOrConferenceActive()
|
||||
areControlsHidden.postValue(videoEnabled)
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.Main) {
|
||||
val videoEnabled = coreContext.isVideoCallOrConferenceActive()
|
||||
areControlsHidden.postValue(videoEnabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 3000)
|
||||
}
|
||||
|
|
|
@ -299,6 +299,18 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
|||
|
||||
/* Call related functions */
|
||||
|
||||
fun answerCallUpdateRequest(call: Call, accept: Boolean) {
|
||||
val params = core.createCallParams(call)
|
||||
|
||||
if (accept) {
|
||||
params?.enableVideo(true)
|
||||
core.enableVideoCapture(true)
|
||||
core.enableVideoDisplay(true)
|
||||
}
|
||||
|
||||
call.acceptUpdate(params)
|
||||
}
|
||||
|
||||
fun answerCall(call: Call) {
|
||||
Log.i("[Context] Answering call $call")
|
||||
val params = core.createCallParams(call)
|
||||
|
|
Loading…
Reference in a new issue