From 0edb3a6f14b2df712d20729a2b90b8a9e288d97c Mon Sep 17 00:00:00 2001 From: Yamil Medina Date: Tue, 25 Jun 2024 11:14:42 +0200 Subject: [PATCH] fix: calling video not streamed when enabling camera in preview screen (#2670) (#2679) (#2840) Co-authored-by: Oussama Hassine --- .../logic/feature/call/CallManagerImpl.kt | 2 +- .../logic/feature/call/CallManagerImpl.kt | 2 +- .../kalium/logic/feature/call/CallManager.kt | 2 +- .../kalium/logic/feature/call/CallsScope.kt | 6 +- .../usecase/video/SetVideoSendStateUseCase.kt | 36 ++++++++++++ .../{ => video}/UpdateVideoStateUseCase.kt | 14 +---- .../video/SetVideoSendStateUseCaseTest.kt | 57 +++++++++++++++++++ .../UpdateVideoStateUseCaseTest.kt | 28 +-------- 8 files changed, 104 insertions(+), 43 deletions(-) create mode 100644 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/video/SetVideoSendStateUseCase.kt rename logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/{ => video}/UpdateVideoStateUseCase.kt (70%) create mode 100644 logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/video/SetVideoSendStateUseCaseTest.kt rename logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/{ => video}/UpdateVideoStateUseCaseTest.kt (80%) diff --git a/logic/src/appleMain/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt b/logic/src/appleMain/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt index ad1d9674747..79c1078dba4 100644 --- a/logic/src/appleMain/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt +++ b/logic/src/appleMain/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt @@ -56,7 +56,7 @@ class CallManagerImpl : CallManager { TODO("Not yet implemented") } - override suspend fun updateVideoState(conversationId: ConversationId, videoState: VideoState) { + override suspend fun setVideoSendState(conversationId: ConversationId, videoState: VideoState) { TODO("Not yet implemented") } diff --git a/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt b/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt index e444919ecf5..24987458d14 100644 --- a/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt +++ b/logic/src/commonJvmAndroid/kotlin/com/wire/kalium/logic/feature/call/CallManagerImpl.kt @@ -346,7 +346,7 @@ class CallManagerImpl internal constructor( /** * This method should NOT be called while the call is still incoming or outgoing and not established yet. */ - override suspend fun updateVideoState(conversationId: ConversationId, videoState: VideoState) { + override suspend fun setVideoSendState(conversationId: ConversationId, videoState: VideoState) { withCalling { callingLogger.d("$TAG -> changing video state to ${videoState.name}..") scope.launch { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallManager.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallManager.kt index cbe5321b80f..eeaf20a86e0 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallManager.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallManager.kt @@ -41,7 +41,7 @@ interface CallManager { suspend fun endCall(conversationId: ConversationId) suspend fun rejectCall(conversationId: ConversationId) suspend fun muteCall(shouldMute: Boolean) - suspend fun updateVideoState(conversationId: ConversationId, videoState: VideoState) + suspend fun setVideoSendState(conversationId: ConversationId, videoState: VideoState) suspend fun requestVideoStreams(conversationId: ConversationId, callClients: CallClientList) suspend fun updateEpochInfo(conversationId: ConversationId, epochInfo: EpochInfo) suspend fun updateConversationClients(conversationId: ConversationId, clients: String) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt index 0bd7104704d..80149f4a909 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/CallsScope.kt @@ -66,7 +66,8 @@ import com.wire.kalium.logic.feature.call.usecase.UnMuteCallUseCase import com.wire.kalium.logic.feature.call.usecase.UnMuteCallUseCaseImpl import com.wire.kalium.logic.feature.call.usecase.UpdateConversationClientsForCurrentCallUseCase import com.wire.kalium.logic.feature.call.usecase.UpdateConversationClientsForCurrentCallUseCaseImpl -import com.wire.kalium.logic.feature.call.usecase.UpdateVideoStateUseCase +import com.wire.kalium.logic.feature.call.usecase.video.SetVideoSendStateUseCase +import com.wire.kalium.logic.feature.call.usecase.video.UpdateVideoStateUseCase import com.wire.kalium.logic.featureFlags.KaliumConfigs import com.wire.kalium.logic.sync.SyncManager import com.wire.kalium.util.KaliumDispatcher @@ -154,7 +155,8 @@ class CallsScope internal constructor( val unMuteCall: UnMuteCallUseCase get() = UnMuteCallUseCaseImpl(callManager, callRepository) - val updateVideoState: UpdateVideoStateUseCase get() = UpdateVideoStateUseCase(callManager, callRepository) + val updateVideoState: UpdateVideoStateUseCase get() = UpdateVideoStateUseCase(callRepository) + val setVideoSendState: SetVideoSendStateUseCase get() = SetVideoSendStateUseCase(callManager) val setVideoPreview: SetVideoPreviewUseCase get() = SetVideoPreviewUseCase(flowManagerService) val flipToFrontCamera: FlipToFrontCameraUseCase get() = FlipToFrontCameraUseCase(flowManagerService) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/video/SetVideoSendStateUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/video/SetVideoSendStateUseCase.kt new file mode 100644 index 00000000000..7f230cad790 --- /dev/null +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/video/SetVideoSendStateUseCase.kt @@ -0,0 +1,36 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * 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 http://www.gnu.org/licenses/. + */ +package com.wire.kalium.logic.feature.call.usecase.video + +import com.wire.kalium.logic.data.call.VideoState +import com.wire.kalium.logic.data.id.ConversationId +import com.wire.kalium.logic.feature.call.CallManager + +/** + * This usecase is responsible for setting the video send state of a call. + */ +class SetVideoSendStateUseCase( + private val callManager: Lazy, +) { + suspend operator fun invoke( + conversationId: ConversationId, + videoState: VideoState + ) { + callManager.value.setVideoSendState(conversationId, videoState) + } +} diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/UpdateVideoStateUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/video/UpdateVideoStateUseCase.kt similarity index 70% rename from logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/UpdateVideoStateUseCase.kt rename to logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/video/UpdateVideoStateUseCase.kt index dc54d4af8d3..2eef270ff06 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/UpdateVideoStateUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/video/UpdateVideoStateUseCase.kt @@ -16,20 +16,17 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ -package com.wire.kalium.logic.feature.call.usecase +package com.wire.kalium.logic.feature.call.usecase.video import com.wire.kalium.logic.data.call.CallRepository import com.wire.kalium.logic.data.call.VideoState import com.wire.kalium.logic.data.id.ConversationId -import com.wire.kalium.logic.feature.call.CallManager -import kotlinx.coroutines.flow.first /** - * This use case is responsible for updating the video state of a call. + * This use case is responsible for updating and caching the video state of a call. * @see [VideoState] */ class UpdateVideoStateUseCase( - private val callManager: Lazy, private val callRepository: CallRepository ) { /** @@ -42,12 +39,5 @@ class UpdateVideoStateUseCase( ) { if (videoState != VideoState.PAUSED) callRepository.updateIsCameraOnById(conversationId, videoState == VideoState.STARTED) - - // updateVideoState should be called only when the call is established - callRepository.establishedCallsFlow().first().find { call -> - call.conversationId == conversationId - }?.let { - callManager.value.updateVideoState(conversationId, videoState) - } } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/video/SetVideoSendStateUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/video/SetVideoSendStateUseCaseTest.kt new file mode 100644 index 00000000000..21e8077ff2a --- /dev/null +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/video/SetVideoSendStateUseCaseTest.kt @@ -0,0 +1,57 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * 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 http://www.gnu.org/licenses/. + */ +package com.wire.kalium.logic.feature.call.usecase.video + +import com.wire.kalium.logic.data.call.VideoState +import com.wire.kalium.logic.feature.call.CallManager +import com.wire.kalium.logic.framework.TestConversation +import io.mockative.Mock +import io.mockative.any +import io.mockative.classOf +import io.mockative.eq +import io.mockative.mock +import io.mockative.once +import io.mockative.verify +import kotlinx.coroutines.test.runTest +import kotlin.test.Test + +class SetVideoSendStateUseCaseTest { + + @Test + fun givenVideoState_whenRunningUsecase_thenInvokeSetVideoSendStateOnce() = runTest { + val (arrangement, setVideoSendState) = Arrangement() + .arrange() + + setVideoSendState.invoke(TestConversation.ID, VideoState.STARTED) + + verify(arrangement.callManager) + .suspendFunction(arrangement.callManager::setVideoSendState) + .with(any(), eq(VideoState.STARTED)) + .wasInvoked(once) + } + + private class Arrangement { + + @Mock + val callManager = mock(classOf()) + + val setVideoSendState = SetVideoSendStateUseCase(lazy { callManager }) + + fun arrange() = this to setVideoSendState + } +} diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/UpdateVideoStateUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/video/UpdateVideoStateUseCaseTest.kt similarity index 80% rename from logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/UpdateVideoStateUseCaseTest.kt rename to logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/video/UpdateVideoStateUseCaseTest.kt index da08ae0d93a..9df4d799941 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/UpdateVideoStateUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/video/UpdateVideoStateUseCaseTest.kt @@ -16,17 +16,15 @@ * along with this program. If not, see http://www.gnu.org/licenses/. */ -package com.wire.kalium.logic.feature.call.usecase +package com.wire.kalium.logic.feature.call.usecase.video import com.wire.kalium.logic.data.call.CallRepository import com.wire.kalium.logic.data.call.VideoState import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.call.Call -import com.wire.kalium.logic.feature.call.CallManager import com.wire.kalium.logic.data.call.CallStatus import io.mockative.Mock -import io.mockative.any import io.mockative.classOf import io.mockative.eq import io.mockative.given @@ -41,9 +39,6 @@ import kotlin.test.Test class UpdateVideoStateUseCaseTest { - @Mock - private val callManager = mock(classOf()) - @Mock private val callRepository = mock(classOf()) @@ -51,16 +46,11 @@ class UpdateVideoStateUseCaseTest { @BeforeTest fun setup() { - updateVideoStateUseCase = UpdateVideoStateUseCase(lazy { callManager }, callRepository) + updateVideoStateUseCase = UpdateVideoStateUseCase(callRepository) given(callRepository) .function(callRepository::updateIsCameraOnById) .whenInvokedWith(eq(conversationId.toString()), eq(isCameraOn)) .thenDoNothing() - - given(callManager) - .suspendFunction(callManager::updateVideoState) - .whenInvokedWith(any(), any()) - .thenReturn(Unit) } @Test @@ -77,10 +67,6 @@ class UpdateVideoStateUseCaseTest { null, null ) - given(callManager) - .suspendFunction(callManager::updateVideoState) - .whenInvokedWith(eq(conversationId), eq(videoState)) - .thenDoNothing() given(callRepository) .suspendFunction(callRepository::establishedCallsFlow) @@ -98,11 +84,6 @@ class UpdateVideoStateUseCaseTest { .function(callRepository::updateIsCameraOnById) .with(eq(conversationId), eq(isCameraOn)) .wasInvoked(once) - - verify(callManager) - .suspendFunction(callManager::updateVideoState) - .with(any(), any()) - .wasInvoked(once) } @Test @@ -124,11 +105,6 @@ class UpdateVideoStateUseCaseTest { .function(callRepository::updateIsCameraOnById) .with(eq(conversationId), eq(isCameraOn)) .wasInvoked(once) - - verify(callManager) - .suspendFunction(callManager::updateVideoState) - .with(any(), any()) - .wasNotInvoked() } companion object {