From c93ea7a8511b571ece9ce097cd268ebe3b34ce7c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 7 Mar 2022 14:37:28 +0100 Subject: [PATCH] Reworked call UI a bit more --- .../linphone/activities/voip/CallActivity.kt | 34 +-- .../voip/fragments/ConferenceCallFragment.kt | 37 ++- .../voip/fragments/SingleCallFragment.kt | 21 +- .../voip/viewmodels/ControlsViewModel.kt | 8 +- .../org/linphone/utils/DataBindingUtils.kt | 6 +- app/src/main/res/layout/voip_call.xml | 235 ------------------ .../res/layout/voip_single_call_fragment.xml | 195 ++++++++++++++- 7 files changed, 234 insertions(+), 302 deletions(-) delete mode 100644 app/src/main/res/layout/voip_call.xml diff --git a/app/src/main/java/org/linphone/activities/voip/CallActivity.kt b/app/src/main/java/org/linphone/activities/voip/CallActivity.kt index 420731a53..a65e6cd58 100644 --- a/app/src/main/java/org/linphone/activities/voip/CallActivity.kt +++ b/app/src/main/java/org/linphone/activities/voip/CallActivity.kt @@ -43,7 +43,6 @@ import org.linphone.core.Call import org.linphone.core.tools.Log import org.linphone.databinding.VoipActivityBinding import org.linphone.mediastream.Version -import org.linphone.utils.Event import org.linphone.utils.PermissionHelper class CallActivity : ProximitySensorActivity() { @@ -92,7 +91,7 @@ class CallActivity : ProximitySensorActivity() { this ) { it.consume { permission -> - Log.i("[Call] Asking for $permission permission") + Log.i("[Call Activity] Asking for $permission permission") requestPermissions(arrayOf(permission), 0) } } @@ -119,10 +118,10 @@ class CallActivity : ProximitySensorActivity() { this ) { callData -> if (callData.call.conference == null) { - Log.i("[Call] Current call isn't linked to a conference, changing fragment") + Log.i("[Call Activity] Current call isn't linked to a conference, changing fragment") navigateToActiveCall() } else { - Log.i("[Call] Current call is linked to a conference, changing fragment") + Log.i("[Call Activity] Current call is linked to a conference, changing fragment") navigateToConferenceCall() } } @@ -131,10 +130,10 @@ class CallActivity : ProximitySensorActivity() { this ) { exists -> if (exists) { - Log.i("[Call] Found active conference, changing fragment") + Log.i("[Call Activity] Found active conference, changing fragment") navigateToConferenceCall() } else { - Log.i("[Call] Conference no longer exists, changing fragment") + Log.i("[Call Activity] Conference no longer exists, changing fragment") navigateToActiveCall() } } @@ -143,7 +142,7 @@ class CallActivity : ProximitySensorActivity() { this ) { paused -> if (!paused) { - Log.i("[Call] Entered conference, make sure conference fragment is active") + Log.i("[Call Activity] Entered conference, make sure conference fragment is active") navigateToConferenceCall() } } @@ -157,7 +156,7 @@ class CallActivity : ProximitySensorActivity() { super.onUserLeaveHint() if (coreContext.core.currentCall?.currentParams?.isVideoEnabled == true) { - Log.i("[Call] Entering PiP mode") + Log.i("[Call Activity] Entering PiP mode") Compatibility.enterPipMode(this) } } @@ -166,7 +165,7 @@ class CallActivity : ProximitySensorActivity() { isInPictureInPictureMode: Boolean, newConfig: Configuration ) { - Log.i("[Call] Activity is in PiP mode? $isInPictureInPictureMode") + Log.i("[Call Activity] Is in PiP mode? $isInPictureInPictureMode") if (::controlsViewModel.isInitialized) { // To hide UI except for TextureViews controlsViewModel.pipMode.value = isInPictureInPictureMode @@ -177,7 +176,7 @@ class CallActivity : ProximitySensorActivity() { super.onResume() if (coreContext.core.callsNb == 0) { - Log.w("[Call] Resuming but no call found...") + Log.w("[Call Activity] Resuming but no call found...") if (isTaskRoot) { // When resuming app from recent tasks make sure MainActivity will be launched if there is no call val intent = Intent() @@ -227,19 +226,19 @@ class CallActivity : ProximitySensorActivity() { val permissionsRequiredList = arrayListOf() if (!PermissionHelper.get().hasRecordAudioPermission()) { - Log.i("[Call] Asking for RECORD_AUDIO permission") + Log.i("[Call Activity] Asking for RECORD_AUDIO permission") permissionsRequiredList.add(Manifest.permission.RECORD_AUDIO) } if (callsViewModel.currentCallData.value?.call?.currentParams?.isVideoEnabled == true && !PermissionHelper.get().hasCameraPermission() ) { - Log.i("[Call] Asking for CAMERA permission") + Log.i("[Call Activity] Asking for CAMERA permission") permissionsRequiredList.add(Manifest.permission.CAMERA) } if (Version.sdkAboveOrEqual(Version.API31_ANDROID_12) && !PermissionHelper.get().hasBluetoothConnectPermission()) { - Log.i("[Call] Asking for BLUETOOTH_CONNECT permission") + Log.i("[Call Activity] Asking for BLUETOOTH_CONNECT permission") permissionsRequiredList.add(Compatibility.BLUETOOTH_CONNECT) } @@ -259,15 +258,15 @@ class CallActivity : ProximitySensorActivity() { for (i in permissions.indices) { when (permissions[i]) { Manifest.permission.RECORD_AUDIO -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { - Log.i("[Call] RECORD_AUDIO permission has been granted") + Log.i("[Call Activity] RECORD_AUDIO permission has been granted") controlsViewModel.updateMicState() } Manifest.permission.CAMERA -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { - Log.i("[Call] CAMERA permission has been granted") + Log.i("[Call Activity] CAMERA permission has been granted") coreContext.core.reloadVideoDevices() } Compatibility.BLUETOOTH_CONNECT -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { - Log.i("[Call] BLUETOOTH_CONNECT permission has been granted") + Log.i("[Call Activity] BLUETOOTH_CONNECT permission has been granted") } } } @@ -282,6 +281,7 @@ class CallActivity : ProximitySensorActivity() { private fun updateConstraintSetDependingOnFoldingState() { val feature = foldingFeature ?: return - controlsViewModel.foldingStateChangedEvent.value = Event(feature.state) + Log.i("[Call Activity] Folding feature state changed: $feature.state") + controlsViewModel.foldingState.value = feature.state } } diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceCallFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceCallFragment.kt index a172eb143..c689f7d1d 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceCallFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceCallFragment.kt @@ -25,7 +25,6 @@ import android.os.Bundle import android.os.SystemClock import android.view.View import android.widget.Chronometer -import android.widget.LinearLayout import android.widget.RelativeLayout import androidx.databinding.DataBindingUtil import androidx.databinding.ViewDataBinding @@ -95,18 +94,15 @@ class ConferenceCallFragment : GenericFragment(R.id.conference_active_speaker_layout) val window = layout?.findViewById(R.id.conference_active_speaker_remote_video) coreContext.core.nativeVideoWindowId = window } else { - Log.i("[Call] Either not in conference or current layout isn't active speaker, updating Core's native window id") - val layout = binding.root.findViewById(R.id.remote_layout) - val window = - layout?.findViewById(R.id.remote_video_surface) - coreContext.core.nativeVideoWindowId = window + Log.i("[Conference Call] Either not in conference or current layout isn't active speaker, updating Core's native window id") + coreContext.core.nativeVideoWindowId = null } } } @@ -174,12 +170,10 @@ class ConferenceCallFragment : GenericFragment - updateHingeRelatedConstraints(state) - } + ) { state -> + updateHingeRelatedConstraints(state) } callsViewModel.callUpdateEvent.observe( @@ -188,7 +182,7 @@ class ConferenceCallFragment : GenericFragment val conference = call.conference if (conference != null && conferenceViewModel.conference.value == null) { - Log.i("[Call] Found conference attached to call and no conference in dedicated view model, init & configure it") + Log.i("[Conference Call] Found conference attached to call and no conference in dedicated view model, init & configure it") conferenceViewModel.initConference(conference) conferenceViewModel.configureConference(conference) } @@ -209,21 +203,21 @@ class ConferenceCallFragment : GenericFragment - Log.i("[Call] Active speaker conference layout inflated") + Log.i("[Conference Call] Active speaker conference layout inflated") val binding = DataBindingUtil.bind(inflated) binding?.lifecycleOwner = viewLifecycleOwner startTimer(R.id.active_speaker_conference_timer) } binding.stubbedConferenceGridLayout.setOnInflateListener { _, inflated -> - Log.i("[Call] Mosaic conference layout inflated") + Log.i("[Conference Call] Mosaic conference layout inflated") val binding = DataBindingUtil.bind(inflated) binding?.lifecycleOwner = viewLifecycleOwner startTimer(R.id.grid_conference_timer) } binding.stubbedConferenceAudioOnlyLayout.setOnInflateListener { _, inflated -> - Log.i("[Call] Audio only conference layout inflated") + Log.i("[Conference Call] Audio only conference layout inflated") val binding = DataBindingUtil.bind(inflated) binding?.lifecycleOwner = viewLifecycleOwner startTimer(R.id.audio_only_conference_timer) @@ -261,14 +255,14 @@ class ConferenceCallFragment : GenericFragment { - Log.w("[Call] Conference has video enabled but either our device hasn't joined yet") + Log.w("[Conference Call] Conference has video enabled but either our device hasn't joined yet") } conference.me.devices.find { it.getStreamAvailability(StreamType.Video) } != null -> { - Log.i("[Call] Conference has video enabled & our device has video enabled, enabling full screen mode") + Log.i("[Conference Call] Conference has video enabled & our device has video enabled, enabling full screen mode") controlsViewModel.fullScreenMode.value = true } else -> { - Log.w("[Call] Conference has video enabled but our device video is disabled") + Log.w("[Conference Call] Conference has video enabled but our device video is disabled") } } } @@ -290,7 +284,7 @@ class ConferenceCallFragment : GenericFragment() { } } - controlsViewModel.foldingStateChangedEvent.observe( + controlsViewModel.foldingState.observe( viewLifecycleOwner - ) { - it.consume { state -> - updateHingeRelatedConstraints(state) - } + ) { state -> + updateHingeRelatedConstraints(state) } callsViewModel.callUpdateEvent.observe( @@ -143,7 +138,7 @@ class SingleCallFragment : GenericFragment() { showCallVideoUpdateDialog(call) } } else { - Log.w("[Call] Video display & capture are disabled, don't show video dialog") + Log.w("[Single Call] Video display & capture are disabled, don't show video dialog") } } } @@ -162,11 +157,8 @@ class SingleCallFragment : GenericFragment() { } } - val remoteLayout = binding.root.findViewById(R.id.remote_layout) - val remoteVideoView = remoteLayout.findViewById(R.id.remote_video_surface) - coreContext.core.nativeVideoWindowId = remoteVideoView - val localVideoView = remoteLayout.findViewById(R.id.local_preview_video_surface) - coreContext.core.nativePreviewWindowId = localVideoView + coreContext.core.nativeVideoWindowId = binding.remoteVideoSurface + coreContext.core.nativePreviewWindowId = binding.localPreviewVideoSurface binding.stubbedAudioRoutes.setOnInflateListener { _, inflated -> val binding = DataBindingUtil.bind(inflated) @@ -232,6 +224,7 @@ class SingleCallFragment : GenericFragment() { } private fun updateHingeRelatedConstraints(state: FoldingFeature.State) { + Log.i("[Single Call] Updating constraint layout hinges") /*val constraintLayout = binding.constraintLayout val set = ConstraintSet() set.clone(constraintLayout) diff --git a/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt b/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt index 083101e97..06cc2b784 100644 --- a/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/voip/viewmodels/ControlsViewModel.kt @@ -103,9 +103,7 @@ class ControlsViewModel : ViewModel() { MutableLiveData>() } - val foldingStateChangedEvent: MutableLiveData> by lazy { - MutableLiveData>() - } + val foldingState = MutableLiveData() private val nonEarpieceOutputAudioDevice = MutableLiveData() @@ -144,6 +142,9 @@ class ControlsViewModel : ViewModel() { isOutgoingEarlyMedia.value = state == Call.State.OutgoingEarlyMedia if (state == Call.State.StreamsRunning) { + if (!call.currentParams.isVideoEnabled && fullScreenMode.value == true) { + fullScreenMode.value = false + } isVideoUpdateInProgress.value = false } else if (state == Call.State.PausedByRemote) { fullScreenMode.value = false @@ -224,6 +225,7 @@ class ControlsViewModel : ViewModel() { extraButtonsMenuTranslateY.value = AppUtils.getDimension(R.dimen.voip_call_extra_buttons_translate_y) audioRoutesMenuTranslateY.value = AppUtils.getDimension(R.dimen.voip_audio_routes_menu_translate_y) audioRoutesSelected.value = false + foldingState.value = FoldingFeature.State.FLAT nonEarpieceOutputAudioDevice.value = coreContext.core.outputAudioDevice?.type != AudioDevice.Type.Earpiece proximitySensorEnabled.value = shouldProximitySensorBeEnabled() diff --git a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt index bf7778b6b..6bb928ce4 100644 --- a/app/src/main/java/org/linphone/utils/DataBindingUtils.kt +++ b/app/src/main/java/org/linphone/utils/DataBindingUtils.kt @@ -579,11 +579,11 @@ fun VoiceRecordProgressBar.setSecProgressTint(color: Int) { } @BindingAdapter("android:layout_margin") -fun ConstraintLayout.setMargins(margins: Float) { - val params = layoutParams as ConstraintLayout.LayoutParams +fun setConstraintLayoutMargins(view: View, margins: Float) { + val params = view.layoutParams as ConstraintLayout.LayoutParams val m = margins.toInt() params.setMargins(m, m, m, m) - layoutParams = params + view.layoutParams = params } @BindingAdapter("android:onTouch") diff --git a/app/src/main/res/layout/voip_call.xml b/app/src/main/res/layout/voip_call.xml deleted file mode 100644 index 4c94a49f8..000000000 --- a/app/src/main/res/layout/voip_call.xml +++ /dev/null @@ -1,235 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 7936ef407..107c0fd14 100644 --- a/app/src/main/res/layout/voip_single_call_fragment.xml +++ b/app/src/main/res/layout/voip_single_call_fragment.xml @@ -31,20 +31,197 @@ android:layout_height="match_parent" android:background="@{controlsViewModel.fullScreenMode ? @color/black_color : @color/transparent_color}"> + + + + + + + + + + + + + + + + + + + + + + + + + + + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintWidth_max="@dimen/voip_views_max_width"> + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_margin="10dp" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintHeight_max="200dp" + app:data="@{callsViewModel.currentCallData}" + layout="@layout/voip_contact_avatar"/> + + + + + + + + + + + + + + + +