mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-04-25 22:08:38 +00:00
Started to add video to conference participants + fixed call ended fragment timer
This commit is contained in:
parent
2eb8b496cd
commit
aa52f3d2b5
9 changed files with 177 additions and 15 deletions
|
|
@ -44,6 +44,7 @@ import org.linphone.R
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
import org.linphone.databinding.CallActivityBinding
|
import org.linphone.databinding.CallActivityBinding
|
||||||
import org.linphone.ui.call.fragment.ActiveCallFragmentDirections
|
import org.linphone.ui.call.fragment.ActiveCallFragmentDirections
|
||||||
|
import org.linphone.ui.call.fragment.ActiveConferenceCallFragmentDirections
|
||||||
import org.linphone.ui.call.fragment.AudioDevicesMenuDialogFragment
|
import org.linphone.ui.call.fragment.AudioDevicesMenuDialogFragment
|
||||||
import org.linphone.ui.call.fragment.IncomingCallFragmentDirections
|
import org.linphone.ui.call.fragment.IncomingCallFragmentDirections
|
||||||
import org.linphone.ui.call.fragment.OutgoingCallFragmentDirections
|
import org.linphone.ui.call.fragment.OutgoingCallFragmentDirections
|
||||||
|
|
@ -187,17 +188,50 @@ class CallActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
callsViewModel.goToActiveCallEvent.observe(this) {
|
callsViewModel.goToActiveCallEvent.observe(this) {
|
||||||
it.consume {
|
it.consume { singleCall ->
|
||||||
val navController = findNavController(R.id.call_nav_container)
|
val navController = findNavController(R.id.call_nav_container)
|
||||||
val action = when (navController.currentDestination?.id) {
|
val action = when (navController.currentDestination?.id) {
|
||||||
R.id.outgoingCallFragment -> {
|
R.id.outgoingCallFragment -> {
|
||||||
OutgoingCallFragmentDirections.actionOutgoingCallFragmentToActiveCallFragment()
|
if (singleCall) {
|
||||||
|
Log.i("$TAG Going from outgoing call fragment to call fragment")
|
||||||
|
OutgoingCallFragmentDirections.actionOutgoingCallFragmentToActiveCallFragment()
|
||||||
|
} else {
|
||||||
|
Log.i(
|
||||||
|
"$TAG Going from outgoing call fragment to conference call fragment"
|
||||||
|
)
|
||||||
|
OutgoingCallFragmentDirections.actionOutgoingCallFragmentToActiveConferenceCallFragment()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
R.id.incomingCallFragment -> {
|
R.id.incomingCallFragment -> {
|
||||||
IncomingCallFragmentDirections.actionIncomingCallFragmentToActiveCallFragment()
|
if (singleCall) {
|
||||||
|
Log.i("$TAG Going from incoming call fragment to call fragment")
|
||||||
|
IncomingCallFragmentDirections.actionIncomingCallFragmentToActiveCallFragment()
|
||||||
|
} else {
|
||||||
|
Log.i(
|
||||||
|
"$TAG Going from incoming call fragment to conference call fragment"
|
||||||
|
)
|
||||||
|
IncomingCallFragmentDirections.actionIncomingCallFragmentToActiveConferenceCallFragment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
R.id.activeConferenceCallFragment -> {
|
||||||
|
if (singleCall) {
|
||||||
|
Log.i("$TAG Going from conference call fragment to call fragment")
|
||||||
|
ActiveConferenceCallFragmentDirections.actionActiveConferenceCallFragmentToActiveCallFragment()
|
||||||
|
} else {
|
||||||
|
Log.i(
|
||||||
|
"$TAG Going from conference call fragment to conference call fragment"
|
||||||
|
)
|
||||||
|
ActiveConferenceCallFragmentDirections.actionGlobalActiveConferenceCallFragment()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
ActiveCallFragmentDirections.actionGlobalActiveCallFragment()
|
if (singleCall) {
|
||||||
|
Log.i("$TAG Going from call fragment to call fragment")
|
||||||
|
ActiveCallFragmentDirections.actionGlobalActiveCallFragment()
|
||||||
|
} else {
|
||||||
|
Log.i("$TAG Going from call fragment to conference call fragment")
|
||||||
|
ActiveCallFragmentDirections.actionActiveCallFragmentToActiveConferenceCallFragment()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
navController.navigate(action)
|
navController.navigate(action)
|
||||||
|
|
|
||||||
|
|
@ -253,9 +253,12 @@ class ActiveCallFragment : GenericCallFragment() {
|
||||||
|
|
||||||
callViewModel.goToConferenceEvent.observe(viewLifecycleOwner) {
|
callViewModel.goToConferenceEvent.observe(viewLifecycleOwner) {
|
||||||
it.consume {
|
it.consume {
|
||||||
Log.i("$TAG Going to conference fragment")
|
if (findNavController().currentDestination?.id == R.id.activeCallFragment) {
|
||||||
val action = ActiveCallFragmentDirections.actionActiveCallFragmentToActiveConferenceCallFragment()
|
Log.i("$TAG Going to conference fragment")
|
||||||
findNavController().navigate(action)
|
val action =
|
||||||
|
ActiveCallFragmentDirections.actionActiveCallFragmentToActiveConferenceCallFragment()
|
||||||
|
findNavController().navigate(action)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,15 @@
|
||||||
*/
|
*/
|
||||||
package org.linphone.ui.call.model
|
package org.linphone.ui.call.model
|
||||||
|
|
||||||
|
import android.view.TextureView
|
||||||
|
import androidx.annotation.UiThread
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||||
|
import org.linphone.core.MediaDirection
|
||||||
import org.linphone.core.ParticipantDevice
|
import org.linphone.core.ParticipantDevice
|
||||||
import org.linphone.core.ParticipantDeviceListenerStub
|
import org.linphone.core.ParticipantDeviceListenerStub
|
||||||
|
import org.linphone.core.StreamType
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
|
|
||||||
class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
||||||
|
|
@ -40,7 +44,14 @@ class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
||||||
|
|
||||||
val isSpeaking = MutableLiveData<Boolean>()
|
val isSpeaking = MutableLiveData<Boolean>()
|
||||||
|
|
||||||
|
val isVideoAvailable = MutableLiveData<Boolean>()
|
||||||
|
|
||||||
|
val isSendingVideo = MutableLiveData<Boolean>()
|
||||||
|
|
||||||
|
private lateinit var textureView: TextureView
|
||||||
|
|
||||||
private val deviceListener = object : ParticipantDeviceListenerStub() {
|
private val deviceListener = object : ParticipantDeviceListenerStub() {
|
||||||
|
@WorkerThread
|
||||||
override fun onStateChanged(
|
override fun onStateChanged(
|
||||||
participantDevice: ParticipantDevice,
|
participantDevice: ParticipantDevice,
|
||||||
state: ParticipantDevice.State?
|
state: ParticipantDevice.State?
|
||||||
|
|
@ -50,6 +61,7 @@ class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
override fun onIsMuted(participantDevice: ParticipantDevice, muted: Boolean) {
|
override fun onIsMuted(participantDevice: ParticipantDevice, muted: Boolean) {
|
||||||
Log.i(
|
Log.i(
|
||||||
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] is ${if (participantDevice.isMuted) "muted" else "no longer muted"}"
|
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] is ${if (participantDevice.isMuted) "muted" else "no longer muted"}"
|
||||||
|
|
@ -57,6 +69,7 @@ class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
||||||
isMuted.postValue(participantDevice.isMuted)
|
isMuted.postValue(participantDevice.isMuted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
override fun onIsSpeakingChanged(
|
override fun onIsSpeakingChanged(
|
||||||
participantDevice: ParticipantDevice,
|
participantDevice: ParticipantDevice,
|
||||||
speaking: Boolean
|
speaking: Boolean
|
||||||
|
|
@ -66,6 +79,41 @@ class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
||||||
)
|
)
|
||||||
isSpeaking.postValue(participantDevice.isSpeaking)
|
isSpeaking.postValue(participantDevice.isSpeaking)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
override fun onStreamAvailabilityChanged(
|
||||||
|
participantDevice: ParticipantDevice,
|
||||||
|
available: Boolean,
|
||||||
|
streamType: StreamType?
|
||||||
|
) {
|
||||||
|
Log.i(
|
||||||
|
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] stream [$streamType] availability changed to ${if (available) "available" else "not available"}"
|
||||||
|
)
|
||||||
|
if (streamType == StreamType.Video) {
|
||||||
|
val available = participantDevice.getStreamAvailability(StreamType.Video)
|
||||||
|
isVideoAvailable.postValue(available)
|
||||||
|
if (available) {
|
||||||
|
updateWindowId(textureView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
override fun onStreamCapabilityChanged(
|
||||||
|
participantDevice: ParticipantDevice,
|
||||||
|
direction: MediaDirection?,
|
||||||
|
streamType: StreamType?
|
||||||
|
) {
|
||||||
|
Log.i(
|
||||||
|
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] stream [$streamType] capability changed to [$direction]"
|
||||||
|
)
|
||||||
|
if (streamType == StreamType.Video) {
|
||||||
|
val videoCapability = participantDevice.getStreamCapability(StreamType.Video)
|
||||||
|
isSendingVideo.postValue(
|
||||||
|
videoCapability == MediaDirection.SendRecv || videoCapability == MediaDirection.SendOnly
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
@ -76,10 +124,35 @@ class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
||||||
Log.i(
|
Log.i(
|
||||||
"$TAG Participant [${device.address.asStringUriOnly()}] is in state [${device.state}]"
|
"$TAG Participant [${device.address.asStringUriOnly()}] is in state [${device.state}]"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
isVideoAvailable.postValue(device.getStreamAvailability(StreamType.Video))
|
||||||
|
val videoCapability = device.getStreamCapability(StreamType.Video)
|
||||||
|
isSendingVideo.postValue(
|
||||||
|
videoCapability == MediaDirection.SendRecv || videoCapability == MediaDirection.SendOnly
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
fun destroy() {
|
fun destroy() {
|
||||||
device.removeListener(deviceListener)
|
device.removeListener(deviceListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
fun setTextureView(view: TextureView) {
|
||||||
|
Log.i(
|
||||||
|
"$TAG TextureView for participant [${device.address.asStringUriOnly()}] available from UI [$view]"
|
||||||
|
)
|
||||||
|
textureView = view
|
||||||
|
coreContext.postOnCoreThread {
|
||||||
|
updateWindowId(textureView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
private fun updateWindowId(windowId: Any?) {
|
||||||
|
Log.i(
|
||||||
|
"$$TAG Setting participant [${device.address.asStringUriOnly()}] window ID [$windowId]"
|
||||||
|
)
|
||||||
|
device.nativeVideoWindowId = windowId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ class CallsViewModel @UiThread constructor() : ViewModel() {
|
||||||
)
|
)
|
||||||
when (call.state) {
|
when (call.state) {
|
||||||
Call.State.Connected -> {
|
Call.State.Connected -> {
|
||||||
goToActiveCallEvent.postValue(Event(true))
|
goToActiveCallEvent.postValue(Event(call.conference == null))
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
}
|
}
|
||||||
|
|
@ -132,8 +132,15 @@ class CallsViewModel @UiThread constructor() : ViewModel() {
|
||||||
Log.i("$TAG Asking activity to show incoming call fragment")
|
Log.i("$TAG Asking activity to show incoming call fragment")
|
||||||
showIncomingCallEvent.postValue(Event(true))
|
showIncomingCallEvent.postValue(Event(true))
|
||||||
} else {
|
} else {
|
||||||
Log.i("$TAG Asking activity to show active call fragment")
|
if (newCurrentCall.conference == null) {
|
||||||
goToActiveCallEvent.postValue(Event(true))
|
Log.i("$TAG Asking activity to show active call fragment")
|
||||||
|
goToActiveCallEvent.postValue(Event(true))
|
||||||
|
} else {
|
||||||
|
Log.i(
|
||||||
|
"$TAG Asking activity to show active conference call fragment"
|
||||||
|
)
|
||||||
|
goToActiveCallEvent.postValue(Event(false))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -160,7 +167,7 @@ class CallsViewModel @UiThread constructor() : ViewModel() {
|
||||||
|
|
||||||
when (currentCall.state) {
|
when (currentCall.state) {
|
||||||
Call.State.Connected, Call.State.StreamsRunning, Call.State.Paused, Call.State.Pausing, Call.State.PausedByRemote, Call.State.UpdatedByRemote, Call.State.Updating -> {
|
Call.State.Connected, Call.State.StreamsRunning, Call.State.Paused, Call.State.Pausing, Call.State.PausedByRemote, Call.State.UpdatedByRemote, Call.State.Updating -> {
|
||||||
goToActiveCallEvent.postValue(Event(true))
|
goToActiveCallEvent.postValue(Event(currentCall.conference == null))
|
||||||
}
|
}
|
||||||
Call.State.OutgoingInit, Call.State.OutgoingRinging, Call.State.OutgoingProgress, Call.State.OutgoingEarlyMedia -> {
|
Call.State.OutgoingInit, Call.State.OutgoingRinging, Call.State.OutgoingProgress, Call.State.OutgoingEarlyMedia -> {
|
||||||
showOutgoingCallEvent.postValue(Event(true))
|
showOutgoingCallEvent.postValue(Event(true))
|
||||||
|
|
|
||||||
|
|
@ -210,9 +210,11 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() {
|
||||||
Log.e(
|
Log.e(
|
||||||
"$TAG Failed to get a valid call to display, go to ended call fragment"
|
"$TAG Failed to get a valid call to display, go to ended call fragment"
|
||||||
)
|
)
|
||||||
|
updateCallDuration()
|
||||||
goToEndedCallEvent.postValue(Event(true))
|
goToEndedCallEvent.postValue(Event(true))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
updateCallDuration()
|
||||||
Log.i("$TAG Call is ending, go to ended call fragment")
|
Log.i("$TAG Call is ending, go to ended call fragment")
|
||||||
// Show that call was ended for a few seconds, then leave
|
// Show that call was ended for a few seconds, then leave
|
||||||
// TODO FIXME: do not show it when call is being ended due to user terminating the call
|
// TODO FIXME: do not show it when call is being ended due to user terminating the call
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import org.linphone.core.ConferenceInfo
|
||||||
import org.linphone.core.Core
|
import org.linphone.core.Core
|
||||||
import org.linphone.core.CoreListenerStub
|
import org.linphone.core.CoreListenerStub
|
||||||
import org.linphone.core.Factory
|
import org.linphone.core.Factory
|
||||||
|
import org.linphone.core.MediaDirection
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
import org.linphone.ui.main.contacts.model.ContactAvatarModel
|
import org.linphone.ui.main.contacts.model.ContactAvatarModel
|
||||||
import org.linphone.utils.Event
|
import org.linphone.utils.Event
|
||||||
|
|
@ -135,6 +136,10 @@ class MeetingWaitingRoomViewModel @UiThread constructor() : ViewModel() {
|
||||||
fun join() {
|
fun join() {
|
||||||
coreContext.postOnCoreThread { core ->
|
coreContext.postOnCoreThread { core ->
|
||||||
if (::conferenceInfo.isInitialized) {
|
if (::conferenceInfo.isInitialized) {
|
||||||
|
Log.i("$TAG Stopping video preview")
|
||||||
|
core.nativePreviewWindowId = null
|
||||||
|
core.isVideoPreviewEnabled = false
|
||||||
|
|
||||||
val conferenceUri = conferenceInfo.uri
|
val conferenceUri = conferenceInfo.uri
|
||||||
if (conferenceUri == null) {
|
if (conferenceUri == null) {
|
||||||
Log.e("$TAG Conference Info doesn't have a conference SIP URI to call!")
|
Log.e("$TAG Conference Info doesn't have a conference SIP URI to call!")
|
||||||
|
|
@ -144,7 +149,8 @@ class MeetingWaitingRoomViewModel @UiThread constructor() : ViewModel() {
|
||||||
val params = core.createCallParams(null)
|
val params = core.createCallParams(null)
|
||||||
params ?: return@postOnCoreThread
|
params ?: return@postOnCoreThread
|
||||||
|
|
||||||
params.isVideoEnabled = isVideoEnabled.value == true
|
params.isVideoEnabled = true
|
||||||
|
params.videoDirection = if (isVideoEnabled.value == true) MediaDirection.SendRecv else MediaDirection.RecvOnly
|
||||||
params.isMicEnabled = isMicrophoneMuted.value == false
|
params.isMicEnabled = isMicrophoneMuted.value == false
|
||||||
params.account = core.defaultAccount
|
params.account = core.defaultAccount
|
||||||
coreContext.startCall(conferenceUri, params)
|
coreContext.startCall(conferenceUri, params)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import android.graphics.PorterDuff
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.TextureView
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
|
|
@ -62,6 +63,7 @@ import org.linphone.contacts.AvatarGenerator
|
||||||
import org.linphone.core.ChatRoom
|
import org.linphone.core.ChatRoom
|
||||||
import org.linphone.core.ConsolidatedPresence
|
import org.linphone.core.ConsolidatedPresence
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
|
import org.linphone.ui.call.model.ConferenceParticipantDeviceModel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file contains all the data binding necessary for the app
|
* This file contains all the data binding necessary for the app
|
||||||
|
|
@ -376,6 +378,15 @@ private suspend fun loadContactPictureWithCoil(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@BindingAdapter("participantTextureView")
|
||||||
|
fun setParticipantTextureView(
|
||||||
|
textureView: TextureView,
|
||||||
|
model: ConferenceParticipantDeviceModel
|
||||||
|
) {
|
||||||
|
model.setTextureView(textureView)
|
||||||
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@BindingAdapter("onValueChanged")
|
@BindingAdapter("onValueChanged")
|
||||||
fun AppCompatEditText.editTextSetting(lambda: () -> Unit) {
|
fun AppCompatEditText.editTextSetting(lambda: () -> Unit) {
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,10 @@
|
||||||
android:id="@+id/participant_video_surface"
|
android:id="@+id/participant_video_surface"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_margin="5dp"
|
|
||||||
app:alignTopRight="false"
|
app:alignTopRight="false"
|
||||||
app:displayMode="hybrid"
|
app:displayMode="hybrid"
|
||||||
|
participantTextureView="@{model}"
|
||||||
|
android:visibility="@{model.isSendingVideo ? View.VISIBLE : View.GONE, default=gone}"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|
@ -66,7 +67,7 @@
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:padding="2dp"
|
android:padding="2dp"
|
||||||
android:src="@drawable/microphone_slash"
|
android:src="@drawable/microphone_slash"
|
||||||
android:background="@drawable/circle_white_button_background"
|
android:background="@drawable/shape_circle_white_background"
|
||||||
android:visibility="@{model.isMuted ? View.VISIBLE : View.GONE}"
|
android:visibility="@{model.isMuted ? View.VISIBLE : View.GONE}"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,12 @@
|
||||||
app:popUpTo="@id/outgoingCallFragment"
|
app:popUpTo="@id/outgoingCallFragment"
|
||||||
app:popUpToInclusive="true"
|
app:popUpToInclusive="true"
|
||||||
app:launchSingleTop="true"/>
|
app:launchSingleTop="true"/>
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_outgoingCallFragment_to_activeConferenceCallFragment"
|
||||||
|
app:destination="@id/activeConferenceCallFragment"
|
||||||
|
app:popUpTo="@id/outgoingCallFragment"
|
||||||
|
app:popUpToInclusive="true"
|
||||||
|
app:launchSingleTop="true" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<action android:id="@+id/action_global_outgoingCallFragment"
|
<action android:id="@+id/action_global_outgoingCallFragment"
|
||||||
|
|
@ -35,6 +41,12 @@
|
||||||
app:popUpTo="@id/incomingCallFragment"
|
app:popUpTo="@id/incomingCallFragment"
|
||||||
app:popUpToInclusive="true"
|
app:popUpToInclusive="true"
|
||||||
app:launchSingleTop="true" />
|
app:launchSingleTop="true" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_incomingCallFragment_to_activeConferenceCallFragment"
|
||||||
|
app:destination="@id/activeConferenceCallFragment"
|
||||||
|
app:popUpTo="@id/outgoingCallFragment"
|
||||||
|
app:popUpToInclusive="true"
|
||||||
|
app:launchSingleTop="true" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<action android:id="@+id/action_global_incomingCallFragment"
|
<action android:id="@+id/action_global_incomingCallFragment"
|
||||||
|
|
@ -114,6 +126,19 @@
|
||||||
android:id="@+id/activeConferenceCallFragment"
|
android:id="@+id/activeConferenceCallFragment"
|
||||||
android:name="org.linphone.ui.call.fragment.ActiveConferenceCallFragment"
|
android:name="org.linphone.ui.call.fragment.ActiveConferenceCallFragment"
|
||||||
android:label="ActiveConferenceCallFragment"
|
android:label="ActiveConferenceCallFragment"
|
||||||
tools:layout="@layout/call_active_conference_fragment"/>
|
tools:layout="@layout/call_active_conference_fragment">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_activeConferenceCallFragment_to_activeCallFragment"
|
||||||
|
app:destination="@id/activeCallFragment"
|
||||||
|
app:popUpTo="@id/activeConferenceCallFragment"
|
||||||
|
app:popUpToInclusive="true"
|
||||||
|
app:launchSingleTop="true" />
|
||||||
|
</fragment>
|
||||||
|
|
||||||
|
<action android:id="@+id/action_global_activeConferenceCallFragment"
|
||||||
|
app:destination="@id/activeConferenceCallFragment"
|
||||||
|
app:popUpTo="@id/activeConferenceCallFragment"
|
||||||
|
app:popUpToInclusive="true"
|
||||||
|
app:launchSingleTop="true"/>
|
||||||
|
|
||||||
</navigation>
|
</navigation>
|
||||||
Loading…
Add table
Reference in a new issue