From d201fc7f6aa57c53f138f8490c8e016c7ef6b0ed Mon Sep 17 00:00:00 2001 From: MohamadJaara Date: Mon, 15 Apr 2024 14:38:38 +0200 Subject: [PATCH 1/2] feat: display avs and CC version on all builds --- .../wire/android/ui/debug/DebugDataOptions.kt | 271 +++--------------- .../android/ui/debug/DebugDataOptionsState.kt | 32 +++ .../ui/debug/DebugDataOptionsViewModel.kt | 205 +++++++++++++ app/src/main/res/values/strings.xml | 1 + .../kotlin/scripts/compilation.gradle.kts | 2 +- 5 files changed, 283 insertions(+), 228 deletions(-) create mode 100644 app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt create mode 100644 app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt index 1d9fbeb0301..692d7cd2aba 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt @@ -17,7 +17,6 @@ */ package com.wire.android.ui.debug -import android.content.Context import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -25,20 +24,17 @@ import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.MutableState import androidx.compose.runtime.Stable -import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope import com.wire.android.BuildConfig import com.wire.android.R -import com.wire.android.datastore.GlobalDataStore -import com.wire.android.di.CurrentAccount -import com.wire.android.migration.failure.UserMigrationStatus import com.wire.android.model.Clickable import com.wire.android.ui.common.RowItemTemplate import com.wire.android.ui.common.WireDialog @@ -53,214 +49,15 @@ import com.wire.android.ui.home.settings.SettingsItem import com.wire.android.ui.theme.wireColorScheme import com.wire.android.ui.theme.wireDimensions import com.wire.android.ui.theme.wireTypography +import com.wire.android.util.EMPTY import com.wire.android.util.getDependenciesVersion -import com.wire.android.util.getDeviceIdString -import com.wire.android.util.getGitBuildId import com.wire.android.util.ui.PreviewMultipleThemes import com.wire.kalium.logic.CoreFailure -import com.wire.kalium.logic.E2EIFailure import com.wire.kalium.logic.data.user.UserId -import com.wire.kalium.logic.feature.debug.DisableEventProcessingUseCase -import com.wire.kalium.logic.feature.e2ei.CheckCrlRevocationListUseCase import com.wire.kalium.logic.feature.e2ei.usecase.E2EIEnrollmentResult -import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountResult -import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountUseCase import com.wire.kalium.logic.functional.Either -import com.wire.kalium.logic.functional.fold -import com.wire.kalium.logic.sync.periodic.UpdateApiVersionsScheduler -import com.wire.kalium.logic.sync.slow.RestartSlowSyncProcessForRecoveryUseCase -import dagger.hilt.android.lifecycle.HiltViewModel -import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.collections.immutable.ImmutableMap -import kotlinx.collections.immutable.persistentMapOf -import kotlinx.collections.immutable.toImmutableMap -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.launch -import javax.inject.Inject - -//region DebugDataOptionsViewModel -data class DebugDataOptionsState( - val isEncryptedProteusStorageEnabled: Boolean = false, - val isEventProcessingDisabled: Boolean = false, - val keyPackagesCount: Int = 0, - val mslClientId: String = "null", - val mlsErrorMessage: String = "null", - val isManualMigrationAllowed: Boolean = false, - val debugId: String = "null", - val commitish: String = "null", - val certificate: String = "null", - val showCertificate: Boolean = false, - val startGettingE2EICertificate: Boolean = false, - val dependencies: ImmutableMap = persistentMapOf() -) - -@Suppress("LongParameterList") -@HiltViewModel -class DebugDataOptionsViewModel -@Inject constructor( - @ApplicationContext private val context: Context, - @CurrentAccount val currentAccount: UserId, - private val globalDataStore: GlobalDataStore, - private val updateApiVersions: UpdateApiVersionsScheduler, - private val mlsKeyPackageCountUseCase: MLSKeyPackageCountUseCase, - private val restartSlowSyncProcessForRecovery: RestartSlowSyncProcessForRecoveryUseCase, - private val disableEventProcessingUseCase: DisableEventProcessingUseCase, - private val checkCrlRevocationListUseCase: CheckCrlRevocationListUseCase -) : ViewModel() { - - var state by mutableStateOf( - DebugDataOptionsState() - ) - - init { - observeEncryptedProteusStorageState() - observeMlsMetadata() - checkIfCanTriggerManualMigration() - checkDependenciesVersion() - setGitHashAndDeviceId() - } - - private fun setGitHashAndDeviceId() { - viewModelScope.launch { - val deviceId = context.getDeviceIdString() ?: "null" - val gitBuildId = context.getGitBuildId() - state = state.copy( - debugId = deviceId, - commitish = gitBuildId - ) - } - } - - fun checkCrlRevocationList() { - viewModelScope.launch { - checkCrlRevocationListUseCase( - forceUpdate = true - ) - } - } - - fun checkDependenciesVersion() { - viewModelScope.launch { - val dependencies = context.getDependenciesVersion().toImmutableMap() - state = state.copy( - dependencies = dependencies - ) - } - } - - fun enableEncryptedProteusStorage(enabled: Boolean) { - if (enabled) { - viewModelScope.launch { - globalDataStore.setEncryptedProteusStorageEnabled(true) - } - } - } - - fun restartSlowSyncForRecovery() { - viewModelScope.launch { - restartSlowSyncProcessForRecovery() - } - } - - fun enrollE2EICertificate() { - state = state.copy(startGettingE2EICertificate = true) - } - - fun handleE2EIEnrollmentResult(result: Either) { - result.fold({ - state = state.copy( - certificate = (it as E2EIFailure.OAuth).reason, - showCertificate = true, - startGettingE2EICertificate = false - ) - }, { - if (it is E2EIEnrollmentResult.Finalized) { - state = state.copy( - certificate = it.certificate, - showCertificate = true, - startGettingE2EICertificate = false - ) - } else { - state.copy( - certificate = it.toString(), - showCertificate = true, - startGettingE2EICertificate = false - ) - } - }) - } - - fun dismissCertificateDialog() { - state = state.copy( - showCertificate = false, - ) - } - - fun forceUpdateApiVersions() { - updateApiVersions.scheduleImmediateApiVersionUpdate() - } - - fun disableEventProcessing(disabled: Boolean) { - viewModelScope.launch { - disableEventProcessingUseCase(disabled) - state = state.copy(isEventProcessingDisabled = disabled) - } - } - - //region Private - private fun observeEncryptedProteusStorageState() { - viewModelScope.launch { - globalDataStore.isEncryptedProteusStorageEnabled().collect { - state = state.copy(isEncryptedProteusStorageEnabled = it) - } - } - } - - // If status is NoNeed, it means that the user has already been migrated in and older app version, - // or it is a new install - // this is why we check the existence of the database file - private fun checkIfCanTriggerManualMigration() { - viewModelScope.launch { - globalDataStore.getUserMigrationStatus(currentAccount.value).first() - .let { migrationStatus -> - if (migrationStatus != UserMigrationStatus.NoNeed) { - context.getDatabasePath(currentAccount.value).let { - state = state.copy( - isManualMigrationAllowed = (it.exists() && it.isFile) - ) - } - } - } - } - } - - private fun observeMlsMetadata() { - viewModelScope.launch { - mlsKeyPackageCountUseCase().let { - when (it) { - is MLSKeyPackageCountResult.Success -> { - state = state.copy( - keyPackagesCount = it.count, - mslClientId = it.clientId.value - ) - } - - is MLSKeyPackageCountResult.Failure.NetworkCallFailure -> { - state = state.copy(mlsErrorMessage = "Network Error!") - } - - is MLSKeyPackageCountResult.Failure.FetchClientIdFailure -> { - state = state.copy(mlsErrorMessage = "ClientId Fetch Error!") - } - - is MLSKeyPackageCountResult.Failure.Generic -> {} - } - } - } - } - //endregion -} -//endregion +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext @Composable fun DebugDataOptions( @@ -337,6 +134,7 @@ fun DebugDataOptionsContent( onClick = { onCopyText(state.commitish) } ) ) + dependenciesItem() if (BuildConfig.PRIVATE_BUILD) { SettingsItem( @@ -399,8 +197,7 @@ fun DebugDataOptionsContent( onDisableEventProcessingChange = onDisableEventProcessingChange, onRestartSlowSyncForRecovery = onRestartSlowSyncForRecovery, onForceUpdateApiVersions = onForceUpdateApiVersions, - checkCrlRevocationList = checkCrlRevocationList, - dependenciesMap = state.dependencies + checkCrlRevocationList = checkCrlRevocationList ) } @@ -569,8 +366,7 @@ private fun DebugToolsOptions( onDisableEventProcessingChange: (Boolean) -> Unit, onRestartSlowSyncForRecovery: () -> Unit, onForceUpdateApiVersions: () -> Unit, - checkCrlRevocationList: () -> Unit, - dependenciesMap: ImmutableMap + checkCrlRevocationList: () -> Unit ) { FolderHeader(stringResource(R.string.label_debug_tools_title)) Column { @@ -641,20 +437,41 @@ private fun DebugToolsOptions( ) } ) - RowItemTemplate( - modifier = Modifier.wrapContentWidth(), - title = { - Text( - style = MaterialTheme.wireTypography.body01, - color = MaterialTheme.wireColorScheme.onBackground, - text = prettyPrintMap(dependenciesMap), - modifier = Modifier.padding(start = dimensions().spacing8x) - ) - } - ) } } +/** + * + */ +@Composable +fun dependenciesItem() { + val applicationContext = LocalContext.current.applicationContext + val state: MutableState = remember { mutableStateOf(String.EMPTY) } + + LaunchedEffect(key1 = Unit) { + withContext(Dispatchers.IO) { + val title = applicationContext.resources.getString(R.string.item_dependencies_title) + applicationContext.getDependenciesVersion().let { + prettyPrintMap(it, title) + }.also { + withContext(Dispatchers.Main) { + state.value = it + } + } + } + } + RowItemTemplate( + modifier = Modifier.wrapContentWidth(), + title = { + Text( + style = MaterialTheme.wireTypography.body01, + color = MaterialTheme.wireColorScheme.onBackground, + text = state.value, + modifier = Modifier.padding(start = dimensions().spacing8x) + ) + } + ) +} @Composable private fun DisableEventProcessingSwitch( isEnabled: Boolean = false, @@ -685,8 +502,8 @@ private fun DisableEventProcessingSwitch( } @Stable -private fun prettyPrintMap(map: ImmutableMap): String = StringBuilder().apply { - append("Dependencies:\n") +private fun prettyPrintMap(map: Map, title: String): String = StringBuilder().apply { + append("$title\n") map.forEach { (key, value) -> append("$key: $value\n") } diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt new file mode 100644 index 00000000000..94e9500528a --- /dev/null +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt @@ -0,0 +1,32 @@ +/* + * 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.android.ui.debug + +data class DebugDataOptionsState( + val isEncryptedProteusStorageEnabled: Boolean = false, + val isEventProcessingDisabled: Boolean = false, + val keyPackagesCount: Int = 0, + val mslClientId: String = "null", + val mlsErrorMessage: String = "null", + val isManualMigrationAllowed: Boolean = false, + val debugId: String = "null", + val commitish: String = "null", + val certificate: String = "null", + val showCertificate: Boolean = false, + val startGettingE2EICertificate: Boolean = false +) diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt new file mode 100644 index 00000000000..2dd92e9a3a0 --- /dev/null +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt @@ -0,0 +1,205 @@ +/* + * 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.android.ui.debug + +import android.content.Context +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.wire.android.datastore.GlobalDataStore +import com.wire.android.di.CurrentAccount +import com.wire.android.migration.failure.UserMigrationStatus +import com.wire.android.util.getDeviceIdString +import com.wire.android.util.getGitBuildId +import com.wire.kalium.logic.CoreFailure +import com.wire.kalium.logic.E2EIFailure +import com.wire.kalium.logic.data.user.UserId +import com.wire.kalium.logic.feature.debug.DisableEventProcessingUseCase +import com.wire.kalium.logic.feature.e2ei.CheckCrlRevocationListUseCase +import com.wire.kalium.logic.feature.e2ei.usecase.E2EIEnrollmentResult +import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountResult +import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountUseCase +import com.wire.kalium.logic.functional.Either +import com.wire.kalium.logic.functional.fold +import com.wire.kalium.logic.sync.periodic.UpdateApiVersionsScheduler +import com.wire.kalium.logic.sync.slow.RestartSlowSyncProcessForRecoveryUseCase +import dagger.hilt.android.lifecycle.HiltViewModel +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch +import javax.inject.Inject + +@Suppress("LongParameterList") +@HiltViewModel +class DebugDataOptionsViewModel +@Inject constructor( + @ApplicationContext private val context: Context, + @CurrentAccount val currentAccount: UserId, + private val globalDataStore: GlobalDataStore, + private val updateApiVersions: UpdateApiVersionsScheduler, + private val mlsKeyPackageCountUseCase: MLSKeyPackageCountUseCase, + private val restartSlowSyncProcessForRecovery: RestartSlowSyncProcessForRecoveryUseCase, + private val disableEventProcessingUseCase: DisableEventProcessingUseCase, + private val checkCrlRevocationListUseCase: CheckCrlRevocationListUseCase +) : ViewModel() { + + var state by mutableStateOf( + DebugDataOptionsState() + ) + + init { + observeEncryptedProteusStorageState() + observeMlsMetadata() + checkIfCanTriggerManualMigration() + setGitHashAndDeviceId() + } + + private fun setGitHashAndDeviceId() { + viewModelScope.launch { + val deviceId = context.getDeviceIdString() ?: "null" + val gitBuildId = context.getGitBuildId() + state = state.copy( + debugId = deviceId, + commitish = gitBuildId + ) + } + } + + fun checkCrlRevocationList() { + viewModelScope.launch { + checkCrlRevocationListUseCase( + forceUpdate = true + ) + } + } + + fun enableEncryptedProteusStorage(enabled: Boolean) { + if (enabled) { + viewModelScope.launch { + globalDataStore.setEncryptedProteusStorageEnabled(true) + } + } + } + + fun restartSlowSyncForRecovery() { + viewModelScope.launch { + restartSlowSyncProcessForRecovery() + } + } + + fun enrollE2EICertificate() { + state = state.copy(startGettingE2EICertificate = true) + } + + fun handleE2EIEnrollmentResult(result: Either) { + result.fold({ + state = state.copy( + certificate = (it as E2EIFailure.OAuth).reason, + showCertificate = true, + startGettingE2EICertificate = false + ) + }, { + if (it is E2EIEnrollmentResult.Finalized) { + state = state.copy( + certificate = it.certificate, + showCertificate = true, + startGettingE2EICertificate = false + ) + } else { + state.copy( + certificate = it.toString(), + showCertificate = true, + startGettingE2EICertificate = false + ) + } + }) + } + + fun dismissCertificateDialog() { + state = state.copy( + showCertificate = false, + ) + } + + fun forceUpdateApiVersions() { + updateApiVersions.scheduleImmediateApiVersionUpdate() + } + + fun disableEventProcessing(disabled: Boolean) { + viewModelScope.launch { + disableEventProcessingUseCase(disabled) + state = state.copy(isEventProcessingDisabled = disabled) + } + } + + //region Private + private fun observeEncryptedProteusStorageState() { + viewModelScope.launch { + globalDataStore.isEncryptedProteusStorageEnabled().collect { + state = state.copy(isEncryptedProteusStorageEnabled = it) + } + } + } + + // If status is NoNeed, it means that the user has already been migrated in and older app version, + // or it is a new install + // this is why we check the existence of the database file + private fun checkIfCanTriggerManualMigration() { + viewModelScope.launch { + globalDataStore.getUserMigrationStatus(currentAccount.value).first() + .let { migrationStatus -> + if (migrationStatus != UserMigrationStatus.NoNeed) { + context.getDatabasePath(currentAccount.value).let { + state = state.copy( + isManualMigrationAllowed = (it.exists() && it.isFile) + ) + } + } + } + } + } + + private fun observeMlsMetadata() { + viewModelScope.launch { + mlsKeyPackageCountUseCase().let { + when (it) { + is MLSKeyPackageCountResult.Success -> { + state = state.copy( + keyPackagesCount = it.count, + mslClientId = it.clientId.value + ) + } + + is MLSKeyPackageCountResult.Failure.NetworkCallFailure -> { + state = state.copy(mlsErrorMessage = "Network Error!") + } + + is MLSKeyPackageCountResult.Failure.FetchClientIdFailure -> { + state = state.copy(mlsErrorMessage = "ClientId Fetch Error!") + } + + is MLSKeyPackageCountResult.Failure.Generic -> {} + } + } + } + } + //endregion +} +//endregion diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2e526d1d4e4..e190e8ba290 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -199,6 +199,7 @@ API VERSIONING E2EI Manual Enrollment Force API versioning update + Dependencies: Update Support Back up & Restore Conversations diff --git a/buildSrc/src/main/kotlin/scripts/compilation.gradle.kts b/buildSrc/src/main/kotlin/scripts/compilation.gradle.kts index 7070edf870a..421db62bed7 100644 --- a/buildSrc/src/main/kotlin/scripts/compilation.gradle.kts +++ b/buildSrc/src/main/kotlin/scripts/compilation.gradle.kts @@ -36,7 +36,7 @@ val dependenciesVersionTask = project.tasks.register("dependenciesVersionTask", val catalog = catalogs.named("klibs") val pairs = mapOf( "avs" to catalog.findVersion("avs").get().requiredVersion, - "core-crypto" to catalog.findVersion("core-crypto-multiplatform").get().requiredVersion + "core-crypto" to catalog.findVersion("core-crypto").get().requiredVersion ) keyValues.set(pairs) } From a7a45461fc036bf37e503327fae80876b23723df Mon Sep 17 00:00:00 2001 From: MohamadJaara Date: Mon, 15 Apr 2024 19:42:24 +0200 Subject: [PATCH 2/2] address PR comments --- .../wire/android/ui/debug/DebugDataOptions.kt | 43 +++++++------------ .../android/ui/debug/DebugDataOptionsState.kt | 6 ++- .../ui/debug/DebugDataOptionsViewModel.kt | 24 ++++++++--- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt index 692d7cd2aba..a51e152fecb 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt @@ -24,13 +24,9 @@ import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.MutableState import androidx.compose.runtime.Stable -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.hilt.navigation.compose.hiltViewModel import com.wire.android.BuildConfig @@ -49,15 +45,13 @@ import com.wire.android.ui.home.settings.SettingsItem import com.wire.android.ui.theme.wireColorScheme import com.wire.android.ui.theme.wireDimensions import com.wire.android.ui.theme.wireTypography -import com.wire.android.util.EMPTY -import com.wire.android.util.getDependenciesVersion import com.wire.android.util.ui.PreviewMultipleThemes import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.feature.e2ei.usecase.E2EIEnrollmentResult import com.wire.kalium.logic.functional.Either -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.collections.immutable.ImmutableMap +import kotlinx.collections.immutable.persistentMapOf @Composable fun DebugDataOptions( @@ -80,7 +74,8 @@ fun DebugDataOptions( enrollE2EICertificate = viewModel::enrollE2EICertificate, handleE2EIEnrollmentResult = viewModel::handleE2EIEnrollmentResult, dismissCertificateDialog = viewModel::dismissCertificateDialog, - checkCrlRevocationList = viewModel::checkCrlRevocationList + checkCrlRevocationList = viewModel::checkCrlRevocationList, + dependenciesMap = viewModel.state.dependencies ) } @@ -99,7 +94,8 @@ fun DebugDataOptionsContent( enrollE2EICertificate: () -> Unit, handleE2EIEnrollmentResult: (Either) -> Unit, dismissCertificateDialog: () -> Unit, - checkCrlRevocationList: () -> Unit + checkCrlRevocationList: () -> Unit, + dependenciesMap: ImmutableMap ) { Column { @@ -134,7 +130,7 @@ fun DebugDataOptionsContent( onClick = { onCopyText(state.commitish) } ) ) - dependenciesItem() + DependenciesItem(dependenciesMap) if (BuildConfig.PRIVATE_BUILD) { SettingsItem( @@ -444,21 +440,10 @@ private fun DebugToolsOptions( * */ @Composable -fun dependenciesItem() { - val applicationContext = LocalContext.current.applicationContext - val state: MutableState = remember { mutableStateOf(String.EMPTY) } - - LaunchedEffect(key1 = Unit) { - withContext(Dispatchers.IO) { - val title = applicationContext.resources.getString(R.string.item_dependencies_title) - applicationContext.getDependenciesVersion().let { - prettyPrintMap(it, title) - }.also { - withContext(Dispatchers.Main) { - state.value = it - } - } - } +fun DependenciesItem(dependencies: ImmutableMap) { + val title = stringResource(id = R.string.item_dependencies_title) + val text = remember { + prettyPrintMap(dependencies, title) } RowItemTemplate( modifier = Modifier.wrapContentWidth(), @@ -466,12 +451,13 @@ fun dependenciesItem() { Text( style = MaterialTheme.wireTypography.body01, color = MaterialTheme.wireColorScheme.onBackground, - text = state.value, + text = text, modifier = Modifier.padding(start = dimensions().spacing8x) ) } ) } + @Composable private fun DisableEventProcessingSwitch( isEnabled: Boolean = false, @@ -535,6 +521,7 @@ fun PreviewOtherDebugOptions() { enrollE2EICertificate = {}, handleE2EIEnrollmentResult = {}, dismissCertificateDialog = {}, - checkCrlRevocationList = {} + checkCrlRevocationList = {}, + dependenciesMap = persistentMapOf() ) } diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt index 94e9500528a..c0f648184dc 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsState.kt @@ -17,6 +17,9 @@ */ package com.wire.android.ui.debug +import kotlinx.collections.immutable.ImmutableMap +import kotlinx.collections.immutable.persistentMapOf + data class DebugDataOptionsState( val isEncryptedProteusStorageEnabled: Boolean = false, val isEventProcessingDisabled: Boolean = false, @@ -28,5 +31,6 @@ data class DebugDataOptionsState( val commitish: String = "null", val certificate: String = "null", val showCertificate: Boolean = false, - val startGettingE2EICertificate: Boolean = false + val startGettingE2EICertificate: Boolean = false, + val dependencies: ImmutableMap = persistentMapOf() ) diff --git a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt index 2dd92e9a3a0..944c27e0336 100644 --- a/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt @@ -26,12 +26,12 @@ import androidx.lifecycle.viewModelScope import com.wire.android.datastore.GlobalDataStore import com.wire.android.di.CurrentAccount import com.wire.android.migration.failure.UserMigrationStatus +import com.wire.android.util.getDependenciesVersion import com.wire.android.util.getDeviceIdString import com.wire.android.util.getGitBuildId import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.E2EIFailure import com.wire.kalium.logic.data.user.UserId -import com.wire.kalium.logic.feature.debug.DisableEventProcessingUseCase import com.wire.kalium.logic.feature.e2ei.CheckCrlRevocationListUseCase import com.wire.kalium.logic.feature.e2ei.usecase.E2EIEnrollmentResult import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountResult @@ -42,6 +42,7 @@ import com.wire.kalium.logic.sync.periodic.UpdateApiVersionsScheduler import com.wire.kalium.logic.sync.slow.RestartSlowSyncProcessForRecoveryUseCase import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.collections.immutable.toImmutableMap import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import javax.inject.Inject @@ -54,10 +55,9 @@ class DebugDataOptionsViewModel @CurrentAccount val currentAccount: UserId, private val globalDataStore: GlobalDataStore, private val updateApiVersions: UpdateApiVersionsScheduler, - private val mlsKeyPackageCountUseCase: MLSKeyPackageCountUseCase, + private val mlsKeyPackageCount: MLSKeyPackageCountUseCase, private val restartSlowSyncProcessForRecovery: RestartSlowSyncProcessForRecoveryUseCase, - private val disableEventProcessingUseCase: DisableEventProcessingUseCase, - private val checkCrlRevocationListUseCase: CheckCrlRevocationListUseCase + private val checkCrlRevocationList: CheckCrlRevocationListUseCase ) : ViewModel() { var state by mutableStateOf( @@ -69,6 +69,16 @@ class DebugDataOptionsViewModel observeMlsMetadata() checkIfCanTriggerManualMigration() setGitHashAndDeviceId() + checkDependenciesVersion() + } + + private fun checkDependenciesVersion() { + viewModelScope.launch { + val dependencies = context.getDependenciesVersion().toImmutableMap() + state = state.copy( + dependencies = dependencies + ) + } } private fun setGitHashAndDeviceId() { @@ -84,7 +94,7 @@ class DebugDataOptionsViewModel fun checkCrlRevocationList() { viewModelScope.launch { - checkCrlRevocationListUseCase( + checkCrlRevocationList( forceUpdate = true ) } @@ -144,7 +154,7 @@ class DebugDataOptionsViewModel fun disableEventProcessing(disabled: Boolean) { viewModelScope.launch { - disableEventProcessingUseCase(disabled) + disableEventProcessing(disabled) state = state.copy(isEventProcessingDisabled = disabled) } } @@ -178,7 +188,7 @@ class DebugDataOptionsViewModel private fun observeMlsMetadata() { viewModelScope.launch { - mlsKeyPackageCountUseCase().let { + mlsKeyPackageCount().let { when (it) { is MLSKeyPackageCountResult.Success -> { state = state.copy(