diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/CallsListFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/CallsListFragment.kt index b171657c6..39a8b0e03 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/CallsListFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/CallsListFragment.kt @@ -27,21 +27,21 @@ import android.view.View import android.widget.PopupWindow import androidx.databinding.DataBindingUtil import androidx.navigation.navGraphViewModels -import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R -import org.linphone.activities.GenericFragment import org.linphone.activities.main.MainActivity import org.linphone.activities.voip.ConferenceDisplayMode import org.linphone.activities.voip.data.CallData import org.linphone.activities.voip.viewmodels.CallsViewModel import org.linphone.activities.voip.viewmodels.ConferenceViewModel +import org.linphone.activities.voip.viewmodels.ControlsViewModel import org.linphone.databinding.VoipCallContextMenuBindingImpl import org.linphone.databinding.VoipCallsListFragmentBinding import org.linphone.utils.AppUtils -class CallsListFragment : GenericFragment() { +class CallsListFragment : GenericVideoPreviewFragment() { private val callsViewModel: CallsViewModel by navGraphViewModels(R.id.call_nav_graph) private val conferenceViewModel: ConferenceViewModel by navGraphViewModels(R.id.call_nav_graph) + private val controlsViewModel: ControlsViewModel by navGraphViewModels(R.id.call_nav_graph) override fun getLayoutId(): Int = R.layout.voip_calls_list_fragment @@ -57,8 +57,13 @@ class CallsListFragment : GenericFragment() { binding.lifecycleOwner = viewLifecycleOwner binding.callsViewModel = callsViewModel + binding.conferenceViewModel = conferenceViewModel + binding.controlsViewModel = controlsViewModel + + setupLocalViewPreview(binding.localPreviewVideoSurface, binding.switchCamera) + binding.setCancelClickListener { goBack() } @@ -91,12 +96,6 @@ class CallsListFragment : GenericFragment() { } } - override fun onResume() { - super.onResume() - - coreContext.core.nativePreviewWindowId = binding.localPreviewVideoSurface - } - private fun showCallMenu(anchor: View, callData: CallData) { val popupView: VoipCallContextMenuBindingImpl = DataBindingUtil.inflate( LayoutInflater.from(requireContext()), diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceLayoutFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceLayoutFragment.kt index d9ddf36bb..0d641dcc5 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceLayoutFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceLayoutFragment.kt @@ -25,13 +25,14 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.navigation.navGraphViewModels import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R -import org.linphone.activities.GenericFragment import org.linphone.activities.voip.ConferenceDisplayMode import org.linphone.activities.voip.viewmodels.ConferenceViewModel +import org.linphone.activities.voip.viewmodels.ControlsViewModel import org.linphone.databinding.VoipConferenceLayoutFragmentBinding -class ConferenceLayoutFragment : GenericFragment() { +class ConferenceLayoutFragment : GenericVideoPreviewFragment() { private val conferenceViewModel: ConferenceViewModel by navGraphViewModels(R.id.call_nav_graph) + private val controlsViewModel: ControlsViewModel by navGraphViewModels(R.id.call_nav_graph) override fun getLayoutId(): Int = R.layout.voip_conference_layout_fragment @@ -42,6 +43,10 @@ class ConferenceLayoutFragment : GenericFragment() { +class ConferenceParticipantsFragment : GenericVideoPreviewFragment() { private val conferenceViewModel: ConferenceViewModel by navGraphViewModels(R.id.call_nav_graph) + private val controlsViewModel: ControlsViewModel by navGraphViewModels(R.id.call_nav_graph) // Only display events happening during while this fragment is visible private var skipEvents = true @@ -46,6 +47,10 @@ class ConferenceParticipantsFragment : GenericFragment diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/GenericVideoPreviewFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/GenericVideoPreviewFragment.kt new file mode 100644 index 000000000..5b649fc14 --- /dev/null +++ b/app/src/main/java/org/linphone/activities/voip/fragments/GenericVideoPreviewFragment.kt @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2010-2022 Belledonne Communications SARL. + * + * This file is part of linphone-android + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.linphone.activities.voip.fragments + +import android.view.MotionEvent +import android.view.TextureView +import android.view.View +import android.widget.ImageView +import androidx.databinding.ViewDataBinding +import org.linphone.LinphoneApplication.Companion.coreContext +import org.linphone.activities.GenericFragment + +abstract class GenericVideoPreviewFragment : GenericFragment() { + private var previewX: Float = 0f + private var previewY: Float = 0f + private var switchX: Float = 0f + private var switchY: Float = 0f + + private var switchCameraImageView: ImageView? = null + private lateinit var videoPreviewTextureView: TextureView + + private val previewTouchListener = View.OnTouchListener { view, event -> + when (event.action) { + MotionEvent.ACTION_DOWN -> { + previewX = view.x - event.rawX + previewY = view.y - event.rawY + switchX = (switchCameraImageView?.x ?: 0f) - event.rawX + switchY = (switchCameraImageView?.y ?: 0f) - event.rawY + true + } + MotionEvent.ACTION_MOVE -> { + view.animate() + .x(event.rawX + previewX) + .y(event.rawY + previewY) + .setDuration(0) + .start() + switchCameraImageView?.apply { + animate() + .x(event.rawX + switchX) + .y(event.rawY + switchY) + .setDuration(0) + .start() + } + true + } + else -> { + view.performClick() + false + } + } + } + + protected fun setupLocalViewPreview(localVideoPreview: TextureView, switchCamera: ImageView?) { + videoPreviewTextureView = localVideoPreview + switchCameraImageView = switchCamera + videoPreviewTextureView.setOnTouchListener(previewTouchListener) + } + + override fun onResume() { + super.onResume() + + if (::videoPreviewTextureView.isInitialized) { + coreContext.core.nativePreviewWindowId = videoPreviewTextureView + } + } +} diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/OutgoingCallFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/OutgoingCallFragment.kt index 3a387e924..143681754 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/OutgoingCallFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/OutgoingCallFragment.kt @@ -28,13 +28,12 @@ import androidx.databinding.ViewDataBinding import androidx.navigation.navGraphViewModels import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R -import org.linphone.activities.GenericFragment import org.linphone.activities.navigateToActiveCall import org.linphone.activities.voip.viewmodels.CallsViewModel import org.linphone.activities.voip.viewmodels.ControlsViewModel import org.linphone.databinding.VoipCallOutgoingFragmentBinding -class OutgoingCallFragment : GenericFragment() { +class OutgoingCallFragment : GenericVideoPreviewFragment() { private val controlsViewModel: ControlsViewModel by navGraphViewModels(R.id.call_nav_graph) private val callsViewModel: CallsViewModel by navGraphViewModels(R.id.call_nav_graph) @@ -49,6 +48,8 @@ class OutgoingCallFragment : GenericFragment() binding.callsViewModel = callsViewModel + setupLocalViewPreview(binding.localPreviewVideoSurface, binding.switchCamera) + callsViewModel.callConnectedEvent.observe( viewLifecycleOwner ) { diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/SingleCallFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/SingleCallFragment.kt index 35b2c01b9..9cece251b 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/SingleCallFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/SingleCallFragment.kt @@ -23,7 +23,6 @@ import android.app.Dialog import android.content.Intent import android.os.Bundle import android.os.SystemClock -import android.view.MotionEvent import android.view.View import android.widget.Chronometer import androidx.constraintlayout.widget.ConstraintSet @@ -46,7 +45,7 @@ import org.linphone.databinding.VoipSingleCallFragmentBinding import org.linphone.utils.AppUtils import org.linphone.utils.DialogUtils -class SingleCallFragment : GenericFragment() { +class SingleCallFragment : GenericVideoPreviewFragment() { private val controlsViewModel: ControlsViewModel by navGraphViewModels(R.id.call_nav_graph) private val callsViewModel: CallsViewModel by navGraphViewModels(R.id.call_nav_graph) private val conferenceViewModel: ConferenceViewModel by navGraphViewModels(R.id.call_nav_graph) @@ -54,39 +53,6 @@ class SingleCallFragment : GenericFragment() { private var dialog: Dialog? = null - private var previewX: Float = 0f - private var previewY: Float = 0f - private var switchX: Float = 0f - private var switchY: Float = 0f - private val previewTouchListener = View.OnTouchListener { view, event -> - when (event.action) { - MotionEvent.ACTION_DOWN -> { - previewX = view.x - event.rawX - previewY = view.y - event.rawY - switchX = binding.switchCamera.x - event.rawX - switchY = binding.switchCamera.y - event.rawY - true - } - MotionEvent.ACTION_MOVE -> { - view.animate() - .x(event.rawX + previewX) - .y(event.rawY + previewY) - .setDuration(0) - .start() - binding.switchCamera.animate() - .x(event.rawX + switchX) - .y(event.rawY + switchY) - .setDuration(0) - .start() - true - } - else -> { - view.performClick() - false - } - } - } - override fun getLayoutId(): Int = R.layout.voip_single_call_fragment override fun onStart() { @@ -102,7 +68,7 @@ class SingleCallFragment : GenericFragment() { binding.lifecycleOwner = viewLifecycleOwner - binding.previewTouchListener = previewTouchListener + setupLocalViewPreview(binding.localPreviewVideoSurface, binding.switchCamera) binding.controlsViewModel = controlsViewModel diff --git a/app/src/main/res/layout/voip_call_outgoing_fragment.xml b/app/src/main/res/layout/voip_call_outgoing_fragment.xml index 0c571b960..1f543d932 100644 --- a/app/src/main/res/layout/voip_call_outgoing_fragment.xml +++ b/app/src/main/res/layout/voip_call_outgoing_fragment.xml @@ -140,6 +140,19 @@ app:layout_constraintHeight_max="200dp" app:layout_constraintWidth_max="200dp" /> + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/voip_conference_layout_fragment.xml b/app/src/main/res/layout/voip_conference_layout_fragment.xml index bb9ca13b2..cf52c8b89 100644 --- a/app/src/main/res/layout/voip_conference_layout_fragment.xml +++ b/app/src/main/res/layout/voip_conference_layout_fragment.xml @@ -19,6 +19,10 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/voip_single_call_fragment.xml b/app/src/main/res/layout/voip_single_call_fragment.xml index f5f656311..8ff16a8ff 100644 --- a/app/src/main/res/layout/voip_single_call_fragment.xml +++ b/app/src/main/res/layout/voip_single_call_fragment.xml @@ -9,10 +9,6 @@ - - @@ -234,7 +230,6 @@ android:layout_width="0dp" android:layout_height="0dp" android:layout_size="@{controlsViewModel.pipMode ? @dimen/video_preview_pip_max_size : @dimen/video_preview_max_size}" - android:onTouch="@{previewTouchListener}" app:alignTopRight="true" app:displayMode="black_bars" app:layout_constraintBottom_toTopOf="@id/bottom_barrier"