From dbb58115ce0cedf39b0e1841b1e355fd4549e06c Mon Sep 17 00:00:00 2001 From: Oussama Hassine Date: Tue, 23 Apr 2024 10:32:12 +0200 Subject: [PATCH] fix: show incoming call screen for second logged in account --- .../android/feature/AccountSwitchUseCase.kt | 6 +-- .../wire/android/ui/calling/CallActivity.kt | 19 ++++--- .../ui/calling/CallActivityViewModel.kt | 21 +++++++- .../android/ui/CallActivityViewModelTest.kt | 53 ++++++++++++++++++- 4 files changed, 88 insertions(+), 11 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/feature/AccountSwitchUseCase.kt b/app/src/main/kotlin/com/wire/android/feature/AccountSwitchUseCase.kt index 307cf2be77f..daca15c2e46 100644 --- a/app/src/main/kotlin/com/wire/android/feature/AccountSwitchUseCase.kt +++ b/app/src/main/kotlin/com/wire/android/feature/AccountSwitchUseCase.kt @@ -161,9 +161,9 @@ sealed class SwitchAccountParam { } sealed class SwitchAccountResult { - object Failure : SwitchAccountResult() - object SwitchedToAnotherAccount : SwitchAccountResult() - object NoOtherAccountToSwitch : SwitchAccountResult() + data object Failure : SwitchAccountResult() + data object SwitchedToAnotherAccount : SwitchAccountResult() + data object NoOtherAccountToSwitch : SwitchAccountResult() fun callAction(actions: SwitchAccountActions) = when (this) { NoOtherAccountToSwitch -> actions.noOtherAccountToSwitch() diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/CallActivity.kt b/app/src/main/kotlin/com/wire/android/ui/calling/CallActivity.kt index be9d4ea7b64..7ff1c4a973d 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/CallActivity.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/CallActivity.kt @@ -68,16 +68,23 @@ class CallActivity : AppCompatActivity() { callNotificationManager.hideAllNotifications() - setUpScreenShootPreventionFlag() - setUpCallingFlags() - - appLogger.i("$TAG Initializing proximity sensor..") - proximitySensorManager.initialize() - WindowCompat.setDecorFitsSystemWindows(window, false) val conversationId = intent.extras?.getString(EXTRA_CONVERSATION_ID) val screenType = intent.extras?.getString(EXTRA_SCREEN_TYPE) + val userId = intent.extras?.getString(EXTRA_USER_ID) + + userId?.let { + qualifiedIdMapper.fromStringToQualifiedID(it).run { + callActivityViewModel.switchAccountIfNeeded(this) + } + } + + setUpCallingFlags() + setUpScreenShootPreventionFlag() + + appLogger.i("$TAG Initializing proximity sensor..") + proximitySensorManager.initialize() setContent { val snackbarHostState = remember { SnackbarHostState() } diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/CallActivityViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/calling/CallActivityViewModel.kt index 7e40cb26840..b504798e1e9 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/CallActivityViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/CallActivityViewModel.kt @@ -20,15 +20,20 @@ package com.wire.android.ui.calling import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.wire.android.di.ObserveScreenshotCensoringConfigUseCaseProvider +import com.wire.android.feature.AccountSwitchUseCase +import com.wire.android.feature.SwitchAccountParam import com.wire.android.util.dispatchers.DispatcherProvider +import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.feature.session.CurrentSessionResult import com.wire.kalium.logic.feature.session.CurrentSessionUseCase import com.wire.kalium.logic.feature.user.screenshotCensoring.ObserveScreenshotCensoringConfigResult import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Deferred +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel @@ -36,7 +41,8 @@ class CallActivityViewModel @Inject constructor( private val dispatchers: DispatcherProvider, private val currentSession: CurrentSessionUseCase, private val observeScreenshotCensoringConfigUseCaseProviderFactory: - ObserveScreenshotCensoringConfigUseCaseProvider.Factory + ObserveScreenshotCensoringConfigUseCaseProvider.Factory, + private val accountSwitch: AccountSwitchUseCase ) : ViewModel() { fun isScreenshotCensoringConfigEnabled(): Deferred = @@ -52,4 +58,17 @@ class CallActivityViewModel @Inject constructor( return@async false } } + + fun switchAccountIfNeeded(userId: UserId) { + viewModelScope.launch(Dispatchers.IO) { + val shouldSwitchAccount = when (val result = currentSession()) { + is CurrentSessionResult.Failure.Generic -> true + CurrentSessionResult.Failure.SessionNotFound -> true + is CurrentSessionResult.Success -> result.accountInfo.userId != userId + } + if (shouldSwitchAccount) { + accountSwitch(SwitchAccountParam.SwitchToAccount(userId)) + } + } + } } diff --git a/app/src/test/kotlin/com/wire/android/ui/CallActivityViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/CallActivityViewModelTest.kt index 429432fb1b1..3cf1e0fea7f 100644 --- a/app/src/test/kotlin/com/wire/android/ui/CallActivityViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/CallActivityViewModelTest.kt @@ -19,6 +19,8 @@ package com.wire.android.ui import com.wire.android.config.TestDispatcherProvider import com.wire.android.di.ObserveScreenshotCensoringConfigUseCaseProvider +import com.wire.android.feature.AccountSwitchUseCase +import com.wire.android.feature.SwitchAccountResult import com.wire.android.ui.calling.CallActivityViewModel import com.wire.kalium.logic.data.auth.AccountInfo import com.wire.kalium.logic.data.user.UserId @@ -28,6 +30,7 @@ import com.wire.kalium.logic.feature.user.screenshotCensoring.ObserveScreenshotC import com.wire.kalium.logic.feature.user.screenshotCensoring.ObserveScreenshotCensoringConfigUseCase import io.mockk.MockKAnnotations import io.mockk.coEvery +import io.mockk.coVerify import io.mockk.every import io.mockk.impl.annotations.MockK import kotlinx.coroutines.flow.flowOf @@ -75,6 +78,45 @@ class CallActivityViewModelTest { assertEquals(false, result.await()) } + @Test + fun `given no session available, when trying to switch account, then try to switchAccount usecase once`() = + runTest { + val (arrangement, viewModel) = Arrangement() + .withCurrentSessionReturning(CurrentSessionResult.Failure.SessionNotFound) + .withAccountSwitch(SwitchAccountResult.Failure) + .arrange() + + viewModel.switchAccountIfNeeded(userId) + + coVerify(exactly = 1) { arrangement.accountSwitch(any()) } + } + + @Test + fun `given userId different from currentSession, when trying to switch account, then invoke switchAccount usecase once`() = + runTest { + val (arrangement, viewModel) = Arrangement() + .withCurrentSessionReturning(CurrentSessionResult.Success(accountInfo)) + .withAccountSwitch(SwitchAccountResult.SwitchedToAnotherAccount) + .arrange() + + viewModel.switchAccountIfNeeded(UserId("anotherUserId", "domain")) + + coVerify(exactly = 1) { arrangement.accountSwitch(any()) } + } + + @Test + fun `given userId same as currentSession, when trying to switch account, then do not invoke switchAccount usecase`() = + runTest { + val (arrangement, viewModel) = Arrangement() + .withCurrentSessionReturning(CurrentSessionResult.Success(accountInfo)) + .withAccountSwitch(SwitchAccountResult.SwitchedToAnotherAccount) + .arrange() + + viewModel.switchAccountIfNeeded(userId) + + coVerify(inverse = true) { arrangement.accountSwitch(any()) } + } + private class Arrangement { @MockK @@ -84,6 +126,9 @@ class CallActivityViewModelTest { @MockK private lateinit var currentSession: CurrentSessionUseCase + @MockK + lateinit var accountSwitch: AccountSwitchUseCase + @MockK private lateinit var observeScreenshotCensoringConfig: ObserveScreenshotCensoringConfigUseCase @@ -99,6 +144,7 @@ class CallActivityViewModelTest { dispatchers = TestDispatcherProvider(), currentSession = currentSession, observeScreenshotCensoringConfigUseCaseProviderFactory = observeScreenshotCensoringConfigUseCaseProviderFactory, + accountSwitch = accountSwitch ) } @@ -108,6 +154,10 @@ class CallActivityViewModelTest { coEvery { currentSession() } returns result } + suspend fun withAccountSwitch(result: SwitchAccountResult) = apply { + coEvery { accountSwitch(any()) } returns result + } + suspend fun withScreenshotCensoringConfigReturning(result: ObserveScreenshotCensoringConfigResult) = apply { coEvery { observeScreenshotCensoringConfig() } returns flowOf(result) @@ -115,6 +165,7 @@ class CallActivityViewModelTest { } companion object { - val accountInfo = AccountInfo.Valid(userId = UserId("userId", "domain")) + val userId = UserId("userId", "domain") + val accountInfo = AccountInfo.Valid(userId = userId) } }