Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class DebugScreenComposeTest {
onShowFeatureFlags = {},
onShowCryptoStats = {},
onFlushLogs = { CompletableDeferred(Unit) },
debugDataOptionsViewModel = object : DebugDataOptionsViewModel {},
exportObfuscatedCopyViewModel = object : ExportObfuscatedCopyViewModel {},
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import com.wire.android.feature.cells.ui.CellsViewModelFactory
import com.wire.android.feature.cells.ui.CellsViewModelGraph
import com.wire.android.model.ImageAssetViewModelFactory
import com.wire.android.model.ImageAssetViewModelGraph
import com.wire.android.ui.debug.DebugInfoViewModelFactory
import com.wire.android.ui.debug.DebugInfoViewModelGraph
import com.wire.android.util.ui.WireSessionImageLoader
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
Expand All @@ -34,10 +36,14 @@ import javax.inject.Provider
class WireActivityViewModelGraphBridge @Inject constructor(
imageLoader: Provider<WireSessionImageLoader>,
private val cellsViewModelFactoryProvider: Provider<CellsViewModelFactory>,
) : ViewModel(), ImageAssetViewModelGraph, CellsViewModelGraph {
private val debugInfoViewModelFactoryProvider: Provider<DebugInfoViewModelFactory>,
) : ViewModel(), ImageAssetViewModelGraph, CellsViewModelGraph, DebugInfoViewModelGraph {
override val imageAssetViewModelFactory: ImageAssetViewModelFactory =
ImageAssetViewModelFactory(imageLoader = imageLoader::get)

override val cellsViewModelFactory: CellsViewModelFactory
get() = cellsViewModelFactoryProvider.get()

override val debugInfoViewModelFactory: DebugInfoViewModelFactory
get() = debugInfoViewModelFactoryProvider.get()
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import com.wire.android.BuildConfig
import com.wire.android.R
import com.wire.android.di.wireViewModelScoped
import com.wire.android.feature.analytics.AnonymousAnalyticsManagerImpl
import com.wire.android.model.Clickable
import com.wire.android.ui.common.WireDialog
Expand Down Expand Up @@ -69,8 +68,7 @@ fun DebugDataOptions(
onCopyText: (String) -> Unit,
onShowFeatureFlags: () -> Unit,
onShowCryptoStats: () -> Unit,
viewModel: DebugDataOptionsViewModel =
wireViewModelScoped<DebugDataOptionsViewModelImpl, DebugDataOptionsViewModel>()
viewModel: DebugDataOptionsViewModel = debugDataOptionsViewModel()
) {
LocalSnackbarHostState.current.collectAndShowSnackbar(snackbarFlow = viewModel.infoMessage)
DebugDataOptionsContent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.wire.android.BuildConfig.DOMAIN_REMOVAL_KEYS_FOR_REPAIR
import com.wire.android.appLogger
import com.wire.android.di.CurrentAccount
import com.wire.android.di.ViewModelScopedPreview
import com.wire.android.util.dispatchers.DispatcherProvider
import com.wire.android.util.getDeviceIdString
Expand Down Expand Up @@ -60,8 +59,6 @@ import com.wire.kalium.logic.feature.user.GetDefaultProtocolUseCase
import com.wire.kalium.logic.feature.user.SelfServerConfigUseCase
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.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
Expand All @@ -70,7 +67,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
import kotlin.time.Duration.Companion.days

@Suppress("TooManyFunctions")
Expand All @@ -97,11 +93,9 @@ interface DebugDataOptionsViewModel {
}

@Suppress("LongParameterList", "TooManyFunctions")
@HiltViewModel
class DebugDataOptionsViewModelImpl
@Inject constructor(
@ApplicationContext private val context: Context,
@CurrentAccount val currentAccount: UserId,
class DebugDataOptionsViewModelImpl(
private val context: Context,
val currentAccount: UserId,
private val updateApiVersions: UpdateApiVersionsScheduler,
private val mlsKeyPackageCount: MLSKeyPackageCountUseCase,
private val restartSlowSyncProcessForRecovery: RestartSlowSyncProcessForRecoveryUseCase,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* Wire
* Copyright (C) 2026 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.lifecycle.SavedStateHandle
import com.wire.android.datastore.GlobalDataStore
import com.wire.android.di.CurrentAccount
import com.wire.android.ui.debug.conversation.DebugConversationViewModel
import com.wire.android.ui.debug.cryptostats.ConversationCryptoStatsViewModel
import com.wire.android.ui.debug.featureflags.DebugFeatureFlagsViewModel
import com.wire.android.ui.home.settings.about.dependencies.DependenciesViewModel
import com.wire.android.ui.home.settings.about.licenses.LicensesViewModel
import com.wire.android.ui.home.whatsnew.WhatsNewViewModel
import com.wire.android.ui.settings.about.AboutThisAppViewModel
import com.wire.android.util.FileManager
import com.wire.android.util.dispatchers.DispatcherProvider
import com.wire.android.util.logging.LogFileWriter
import com.wire.kalium.logic.data.conversation.FetchConversationUseCase
import com.wire.kalium.logic.data.conversation.ResetMLSConversationUseCase
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.feature.analytics.GetCurrentAnalyticsTrackingIdentifierUseCase
import com.wire.kalium.logic.feature.backup.CreateObfuscatedCopyUseCase
import com.wire.kalium.logic.feature.client.ObserveCurrentClientIdUseCase
import com.wire.kalium.logic.feature.conversation.ObserveConversationDetailsUseCase
import com.wire.kalium.logic.feature.debug.ChangeProfilingUseCase
import com.wire.kalium.logic.feature.debug.DebugFeedConversationUseCase
import com.wire.kalium.logic.feature.debug.GetConversationCryptoStatsUseCase
import com.wire.kalium.logic.feature.debug.GetConversationEpochFromCCUseCase
import com.wire.kalium.logic.feature.debug.GetDebugE2EICertificateExpirationUseCase
import com.wire.kalium.logic.feature.debug.GetFeatureConfigUseCase
import com.wire.kalium.logic.feature.debug.ObserveDatabaseLoggerStateUseCase
import com.wire.kalium.logic.feature.debug.ObserveDebugCRLExpirationAfterOneMinuteUseCase
import com.wire.kalium.logic.feature.debug.ObserveIsConsumableNotificationsEnabledUseCase
import com.wire.kalium.logic.feature.debug.RepairFaultyRemovalKeysUseCase
import com.wire.kalium.logic.feature.debug.SetDebugCRLExpirationAfterOneMinuteUseCase
import com.wire.kalium.logic.feature.debug.SetDebugE2EICertificateExpirationUseCase
import com.wire.kalium.logic.feature.debug.StartUsingAsyncNotificationsUseCase
import com.wire.kalium.logic.feature.e2ei.CheckCrlRevocationListUseCase
import com.wire.kalium.logic.feature.keypackage.MLSKeyPackageCountUseCase
import com.wire.kalium.logic.feature.notificationToken.SendFCMTokenUseCase
import com.wire.kalium.logic.feature.user.GetDefaultProtocolUseCase
import com.wire.kalium.logic.feature.user.SelfServerConfigUseCase
import com.wire.kalium.logic.sync.periodic.UpdateApiVersionsScheduler
import com.wire.kalium.logic.sync.slow.RestartSlowSyncProcessForRecoveryUseCase
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

@Suppress("LongParameterList")

Check warning on line 64 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L64

Added line #L64 was not covered by tests
class DebugInfoViewModelFactory @Inject constructor(
@ApplicationContext private val context: Context,
@CurrentAccount private val currentAccount: UserId,
private val logFileWriter: LogFileWriter,
private val currentClientIdUseCase: ObserveCurrentClientIdUseCase,
private val globalDataStore: GlobalDataStore,
private val changeProfilingUseCase: ChangeProfilingUseCase,
private val observeDatabaseLoggerState: ObserveDatabaseLoggerStateUseCase,
private val updateApiVersions: UpdateApiVersionsScheduler,
private val mlsKeyPackageCount: MLSKeyPackageCountUseCase,
private val restartSlowSyncProcessForRecovery: RestartSlowSyncProcessForRecoveryUseCase,
private val checkCrlRevocationList: CheckCrlRevocationListUseCase,
private val getCurrentAnalyticsTrackingIdentifier: GetCurrentAnalyticsTrackingIdentifierUseCase,
private val sendFCMToken: SendFCMTokenUseCase,
private val dispatcherProvider: DispatcherProvider,
private val selfServerConfigUseCase: SelfServerConfigUseCase,
private val getDefaultProtocolUseCase: GetDefaultProtocolUseCase,
private val observeAsyncNotificationsEnabled: ObserveIsConsumableNotificationsEnabledUseCase,
private val startUsingAsyncNotifications: StartUsingAsyncNotificationsUseCase,
private val repairFaultyRemovalKeys: RepairFaultyRemovalKeysUseCase,
private val getDebugE2EICertificateExpiration: GetDebugE2EICertificateExpirationUseCase,
private val setDebugE2EICertificateExpiration: SetDebugE2EICertificateExpirationUseCase,
private val observeDebugCRLExpirationAfterOneMinute: ObserveDebugCRLExpirationAfterOneMinuteUseCase,
private val setDebugCRLExpirationAfterOneMinute: SetDebugCRLExpirationAfterOneMinuteUseCase,
private val createUnencryptedCopy: CreateObfuscatedCopyUseCase,
private val fileManager: FileManager,
private val conversationDetails: ObserveConversationDetailsUseCase,
private val resetMLSConversation: ResetMLSConversationUseCase,
private val fetchConversation: FetchConversationUseCase,
private val feedConversation: DebugFeedConversationUseCase,
private val getConversationEpochFromCC: GetConversationEpochFromCCUseCase,
private val getConversationCryptoStats: GetConversationCryptoStatsUseCase,
private val getFeatureConfig: GetFeatureConfigUseCase,

Check warning on line 97 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L66-L97

Added lines #L66 - L97 were not covered by tests
) {
fun userDebugViewModel() = UserDebugViewModel(
currentAccount = currentAccount,
logFileWriter = logFileWriter,
currentClientIdUseCase = currentClientIdUseCase,
globalDataStore = globalDataStore,
changeProfilingUseCase = changeProfilingUseCase,
observeDatabaseLoggerState = observeDatabaseLoggerState,

Check warning on line 105 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L99-L105

Added lines #L99 - L105 were not covered by tests
)

fun logManagementViewModel() = LogManagementViewModel(
logFileWriter = logFileWriter,
globalDataStore = globalDataStore,

Check warning on line 110 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L108-L110

Added lines #L108 - L110 were not covered by tests
)

fun debugDataOptionsViewModel() = DebugDataOptionsViewModelImpl(
context = context,
currentAccount = currentAccount,
updateApiVersions = updateApiVersions,
mlsKeyPackageCount = mlsKeyPackageCount,
restartSlowSyncProcessForRecovery = restartSlowSyncProcessForRecovery,
checkCrlRevocationList = checkCrlRevocationList,
getCurrentAnalyticsTrackingIdentifier = getCurrentAnalyticsTrackingIdentifier,
sendFCMToken = sendFCMToken,
dispatcherProvider = dispatcherProvider,
selfServerConfigUseCase = selfServerConfigUseCase,
getDefaultProtocolUseCase = getDefaultProtocolUseCase,
observeAsyncNotificationsEnabled = observeAsyncNotificationsEnabled,
startUsingAsyncNotifications = startUsingAsyncNotifications,
repairFaultyRemovalKeys = repairFaultyRemovalKeys,
getDebugE2EICertificateExpiration = getDebugE2EICertificateExpiration,
setDebugE2EICertificateExpiration = setDebugE2EICertificateExpiration,
observeDebugCRLExpirationAfterOneMinute = observeDebugCRLExpirationAfterOneMinute,
setDebugCRLExpirationAfterOneMinute = setDebugCRLExpirationAfterOneMinute,

Check warning on line 131 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L113-L131

Added lines #L113 - L131 were not covered by tests
)

fun exportObfuscatedCopyViewModel() = ExportObfuscatedCopyViewModelImpl(
createUnencryptedCopy = createUnencryptedCopy,
dispatcher = dispatcherProvider,
fileManager = fileManager,

Check warning on line 137 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L134-L137

Added lines #L134 - L137 were not covered by tests
)

fun debugConversationViewModel(savedStateHandle: SavedStateHandle) = DebugConversationViewModel(
conversationDetails = conversationDetails,
resetMLSConversation = resetMLSConversation,
fetchConversation = fetchConversation,
feedConversation = feedConversation,
getConversationEpochFromCC = getConversationEpochFromCC,
savedStateHandle = savedStateHandle,

Check warning on line 146 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L140-L146

Added lines #L140 - L146 were not covered by tests
)

fun conversationCryptoStatsViewModel() = ConversationCryptoStatsViewModel(
getConversationCryptoStats = getConversationCryptoStats,

Check warning on line 150 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L149-L150

Added lines #L149 - L150 were not covered by tests
)

fun debugFeatureFlagsViewModel() = DebugFeatureFlagsViewModel(
getFeatureConfig = getFeatureConfig,

Check warning on line 154 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L153-L154

Added lines #L153 - L154 were not covered by tests
)

fun whatsNewViewModel() = WhatsNewViewModel(context = context)

Check warning on line 157 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L157

Added line #L157 was not covered by tests

fun aboutThisAppViewModel() = AboutThisAppViewModel(context = context)

Check warning on line 159 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L159

Added line #L159 was not covered by tests

fun dependenciesViewModel() = DependenciesViewModel(context = context)

Check warning on line 161 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L161

Added line #L161 was not covered by tests

fun licensesViewModel() = LicensesViewModel(context = context)

Check warning on line 163 in app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugInfoViewModelFactory.kt#L163

Added line #L163 was not covered by tests
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Wire
* Copyright (C) 2026 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 androidx.compose.runtime.Composable
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import com.wire.android.di.metro.MetroViewModelGraph
import com.wire.android.di.metro.metroSavedStateViewModel
import com.wire.android.di.metro.metroViewModel
import com.wire.android.ui.debug.conversation.DebugConversationViewModel
import com.wire.android.ui.debug.cryptostats.ConversationCryptoStatsViewModel
import com.wire.android.ui.debug.featureflags.DebugFeatureFlagsViewModel
import com.wire.android.ui.home.settings.about.dependencies.DependenciesViewModel
import com.wire.android.ui.home.settings.about.licenses.LicensesViewModel
import com.wire.android.ui.home.whatsnew.WhatsNewViewModel
import com.wire.android.ui.settings.about.AboutThisAppViewModel

interface DebugInfoViewModelGraph : MetroViewModelGraph {
val debugInfoViewModelFactory: DebugInfoViewModelFactory
}

@Composable
inline fun <reified VM> debugInfoViewModel(
viewModelStoreOwner: ViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
"No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
},
key: String? = null,
crossinline create: DebugInfoViewModelFactory.() -> VM,
): VM where VM : ViewModel =
metroViewModel<DebugInfoViewModelGraph, VM>(
viewModelStoreOwner = viewModelStoreOwner,
key = key,
) {
debugInfoViewModelFactory.create()
}

@Composable
inline fun <reified VM> debugInfoSavedStateViewModel(
viewModelStoreOwner: ViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
"No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
},
key: String? = null,
crossinline create: DebugInfoViewModelFactory.(SavedStateHandle) -> VM,
): VM where VM : ViewModel =
metroSavedStateViewModel<DebugInfoViewModelGraph, VM>(
viewModelStoreOwner = viewModelStoreOwner,
key = key,
) { savedStateHandle ->
debugInfoViewModelFactory.create(savedStateHandle)
}

@Composable
fun userDebugViewModel(): UserDebugViewModel = debugInfoViewModel { userDebugViewModel() }

@Composable
fun logManagementViewModel(): LogManagementViewModel = debugInfoViewModel { logManagementViewModel() }

@Composable
fun debugDataOptionsViewModel(): DebugDataOptionsViewModel =
debugInfoViewModel<DebugDataOptionsViewModelImpl> { debugDataOptionsViewModel() }

@Composable
fun exportObfuscatedCopyViewModel(): ExportObfuscatedCopyViewModel =
debugInfoViewModel<ExportObfuscatedCopyViewModelImpl> { exportObfuscatedCopyViewModel() }

@Composable
fun debugConversationViewModel(): DebugConversationViewModel =
debugInfoSavedStateViewModel { debugConversationViewModel(it) }

@Composable
fun conversationCryptoStatsViewModel(): ConversationCryptoStatsViewModel =
debugInfoViewModel { conversationCryptoStatsViewModel() }

@Composable
fun debugFeatureFlagsViewModel(): DebugFeatureFlagsViewModel =
debugInfoViewModel { debugFeatureFlagsViewModel() }

@Composable
fun whatsNewViewModel(): WhatsNewViewModel = debugInfoViewModel { whatsNewViewModel() }

@Composable
fun aboutThisAppViewModel(): AboutThisAppViewModel = debugInfoViewModel { aboutThisAppViewModel() }

@Composable
fun dependenciesViewModel(): DependenciesViewModel = debugInfoViewModel { dependenciesViewModel() }

@Composable
fun licensesViewModel(): LicensesViewModel = debugInfoViewModel { licensesViewModel() }
Loading
Loading