diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b7f5973d..c1f22f4e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Group changes to describe their impact on the project, as follows: - one to let edit native contacts Linphone copy in-app instead of opening native addressbook third party app - Added a vu meter for recording & playback volumes (must be enabled in developer settings) - Added support for HDMI audio devices +- Added video preview during in-call conversation ### Changed - No longer follow TelecomManager audio endpoint during calls, using our own routing policy diff --git a/app/src/main/java/org/linphone/ui/call/fragment/ConversationFragment.kt b/app/src/main/java/org/linphone/ui/call/fragment/ConversationFragment.kt index c18d716ba..c5c5660cd 100644 --- a/app/src/main/java/org/linphone/ui/call/fragment/ConversationFragment.kt +++ b/app/src/main/java/org/linphone/ui/call/fragment/ConversationFragment.kt @@ -19,12 +19,20 @@ */ package org.linphone.ui.call.fragment +import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle +import android.view.MotionEvent import android.view.View +import android.view.ViewGroup +import androidx.core.view.doOnLayout +import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.findNavController +import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R import org.linphone.core.tools.Log +import org.linphone.ui.call.view.RoundCornersTextureView +import org.linphone.ui.call.viewmodel.CurrentCallViewModel import org.linphone.ui.fileviewer.FileViewerActivity import org.linphone.ui.fileviewer.MediaViewerActivity import org.linphone.ui.main.chat.fragment.ConversationFragment @@ -34,9 +42,48 @@ class ConversationFragment : ConversationFragment() { private const val TAG = "[In-call Conversation Fragment]" } + private lateinit var callViewModel: CurrentCallViewModel + + private lateinit var localPreviewVideoSurface: RoundCornersTextureView + + private var videoPreviewX: Float = 0f + private var videoPreviewY: Float = 0f + + // For moving video preview purposes + private val videoPreviewTouchListener = View.OnTouchListener { view, event -> + when (event.action) { + MotionEvent.ACTION_DOWN -> { + videoPreviewX = view.x - event.rawX + videoPreviewY = view.y - event.rawY + true + } + MotionEvent.ACTION_UP -> { + videoPreviewX = view.x + videoPreviewY = view.y + true + } + MotionEvent.ACTION_MOVE -> { + view.animate() + .x(event.rawX + videoPreviewX) + .y(event.rawY + videoPreviewY) + .setDuration(0) + .start() + true + } + else -> { + view.performClick() + false + } + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + callViewModel = requireActivity().run { + ViewModelProvider(this)[CurrentCallViewModel::class.java] + } + Log.i("$TAG Creating an in-call ConversationFragment") sendMessageViewModel.isCallConversation.value = true viewModel.isCallConversation.value = true @@ -70,5 +117,50 @@ class ConversationFragment : ConversationFragment() { } } } + + val layout = layoutInflater.inflate(R.layout.call_video_local_preview_surface, binding.constraintLayout, false) + binding.constraintLayout.addView(layout) + localPreviewVideoSurface = layout.findViewById(R.id.local_preview_video_surface) + + callViewModel.isSendingVideo.observe(viewLifecycleOwner) { sending -> + coreContext.postOnCoreThread { core -> + core.nativePreviewWindowId = if (sending) { + Log.i("$TAG We are sending video, setting capture preview surface") + localPreviewVideoSurface + } else { + Log.i("$TAG We are not sending video, clearing capture preview surface") + null + } + } + } + } + + override fun onResume() { + super.onResume() + + (binding.root as? ViewGroup)?.doOnLayout { + setupVideoPreview(localPreviewVideoSurface) + } + } + + override fun onPause() { + super.onPause() + + cleanVideoPreview(localPreviewVideoSurface) + } + + @SuppressLint("ClickableViewAccessibility") + private fun setupVideoPreview(localPreviewVideoSurface: RoundCornersTextureView) { + if (requireActivity().isInPictureInPictureMode) { + Log.i("$TAG Activity is in PiP mode, do not move video preview") + return + } + + localPreviewVideoSurface.setOnTouchListener(videoPreviewTouchListener) + } + + @SuppressLint("ClickableViewAccessibility") + private fun cleanVideoPreview(localPreviewVideoSurface: RoundCornersTextureView) { + localPreviewVideoSurface.setOnTouchListener(null) } } diff --git a/app/src/main/res/layout/call_conference_participants_list_fragment.xml b/app/src/main/res/layout/call_conference_participants_list_fragment.xml index eaffd8708..b790c8a3b 100644 --- a/app/src/main/res/layout/call_conference_participants_list_fragment.xml +++ b/app/src/main/res/layout/call_conference_participants_list_fragment.xml @@ -100,6 +100,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="10dp" + android:layout_marginBottom="10dp" app:alignTopRight="true" app:displayMode="black_bars" roundCornersRadius="@dimen/call_round_corners_texture_view_radius" diff --git a/app/src/main/res/layout/call_video_local_preview_surface.xml b/app/src/main/res/layout/call_video_local_preview_surface.xml new file mode 100644 index 000000000..99061f5c8 --- /dev/null +++ b/app/src/main/res/layout/call_video_local_preview_surface.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/calls_list_fragment.xml b/app/src/main/res/layout/calls_list_fragment.xml index c42e46ed7..3cb191a64 100644 --- a/app/src/main/res/layout/calls_list_fragment.xml +++ b/app/src/main/res/layout/calls_list_fragment.xml @@ -98,6 +98,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="10dp" + android:layout_marginBottom="10dp" app:alignTopRight="true" app:displayMode="black_bars" roundCornersRadius="@dimen/call_round_corners_texture_view_radius" diff --git a/app/src/main/res/layout/chat_conversation_fragment.xml b/app/src/main/res/layout/chat_conversation_fragment.xml index 22274b5f4..5d9ee2ef9 100644 --- a/app/src/main/res/layout/chat_conversation_fragment.xml +++ b/app/src/main/res/layout/chat_conversation_fragment.xml @@ -53,6 +53,7 @@ android:layout_height="match_parent">