From 424b5141a9924393cc228d6f002244581380969b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Saleniuk?= Date: Fri, 29 Dec 2023 18:23:33 +0100 Subject: [PATCH 1/3] fix: applock toggle state when enforced and responding to changes [WPB-5751] --- .../com/wire/android/di/CoreLogicModule.kt | 6 ++--- .../android/feature/DisableAppLockUseCase.kt | 7 +++--- .../appLock/set/SetLockScreenViewModel.kt | 24 ++++++++++--------- .../ui/home/settings/SettingsScreen.kt | 11 +++------ .../ui/home/settings/SettingsViewModel.kt | 21 +++++++++------- .../feature/DisableAppLockUseCaseTest.kt | 9 +++---- .../appLock/set/SetLockScreenViewModelTest.kt | 10 ++++---- kalium | 2 +- 8 files changed, 47 insertions(+), 43 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt b/app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt index a9f91f41ad5..0835d6ad8ff 100644 --- a/app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt +++ b/app/src/main/kotlin/com/wire/android/di/CoreLogicModule.kt @@ -35,7 +35,7 @@ import com.wire.kalium.logic.feature.connection.BlockUserUseCase import com.wire.kalium.logic.feature.connection.UnblockUserUseCase import com.wire.kalium.logic.feature.conversation.ObserveOtherUserSecurityClassificationLabelUseCase import com.wire.kalium.logic.feature.conversation.ObserveSecurityClassificationLabelUseCase -import com.wire.kalium.logic.feature.featureConfig.IsAppLockEditableUseCase +import com.wire.kalium.logic.feature.featureConfig.ObserveIsAppLockEditableUseCase import com.wire.kalium.logic.feature.selfDeletingMessages.ObserveSelfDeletionTimerSettingsForConversationUseCase import com.wire.kalium.logic.feature.selfDeletingMessages.ObserveTeamSettingsSelfDeletingStatusUseCase import com.wire.kalium.logic.feature.selfDeletingMessages.PersistNewSelfDeletionTimerUseCase @@ -431,7 +431,7 @@ class UseCaseModule { @ViewModelScoped @Provides - fun provideIsAppLockEditableUseCase( + fun provideObserveIsAppLockEditableUseCase( @KaliumCoreLogic coreLogic: CoreLogic - ): IsAppLockEditableUseCase = coreLogic.getGlobalScope().isAppLockEditableUseCase + ): ObserveIsAppLockEditableUseCase = coreLogic.getGlobalScope().observeIsAppLockEditableUseCase } diff --git a/app/src/main/kotlin/com/wire/android/feature/DisableAppLockUseCase.kt b/app/src/main/kotlin/com/wire/android/feature/DisableAppLockUseCase.kt index 6f6b735854a..10312cea1ca 100644 --- a/app/src/main/kotlin/com/wire/android/feature/DisableAppLockUseCase.kt +++ b/app/src/main/kotlin/com/wire/android/feature/DisableAppLockUseCase.kt @@ -18,16 +18,17 @@ package com.wire.android.feature import com.wire.android.datastore.GlobalDataStore -import com.wire.kalium.logic.feature.featureConfig.IsAppLockEditableUseCase +import com.wire.kalium.logic.feature.featureConfig.ObserveIsAppLockEditableUseCase import dagger.hilt.android.scopes.ViewModelScoped +import kotlinx.coroutines.flow.firstOrNull import javax.inject.Inject @ViewModelScoped class DisableAppLockUseCase @Inject constructor( private val dataStore: GlobalDataStore, - private val isAppLockEditableUseCase: IsAppLockEditableUseCase + private val observeIsAppLockEditableUseCase: ObserveIsAppLockEditableUseCase ) { - suspend operator fun invoke(): Boolean = if (isAppLockEditableUseCase()) { + suspend operator fun invoke(): Boolean = if (observeIsAppLockEditableUseCase().firstOrNull() == true) { dataStore.clearAppLockPasscode() true } else { diff --git a/app/src/main/kotlin/com/wire/android/ui/home/appLock/set/SetLockScreenViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/home/appLock/set/SetLockScreenViewModel.kt index 2162a0556d5..66c1a55dd47 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/appLock/set/SetLockScreenViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/appLock/set/SetLockScreenViewModel.kt @@ -29,9 +29,10 @@ import com.wire.android.feature.ObserveAppLockConfigUseCase import com.wire.android.util.dispatchers.DispatcherProvider import com.wire.kalium.logic.feature.applock.MarkTeamAppLockStatusAsNotifiedUseCase import com.wire.kalium.logic.feature.auth.ValidatePasswordUseCase -import com.wire.kalium.logic.feature.featureConfig.IsAppLockEditableUseCase +import com.wire.kalium.logic.feature.featureConfig.ObserveIsAppLockEditableUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import javax.inject.Inject @@ -42,7 +43,7 @@ class SetLockScreenViewModel @Inject constructor( private val globalDataStore: GlobalDataStore, private val dispatchers: DispatcherProvider, private val observeAppLockConfig: ObserveAppLockConfigUseCase, - private val isAppLockEditable: IsAppLockEditableUseCase, + private val observeIsAppLockEditable: ObserveIsAppLockEditableUseCase, private val markTeamAppLockStatusAsNotified: MarkTeamAppLockStatusAsNotifiedUseCase ) : ViewModel() { @@ -51,14 +52,15 @@ class SetLockScreenViewModel @Inject constructor( init { viewModelScope.launch { - val isEditable = isAppLockEditable() - observeAppLockConfig() - .collectLatest { - state = state.copy( - timeout = it.timeout, - isEditable = isEditable - ) - } + combine( + observeAppLockConfig(), + observeIsAppLockEditable() + ) { config, isEditable -> + SetLockCodeViewState( + timeout = config.timeout, + isEditable = isEditable + ) + }.collectLatest { state = it } } } @@ -84,7 +86,7 @@ class SetLockScreenViewModel @Inject constructor( viewModelScope.launch { withContext(dispatchers.io()) { with(globalDataStore) { - val source = if (isAppLockEditable()) { + val source = if (state.isEditable) { AppLockSource.Manual } else { AppLockSource.TeamEnforced diff --git a/app/src/main/kotlin/com/wire/android/ui/home/settings/SettingsScreen.kt b/app/src/main/kotlin/com/wire/android/ui/home/settings/SettingsScreen.kt index 4e05ce38e2d..df22b67ccf4 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/settings/SettingsScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/settings/SettingsScreen.kt @@ -116,12 +116,11 @@ fun SettingsScreenContent( } add(SettingsItem.NetworkSettings) + appLogger.d("AppLockConfig " + + "isAppLockEditable: ${settingsState.isAppLockEditable} isAppLockEnabled: ${settingsState.isAppLockEnabled}") add(SettingsItem.AppLock( when (settingsState.isAppLockEditable) { true -> { - appLogger.d("AppLockConfig isAooLockEditable: ${settingsState.isAppLockEditable}") - - appLogger.d("AppLockConfig isAppLockEnabled: ${settingsState.isAppLockEnabled}") SwitchState.Enabled( value = settingsState.isAppLockEnabled, isOnOffVisible = true, @@ -130,12 +129,8 @@ fun SettingsScreenContent( } false -> { - appLogger.d("AppLockConfig isAooLockEditable: ${settingsState.isAppLockEditable}") - - appLogger.d("AppLockConfig isAppLockEnabled: ${settingsState.isAppLockEnabled}") - SwitchState.Disabled( + SwitchState.TextOnly( value = settingsState.isAppLockEnabled, - isOnOffVisible = true, ) } } diff --git a/app/src/main/kotlin/com/wire/android/ui/home/settings/SettingsViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/home/settings/SettingsViewModel.kt index fc0945cad29..b77ccb587b2 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/settings/SettingsViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/settings/SettingsViewModel.kt @@ -26,27 +26,32 @@ import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.wire.android.datastore.GlobalDataStore -import com.wire.kalium.logic.feature.featureConfig.IsAppLockEditableUseCase +import com.wire.kalium.logic.feature.featureConfig.ObserveIsAppLockEditableUseCase import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class SettingsViewModel @Inject constructor( private val globalDataStore: GlobalDataStore, - private val isAppLockEditableUseCase: IsAppLockEditableUseCase + private val observeIsAppLockEditable: ObserveIsAppLockEditableUseCase ) : ViewModel() { var state by mutableStateOf(SettingsState()) private set init { viewModelScope.launch { - isAppLockEditableUseCase().let { - state = state.copy(isAppLockEditable = it) - } - globalDataStore.isAppLockPasscodeSetFlow().collect { - state = state.copy(isAppLockEnabled = it) - } + combine( + observeIsAppLockEditable(), + globalDataStore.isAppLockPasscodeSetFlow() + ) { + isAppLockEditable, isAppLockEnabled -> + SettingsState( + isAppLockEditable = isAppLockEditable, + isAppLockEnabled = isAppLockEnabled + ) + }.collect { state = it } } } diff --git a/app/src/test/kotlin/com/wire/android/feature/DisableAppLockUseCaseTest.kt b/app/src/test/kotlin/com/wire/android/feature/DisableAppLockUseCaseTest.kt index d5c5492bbf7..ce7e875c71e 100644 --- a/app/src/test/kotlin/com/wire/android/feature/DisableAppLockUseCaseTest.kt +++ b/app/src/test/kotlin/com/wire/android/feature/DisableAppLockUseCaseTest.kt @@ -18,11 +18,12 @@ package com.wire.android.feature import com.wire.android.datastore.GlobalDataStore -import com.wire.kalium.logic.feature.featureConfig.IsAppLockEditableUseCase +import com.wire.kalium.logic.feature.featureConfig.ObserveIsAppLockEditableUseCase import io.mockk.MockKAnnotations import io.mockk.coEvery import io.mockk.coVerify import io.mockk.impl.annotations.MockK +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test @@ -60,15 +61,15 @@ class DisableAppLockUseCaseTest { lateinit var dataStore: GlobalDataStore @MockK - lateinit var isAppLockEditableUseCase: IsAppLockEditableUseCase + lateinit var observeIsAppLockEditableUseCase: ObserveIsAppLockEditableUseCase private val useCase = DisableAppLockUseCase( dataStore, - isAppLockEditableUseCase + observeIsAppLockEditableUseCase ) fun withAppLockEditable(result: Boolean) = apply { - coEvery { isAppLockEditableUseCase() } returns result + coEvery { observeIsAppLockEditableUseCase() } returns flowOf(result) } fun withClearAppLockPasscode() = apply { diff --git a/app/src/test/kotlin/com/wire/android/ui/home/appLock/set/SetLockScreenViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/home/appLock/set/SetLockScreenViewModelTest.kt index fc28bf11ca5..1683f263b38 100644 --- a/app/src/test/kotlin/com/wire/android/ui/home/appLock/set/SetLockScreenViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/home/appLock/set/SetLockScreenViewModelTest.kt @@ -26,7 +26,7 @@ import com.wire.android.feature.ObserveAppLockConfigUseCase import com.wire.kalium.logic.feature.applock.MarkTeamAppLockStatusAsNotifiedUseCase import com.wire.kalium.logic.feature.auth.ValidatePasswordResult import com.wire.kalium.logic.feature.auth.ValidatePasswordUseCase -import com.wire.kalium.logic.feature.featureConfig.IsAppLockEditableUseCase +import com.wire.kalium.logic.feature.featureConfig.ObserveIsAppLockEditableUseCase import io.mockk.MockKAnnotations import io.mockk.coEvery import io.mockk.every @@ -83,7 +83,7 @@ class SetLockScreenViewModelTest { private lateinit var markTeamAppLockStatusAsNotified: MarkTeamAppLockStatusAsNotifiedUseCase @MockK - private lateinit var isAppLockEditableUseCase: IsAppLockEditableUseCase + private lateinit var observeIsAppLockEditableUseCase: ObserveIsAppLockEditableUseCase init { MockKAnnotations.init(this, relaxUnitFun = true) @@ -91,7 +91,7 @@ class SetLockScreenViewModelTest { coEvery { observeAppLockConfig() } returns flowOf( AppLockConfig.Disabled(ObserveAppLockConfigUseCase.DEFAULT_APP_LOCK_TIMEOUT) ) - coEvery { isAppLockEditableUseCase() } returns true + coEvery { observeIsAppLockEditableUseCase() } returns flowOf(true) } fun withValidPassword() = apply { @@ -103,7 +103,7 @@ class SetLockScreenViewModelTest { } fun withIsAppLockEditable(result: Boolean) = apply { - coEvery { isAppLockEditableUseCase() } returns result + coEvery { observeIsAppLockEditableUseCase() } returns flowOf(result) } private val viewModel = SetLockScreenViewModel( @@ -111,7 +111,7 @@ class SetLockScreenViewModelTest { globalDataStore, TestDispatcherProvider(), observeAppLockConfig, - isAppLockEditableUseCase, + observeIsAppLockEditableUseCase, markTeamAppLockStatusAsNotified ) diff --git a/kalium b/kalium index 3a80367c0dd..d0a743bc0bb 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit 3a80367c0dde3f8ae593a48a4f65bdb0750e754e +Subproject commit d0a743bc0bb2a897536c958f0adc1e3778691146 From 99ce3edc11cfc467d533f1d5e10a5f4c80f0c931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Saleniuk?= Date: Wed, 3 Jan 2024 18:02:07 +0100 Subject: [PATCH 2/3] update kalium ref --- kalium | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kalium b/kalium index d0a743bc0bb..3b2ac67ec72 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit d0a743bc0bb2a897536c958f0adc1e3778691146 +Subproject commit 3b2ac67ec7276057bd92bb262169f78ebff67508 From 349980459704d39daf6efdf8f06e15e309e06cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Saleniuk?= Date: Thu, 4 Jan 2024 11:31:44 +0100 Subject: [PATCH 3/3] update kalium ref --- kalium | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kalium b/kalium index 3b2ac67ec72..05b82b1cd1c 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit 3b2ac67ec7276057bd92bb262169f78ebff67508 +Subproject commit 05b82b1cd1c058b71221b131d785485d14dfd84d