From d6f83f00578b0f82a0da2c1abc930106ce13342f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 4 May 2022 15:22:51 +0200 Subject: [PATCH] Fixes for self-mute during remote conference + rework how we mute single call --- .../linphone/activities/voip/CallActivity.kt | 51 +++++++++++-------- .../voip/viewmodels/CallsViewModel.kt | 27 ++++++++++ .../voip/viewmodels/ControlsViewModel.kt | 21 -------- .../org/linphone/telecom/NativeCallWrapper.kt | 9 +++- app/src/main/res/layout/voip_buttons.xml | 8 +-- .../main/res/layout/voip_buttons_outgoing.xml | 12 +++-- .../layout/voip_call_outgoing_fragment.xml | 1 + 7 files changed, 78 insertions(+), 51 deletions(-) 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 bc4198678..e2fb6b79d 100644 --- a/app/src/main/java/org/linphone/activities/voip/CallActivity.kt +++ b/app/src/main/java/org/linphone/activities/voip/CallActivity.kt @@ -83,26 +83,6 @@ class CallActivity : ProximitySensorActivity() { statsViewModel = ViewModelProvider(navControllerStoreOwner)[StatisticsListViewModel::class.java] - callsViewModel.noMoreCallEvent.observe( - this - ) { - it.consume { noMoreCall -> - if (noMoreCall) { - Log.i("[Call Activity] No more call event fired, finishing activity") - finish() - } - } - } - - callsViewModel.askWriteExternalStoragePermissionEvent.observe( - this - ) { - it.consume { - Log.i("[Call Activity] Asking for WRITE_EXTERNAL_STORAGE permission to take snapshot") - requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1) - } - } - controlsViewModel.askPermissionEvent.observe( this ) { @@ -136,6 +116,26 @@ class CallActivity : ProximitySensorActivity() { if (visible) statsViewModel.enable() else statsViewModel.disable() } + callsViewModel.noMoreCallEvent.observe( + this + ) { + it.consume { noMoreCall -> + if (noMoreCall) { + Log.i("[Call Activity] No more call event fired, finishing activity") + finish() + } + } + } + + callsViewModel.askWriteExternalStoragePermissionEvent.observe( + this + ) { + it.consume { + Log.i("[Call Activity] Asking for WRITE_EXTERNAL_STORAGE permission to take snapshot") + requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1) + } + } + callsViewModel.currentCallData.observe( this ) { callData -> @@ -148,6 +148,15 @@ class CallActivity : ProximitySensorActivity() { } } + callsViewModel.askPermissionEvent.observe( + this + ) { + it.consume { permission -> + Log.i("[Call Activity] Asking for $permission permission") + requestPermissions(arrayOf(permission), 0) + } + } + conferenceViewModel.conferenceExists.observe( this ) { exists -> @@ -281,7 +290,7 @@ class CallActivity : ProximitySensorActivity() { when (permissions[i]) { Manifest.permission.RECORD_AUDIO -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { Log.i("[Call Activity] RECORD_AUDIO permission has been granted") - controlsViewModel.updateMicState() + callsViewModel.updateMicState() } Manifest.permission.CAMERA -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { Log.i("[Call Activity] CAMERA permission has been granted") diff --git a/app/src/main/java/org/linphone/activities/voip/viewmodels/CallsViewModel.kt b/app/src/main/java/org/linphone/activities/voip/viewmodels/CallsViewModel.kt index f1fc5ac6f..f865322e5 100644 --- a/app/src/main/java/org/linphone/activities/voip/viewmodels/CallsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/voip/viewmodels/CallsViewModel.kt @@ -19,6 +19,7 @@ */ package org.linphone.activities.voip.viewmodels +import android.Manifest import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -43,6 +44,10 @@ class CallsViewModel : ViewModel() { val chatAndCallsCount = MediatorLiveData() + val isMicrophoneMuted = MutableLiveData() + + val isMuteMicrophoneEnabled = MutableLiveData() + val askWriteExternalStoragePermissionEvent: MutableLiveData> by lazy { MutableLiveData>() } @@ -63,6 +68,10 @@ class CallsViewModel : ViewModel() { MutableLiveData>() } + val askPermissionEvent: MutableLiveData> by lazy { + MutableLiveData>() + } + private val listener = object : CoreListenerStub() { override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) { updateUnreadChatCount() @@ -145,6 +154,7 @@ class CallsViewModel : ViewModel() { initCallList() updateInactiveCallsCount() updateUnreadChatCount() + updateMicState() } override fun onCleared() { @@ -156,6 +166,17 @@ class CallsViewModel : ViewModel() { super.onCleared() } + fun toggleMuteMicrophone() { + if (!PermissionHelper.get().hasRecordAudioPermission()) { + askPermissionEvent.value = Event(Manifest.permission.RECORD_AUDIO) + return + } + + val micMuted = currentCallData.value?.call?.microphoneMuted ?: false + currentCallData.value?.call?.microphoneMuted = !micMuted + updateMicState() + } + fun mergeCallsIntoConference() { Log.i("[Calls] Merging all calls into new conference") val core = coreContext.core @@ -258,6 +279,7 @@ class CallsViewModel : ViewModel() { currentCallData.value = viewModel } + updateMicState() // updateUnreadChatCount() } @@ -270,6 +292,11 @@ class CallsViewModel : ViewModel() { return false } + fun updateMicState() { + isMicrophoneMuted.value = !PermissionHelper.get().hasRecordAudioPermission() || currentCallData.value?.call?.microphoneMuted == true + isMuteMicrophoneEnabled.value = currentCallData.value?.call != null + } + private fun updateCallsAndChatCount(): Int { return (inactiveCallsCount.value ?: 0) + (currentCallUnreadChatMessageCount.value ?: 0) } 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 29e6fc0d0..5dfabcb08 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 @@ -37,10 +37,6 @@ import org.linphone.utils.Event import org.linphone.utils.PermissionHelper class ControlsViewModel : ViewModel() { - val isMicrophoneMuted = MutableLiveData() - - val isMuteMicrophoneEnabled = MutableLiveData() - val isSpeakerSelected = MutableLiveData() val isBluetoothHeadsetSelected = MutableLiveData() @@ -241,17 +237,6 @@ class ControlsViewModel : ViewModel() { } } - fun toggleMuteMicrophone() { - if (!PermissionHelper.get().hasRecordAudioPermission()) { - askPermissionEvent.value = Event(Manifest.permission.RECORD_AUDIO) - return - } - - val micEnabled = coreContext.core.isMicEnabled - coreContext.core.isMicEnabled = !micEnabled - updateMicState() - } - fun toggleSpeaker() { if (AudioRouteUtils.isSpeakerAudioRouteCurrentlyUsed()) { forceEarpieceAudioRoute() @@ -402,16 +387,10 @@ class ControlsViewModel : ViewModel() { private fun updateUI() { updateVideoAvailable() updateVideoEnabled() - updateMicState() updateSpeakerState() updateAudioRoutesState() } - fun updateMicState() { - isMicrophoneMuted.value = !PermissionHelper.get().hasRecordAudioPermission() || !coreContext.core.isMicEnabled - isMuteMicrophoneEnabled.value = coreContext.core.currentCall != null || coreContext.core.conference?.isIn == true - } - private fun updateSpeakerState() { isSpeakerSelected.value = AudioRouteUtils.isSpeakerAudioRouteCurrentlyUsed() } diff --git a/app/src/main/java/org/linphone/telecom/NativeCallWrapper.kt b/app/src/main/java/org/linphone/telecom/NativeCallWrapper.kt index d69d9e8d8..2979327e6 100644 --- a/app/src/main/java/org/linphone/telecom/NativeCallWrapper.kt +++ b/app/src/main/java/org/linphone/telecom/NativeCallWrapper.kt @@ -75,7 +75,14 @@ class NativeCallWrapper(var callId: String) : Connection() { return } - call.microphoneMuted = state.isMuted + if (state.isMuted != call.microphoneMuted) { + Log.w("[Connection] Connection audio state asks for changing in mute: ${state.isMuted}, currently is ${call.microphoneMuted}") + if (state.isMuted) { + Log.w("[Connection] Muting microphone") + call.microphoneMuted = true + } + } + when (state.route) { CallAudioState.ROUTE_EARPIECE -> AudioRouteUtils.routeAudioToEarpiece(call, true) CallAudioState.ROUTE_SPEAKER -> AudioRouteUtils.routeAudioToSpeaker(call, true) diff --git a/app/src/main/res/layout/voip_buttons.xml b/app/src/main/res/layout/voip_buttons.xml index 5de082609..a9ba15c8e 100644 --- a/app/src/main/res/layout/voip_buttons.xml +++ b/app/src/main/res/layout/voip_buttons.xml @@ -44,11 +44,11 @@ android:layout_height="match_parent" android:layout_marginEnd="5dp" android:background="@drawable/button_background_reverse" - android:contentDescription="@{controlsViewModel.isMicrophoneMuted ? @string/content_description_disable_mic_mute : @string/content_description_enable_mic_mute}" - android:enabled="@{controlsViewModel.isMuteMicrophoneEnabled}" - android:onClick="@{() -> controlsViewModel.toggleMuteMicrophone()}" + android:contentDescription="@{callsViewModel.isMicrophoneMuted ? @string/content_description_disable_mic_mute : @string/content_description_enable_mic_mute}" + android:enabled="@{callsViewModel.isMuteMicrophoneEnabled}" + android:onClick="@{() -> callsViewModel.toggleMuteMicrophone()}" android:padding="5dp" - android:selected="@{controlsViewModel.isMicrophoneMuted}" + android:selected="@{callsViewModel.isMicrophoneMuted}" android:src="@drawable/icon_toggle_mic" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="W,1:1" diff --git a/app/src/main/res/layout/voip_buttons_outgoing.xml b/app/src/main/res/layout/voip_buttons_outgoing.xml index 839e3675f..353c28853 100644 --- a/app/src/main/res/layout/voip_buttons_outgoing.xml +++ b/app/src/main/res/layout/voip_buttons_outgoing.xml @@ -6,6 +6,10 @@ + + @@ -34,11 +38,11 @@ android:layout_height="match_parent" android:layout_marginEnd="5dp" android:background="@drawable/button_background_reverse" - android:contentDescription="@{controlsViewModel.isMicrophoneMuted ? @string/content_description_disable_mic_mute : @string/content_description_enable_mic_mute}" - android:enabled="@{controlsViewModel.isMuteMicrophoneEnabled}" - android:onClick="@{() -> controlsViewModel.toggleMuteMicrophone()}" + android:contentDescription="@{callsViewModel.isMicrophoneMuted ? @string/content_description_disable_mic_mute : @string/content_description_enable_mic_mute}" + android:enabled="@{callsViewModel.isMuteMicrophoneEnabled}" + android:onClick="@{() -> callsViewModel.toggleMuteMicrophone()}" android:padding="5dp" - android:selected="@{controlsViewModel.isMicrophoneMuted}" + android:selected="@{callsViewModel.isMicrophoneMuted}" android:src="@drawable/icon_toggle_mic" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="W,1:1" 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 5722f4c8f..838348d47 100644 --- a/app/src/main/res/layout/voip_call_outgoing_fragment.xml +++ b/app/src/main/res/layout/voip_call_outgoing_fragment.xml @@ -119,6 +119,7 @@ android:layout_width="0dp" android:layout_height="@dimen/voip_buttons_fragment_size" android:layout_margin="10dp" + app:callsViewModel="@{callsViewModel}" app:controlsViewModel="@{controlsViewModel}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"