Skip to content

Commit

Permalink
feat: display avs and CC version on all builds (#2894)
Browse files Browse the repository at this point in the history
  • Loading branch information
MohamadJaara authored Apr 16, 2024
1 parent 2d5066d commit 30e14ee
Show file tree
Hide file tree
Showing 5 changed files with 287 additions and 231 deletions.
264 changes: 34 additions & 230 deletions app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -26,19 +25,12 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
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.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
Expand All @@ -53,214 +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.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<String, String?> = 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<CoreFailure, E2EIEnrollmentResult>) {
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

@Composable
fun DebugDataOptions(
Expand All @@ -283,7 +74,8 @@ fun DebugDataOptions(
enrollE2EICertificate = viewModel::enrollE2EICertificate,
handleE2EIEnrollmentResult = viewModel::handleE2EIEnrollmentResult,
dismissCertificateDialog = viewModel::dismissCertificateDialog,
checkCrlRevocationList = viewModel::checkCrlRevocationList
checkCrlRevocationList = viewModel::checkCrlRevocationList,
dependenciesMap = viewModel.state.dependencies
)
}

Expand All @@ -302,7 +94,8 @@ fun DebugDataOptionsContent(
enrollE2EICertificate: () -> Unit,
handleE2EIEnrollmentResult: (Either<CoreFailure, E2EIEnrollmentResult>) -> Unit,
dismissCertificateDialog: () -> Unit,
checkCrlRevocationList: () -> Unit
checkCrlRevocationList: () -> Unit,
dependenciesMap: ImmutableMap<String, String?>
) {
Column {

Expand Down Expand Up @@ -337,6 +130,7 @@ fun DebugDataOptionsContent(
onClick = { onCopyText(state.commitish) }
)
)
DependenciesItem(dependenciesMap)
if (BuildConfig.PRIVATE_BUILD) {

SettingsItem(
Expand Down Expand Up @@ -399,8 +193,7 @@ fun DebugDataOptionsContent(
onDisableEventProcessingChange = onDisableEventProcessingChange,
onRestartSlowSyncForRecovery = onRestartSlowSyncForRecovery,
onForceUpdateApiVersions = onForceUpdateApiVersions,
checkCrlRevocationList = checkCrlRevocationList,
dependenciesMap = state.dependencies
checkCrlRevocationList = checkCrlRevocationList
)
}

Expand Down Expand Up @@ -569,8 +362,7 @@ private fun DebugToolsOptions(
onDisableEventProcessingChange: (Boolean) -> Unit,
onRestartSlowSyncForRecovery: () -> Unit,
onForceUpdateApiVersions: () -> Unit,
checkCrlRevocationList: () -> Unit,
dependenciesMap: ImmutableMap<String, String?>
checkCrlRevocationList: () -> Unit
) {
FolderHeader(stringResource(R.string.label_debug_tools_title))
Column {
Expand Down Expand Up @@ -641,20 +433,31 @@ 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(dependencies: ImmutableMap<String, String?>) {
val title = stringResource(id = R.string.item_dependencies_title)
val text = remember {
prettyPrintMap(dependencies, title)
}
RowItemTemplate(
modifier = Modifier.wrapContentWidth(),
title = {
Text(
style = MaterialTheme.wireTypography.body01,
color = MaterialTheme.wireColorScheme.onBackground,
text = text,
modifier = Modifier.padding(start = dimensions().spacing8x)
)
}
)
}

@Composable
private fun DisableEventProcessingSwitch(
isEnabled: Boolean = false,
Expand Down Expand Up @@ -685,8 +488,8 @@ private fun DisableEventProcessingSwitch(
}

@Stable
private fun prettyPrintMap(map: ImmutableMap<String, String?>): String = StringBuilder().apply {
append("Dependencies:\n")
private fun prettyPrintMap(map: Map<String, String?>, title: String): String = StringBuilder().apply {
append("$title\n")
map.forEach { (key, value) ->
append("$key: $value\n")
}
Expand Down Expand Up @@ -718,6 +521,7 @@ fun PreviewOtherDebugOptions() {
enrollE2EICertificate = {},
handleE2EIEnrollmentResult = {},
dismissCertificateDialog = {},
checkCrlRevocationList = {}
checkCrlRevocationList = {},
dependenciesMap = persistentMapOf()
)
}
Original file line number Diff line number Diff line change
@@ -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.android.ui.debug

import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentMapOf

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<String, String?> = persistentMapOf()
)
Loading

0 comments on commit 30e14ee

Please sign in to comment.