Skip to content
Merged
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
2 changes: 2 additions & 0 deletions .github/workflows/build-unified.yml
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ jobs:
DATADOG_APP_ID: ${{ secrets.DATADOG_APP_ID }}
DATADOG_CLIENT_TOKEN: ${{ secrets.DATADOG_CLIENT_TOKEN }}
ENABLE_SIGNING: ${{ secrets.ENABLE_SIGNING }}
DOMAIN_REMOVAL_KEYS_FOR_REPAIR: ${{ secrets.DOMAIN_REMOVAL_KEYS_FOR_REPAIR }}

- name: Build AAB
if: matrix.build-type == 'bundle' || matrix.build-type == 'both'
Expand All @@ -233,6 +234,7 @@ jobs:
DATADOG_APP_ID: ${{ secrets.DATADOG_APP_ID }}
DATADOG_CLIENT_TOKEN: ${{ secrets.DATADOG_CLIENT_TOKEN }}
ENABLE_SIGNING: ${{ secrets.ENABLE_SIGNING }}
DOMAIN_REMOVAL_KEYS_FOR_REPAIR: ${{ secrets.DOMAIN_REMOVAL_KEYS_FOR_REPAIR }}

- name: Move version file for consistent artifact structure
if: matrix.generate-version-file == true
Expand Down
24 changes: 23 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,28 @@ android {
val datadogAppIdKey = "DATADOG_APP_ID"
val appId: String? = System.getenv(datadogAppIdKey) ?: project.getLocalProperty(datadogAppIdKey, null)
buildConfigField("String", datadogAppIdKey, appId?.let { "\"$it\"" } ?: "null")

// DOMAIN_REMOVAL_KEYS_FOR_REPAIR json format {"domain": "some hex string key"}
val domainRemovalKeysForRepair = "DOMAIN_REMOVAL_KEYS_FOR_REPAIR"
val domainKeysJson: String? =
System.getenv(domainRemovalKeysForRepair) ?: project.getLocalProperty(domainRemovalKeysForRepair, null)
val domainKeysHashMap = if (domainKeysJson != null) {
try {
val jsonMap = groovy.json.JsonSlurper().parseText(domainKeysJson) as Map<String, String>
val javaMapEntries = jsonMap.entries.joinToString("") { "put(\"${it.key}\", \"${it.value}\");" }
"new java.util.HashMap<String, String>(){{$javaMapEntries}}"
} catch (e: Exception) {
println("Error parsing domain removal keys: ${e.message}")
"new java.util.HashMap<String, String>()"
}
} else {
"new java.util.HashMap<String, String>()"
}
buildConfigField(
"java.util.Map<String, String>",
domainRemovalKeysForRepair,
domainKeysHashMap
)
}
// Most of the configuration is done in the build-logic
// through the Wire Application convention plugin
Expand Down Expand Up @@ -211,7 +233,7 @@ dependencies {
implementation(libs.compose.activity)
implementation(libs.compose.constraintLayout)
implementation(libs.compose.runtime.liveData)

implementation(libs.androidx.paging3)
implementation(libs.androidx.paging3Compose)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.feature.debug.BreakSessionUseCase
import com.wire.kalium.logic.feature.debug.DebugScope
import com.wire.kalium.logic.feature.debug.GetFeatureConfigUseCase
import com.wire.kalium.logic.feature.debug.RepairFaultyRemovalKeysUseCase
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand Down Expand Up @@ -77,4 +78,9 @@ class DebugModule {
@ViewModelScoped
@Provides
fun provideFeatureConfigUseCase(debugScope: DebugScope): GetFeatureConfigUseCase = debugScope.getFeatureConfig

@ViewModelScoped
@Provides
fun provideRepairFaultyRemovalKeysUseCase(debugScope: DebugScope): RepairFaultyRemovalKeysUseCase =
debugScope.repairFaultyRemovalKeysUseCase
}
99 changes: 64 additions & 35 deletions app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ import com.wire.android.R
import com.wire.android.di.hiltViewModelScoped
import com.wire.android.feature.analytics.AnonymousAnalyticsManagerImpl
import com.wire.android.model.Clickable
import com.wire.android.ui.common.rowitem.RowItemTemplate
import com.wire.android.ui.common.WireDialog
import com.wire.android.ui.common.WireDialogButtonProperties
import com.wire.android.ui.common.WireDialogButtonType
import com.wire.android.ui.common.button.WirePrimaryButton
import com.wire.android.ui.common.button.WireSwitch
import com.wire.android.ui.common.dimensions
import com.wire.android.ui.common.rowitem.RowItemTemplate
import com.wire.android.ui.common.rowitem.SectionHeader
import com.wire.android.ui.common.snackbar.LocalSnackbarHostState
import com.wire.android.ui.common.snackbar.collectAndShowSnackbar
import com.wire.android.ui.e2eiEnrollment.GetE2EICertificateUI
import com.wire.android.ui.common.rowitem.SectionHeader
import com.wire.android.ui.home.settings.SettingsItem
import com.wire.android.ui.theme.WireTheme
import com.wire.android.ui.theme.wireColorScheme
Expand Down Expand Up @@ -78,6 +78,7 @@ fun DebugDataOptions(
onResendFCMToken = viewModel::forceSendFCMToken,
onEnableAsyncNotificationsChange = viewModel::enableAsyncNotifications,
onShowFeatureFlags = onShowFeatureFlags,
onRepairFaultyRemovalKeys = viewModel::repairFaultRemovalKeys
)
}

Expand All @@ -98,6 +99,7 @@ fun DebugDataOptionsContent(
checkCrlRevocationList: () -> Unit,
onResendFCMToken: () -> Unit,
onShowFeatureFlags: () -> Unit,
onRepairFaultyRemovalKeys: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier) {
Expand Down Expand Up @@ -209,10 +211,9 @@ fun DebugDataOptionsContent(

if (BuildConfig.PRIVATE_BUILD) {
MLSOptions(
keyPackagesCount = state.keyPackagesCount,
mlsClientId = state.mslClientId,
mlsErrorMessage = state.mlsErrorMessage,
onCopyText = onCopyText
mlsInfoState = state.mlsInfoState,
onCopyText = onCopyText,
onRepairFaultyRemovalKeys = onRepairFaultyRemovalKeys
)
}

Expand Down Expand Up @@ -269,36 +270,58 @@ private fun GetE2EICertificateSwitch(
//region MLS Options
@Composable
private fun MLSOptions(
keyPackagesCount: Int,
mlsClientId: String,
mlsErrorMessage: String,
mlsInfoState: MLSInfoState,
onCopyText: (String) -> Unit,
onRepairFaultyRemovalKeys: () -> Unit,
) {
SectionHeader(stringResource(R.string.label_mls_option_title))
Column {
SettingsItem(
title = "Error Message",
text = mlsErrorMessage,
trailingIcon = null
)
SettingsItem(
title = stringResource(R.string.label_key_packages_count),
text = keyPackagesCount.toString(),
trailingIcon = R.drawable.ic_copy,
onIconPressed = Clickable(
enabled = true,
onClick = { onCopyText(keyPackagesCount.toString()) }
with(mlsInfoState) {
Column {
SettingsItem(
title = "Error Message",
text = mlsErrorMessage,
trailingIcon = null
)
)
SettingsItem(
title = stringResource(R.string.label_mls_client_id),
text = mlsClientId,
trailingIcon = R.drawable.ic_copy,
onIconPressed = Clickable(
enabled = true,
onClick = { onCopyText(mlsClientId) }
SettingsItem(
title = stringResource(R.string.label_key_packages_count),
text = keyPackagesCount.toString(),
trailingIcon = R.drawable.ic_copy,
onIconPressed = Clickable(
enabled = true,
onClick = { onCopyText(keyPackagesCount.toString()) }
)
)
)
SettingsItem(
title = stringResource(R.string.label_mls_client_id),
text = mlsClientId,
trailingIcon = R.drawable.ic_copy,
onIconPressed = Clickable(
enabled = true,
onClick = { onCopyText(mlsClientId) }
)
)
RowItemTemplate(
modifier = Modifier.wrapContentWidth(),
title = {
Text(
style = MaterialTheme.wireTypography.body01,
color = MaterialTheme.wireColorScheme.onBackground,
text = stringResource(R.string.label_mls_repair_faulty_keys),
modifier = Modifier.padding(start = dimensions().spacing8x)
)
},
actions = {
WirePrimaryButton(
minSize = MaterialTheme.wireDimensions.buttonMediumMinSize,
minClickableSize = MaterialTheme.wireDimensions.buttonMinClickableSize,
onClick = onRepairFaultyRemovalKeys,
text = stringResource(R.string.debug_settings_force_repair_faulty_keys),
fillMaxWidth = false,
loading = isLoadingRepair
)
}
)
}
}
}
//endregion
Expand Down Expand Up @@ -457,7 +480,9 @@ private fun DebugToolsOptions(
)
}
)
EnableAsyncNotifications(isAsyncNotificationsEnabled, onEnableAsyncNotificationsChange)
if (BuildConfig.DEBUG) {
EnableAsyncNotifications(isAsyncNotificationsEnabled, onEnableAsyncNotificationsChange)
}
}
}
}
Expand Down Expand Up @@ -530,9 +555,12 @@ fun PreviewOtherDebugOptions() = WireTheme {
buildVariant = "debug",
onCopyText = {},
state = DebugDataOptionsState(
keyPackagesCount = 10,
mslClientId = "clientId",
mlsErrorMessage = "error",
mlsInfoState = MLSInfoState(
mlsClientId = "mlsClientId",
mlsErrorMessage = "-",
keyPackagesCount = 42,
isLoadingRepair = false
),
debugId = "debugId",
commitish = "commitish"
),
Expand All @@ -546,5 +574,6 @@ fun PreviewOtherDebugOptions() = WireTheme {
onResendFCMToken = {},
onEnableAsyncNotificationsChange = {},
onShowFeatureFlags = {},
onRepairFaultyRemovalKeys = {}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ package com.wire.android.ui.debug
data class DebugDataOptionsState(
val isEventProcessingDisabled: Boolean = false,
val isAsyncNotificationsEnabled: Boolean = false,
val keyPackagesCount: Int = 0,
val mslClientId: String = "null",
val mlsErrorMessage: String = "null",
val debugId: String = "null",
val commitish: String = "null",
val certificate: String = "null",
Expand All @@ -32,4 +29,12 @@ data class DebugDataOptionsState(
val isFederationEnabled: Boolean = false,
val currentApiVersion: String = "null",
val defaultProtocol: String = "null",
val mlsInfoState: MLSInfoState = MLSInfoState()
)

data class MLSInfoState(
val mlsClientId: String = "null",
val mlsErrorMessage: String = "-",
val keyPackagesCount: Int = 0,
val isLoadingRepair: Boolean = false,
)
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import androidx.compose.runtime.setValue
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.ScopedArgs
import com.wire.android.di.ViewModelScopedPreview
Expand All @@ -40,8 +42,11 @@
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.feature.analytics.GetCurrentAnalyticsTrackingIdentifierUseCase
import com.wire.kalium.logic.feature.debug.ObserveIsConsumableNotificationsEnabledUseCase
import com.wire.kalium.logic.feature.debug.RepairFaultyRemovalKeysUseCase
import com.wire.kalium.logic.feature.debug.RepairResult
import com.wire.kalium.logic.feature.debug.StartUsingAsyncNotificationsResult
import com.wire.kalium.logic.feature.debug.StartUsingAsyncNotificationsUseCase
import com.wire.kalium.logic.feature.debug.TargetedRepairParam
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
Expand Down Expand Up @@ -76,6 +81,8 @@
fun disableEventProcessing(disabled: Boolean) {}
fun forceSendFCMToken() {}
fun enableAsyncNotifications(enabled: Boolean) {}

fun repairFaultRemovalKeys() {}

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

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt#L85

Added line #L85 was not covered by tests
}

@Suppress("LongParameterList", "TooManyFunctions")
Expand All @@ -95,6 +102,7 @@
private val getDefaultProtocolUseCase: GetDefaultProtocolUseCase,
private val observeAsyncNotificationsEnabled: ObserveIsConsumableNotificationsEnabledUseCase,
private val startUsingAsyncNotifications: StartUsingAsyncNotificationsUseCase,
private val repairFaultyRemovalKeys: RepairFaultyRemovalKeysUseCase,
) : ViewModel(), DebugDataOptionsViewModel {

override var state by mutableStateOf(
Expand Down Expand Up @@ -242,6 +250,36 @@
}
}

override fun repairFaultRemovalKeys() {
viewModelScope.launch {
state = state.copy(mlsInfoState = state.mlsInfoState.copy(isLoadingRepair = true))

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

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt#L254-L255

Added lines #L254 - L255 were not covered by tests
val (domain, faultyKey) = DOMAIN_REMOVAL_KEYS_FOR_REPAIR.entries.firstOrNull()
?: run {
appLogger.w("No faulty removal keys configured for repair")
_infoMessage.emit(UIText.DynamicString("No faulty removal keys configured for repair"))
state = state.copy(mlsInfoState = state.mlsInfoState.copy(isLoadingRepair = false))

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

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt#L257-L260

Added lines #L257 - L260 were not covered by tests
return@launch
}

val result = repairFaultyRemovalKeys(
param = TargetedRepairParam(
domain = domain,
faultyKey = faultyKey

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

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt#L264-L267

Added lines #L264 - L267 were not covered by tests
)
)
when (result) {

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

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt#L270

Added line #L270 was not covered by tests
RepairResult.Error -> appLogger.e("Error occurred during repair of faulty removal keys")
RepairResult.NoConversationsToRepair -> appLogger.i("No conversations to repair")
RepairResult.RepairNotNeeded -> appLogger.i("Repair not needed")
is RepairResult.RepairPerformed -> {
_infoMessage.emit(UIText.DynamicString("Repair finalized"))
appLogger.i("Repair performed: $result")

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

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt#L275-L276

Added lines #L275 - L276 were not covered by tests
}
}
state = state.copy(mlsInfoState = state.mlsInfoState.copy(isLoadingRepair = false))

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

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt#L279

Added line #L279 was not covered by tests
}
}

override fun forceSendFCMToken() {
viewModelScope.launch {
withContext(dispatcherProvider.io()) {
Expand Down Expand Up @@ -276,22 +314,24 @@
when (it) {
is MLSKeyPackageCountResult.Success -> {
state = state.copy(
keyPackagesCount = it.count,
mslClientId = it.clientId.value
mlsInfoState = state.mlsInfoState.copy(
keyPackagesCount = it.count,
mlsClientId = it.clientId.value
)
)
}

is MLSKeyPackageCountResult.Failure.NetworkCallFailure -> {
state = state.copy(mlsErrorMessage = "Network Error!")
state = state.copy(mlsInfoState = state.mlsInfoState.copy(mlsErrorMessage = "Network Error!"))

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

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt#L325

Added line #L325 was not covered by tests
}

is MLSKeyPackageCountResult.Failure.FetchClientIdFailure -> {
state = state.copy(mlsErrorMessage = "ClientId Fetch Error!")
state = state.copy(mlsInfoState = state.mlsInfoState.copy(mlsErrorMessage = "ClientId Fetch Error!"))

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

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt#L329

Added line #L329 was not covered by tests
}

is MLSKeyPackageCountResult.Failure.Generic -> {}
MLSKeyPackageCountResult.Failure.NotEnabled -> {
state = state.copy(mlsErrorMessage = "Not Enabled!")
state = state.copy(mlsInfoState = state.mlsInfoState.copy(mlsErrorMessage = "Not Enabled!"))

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

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/com/wire/android/ui/debug/DebugDataOptionsViewModel.kt#L334

Added line #L334 was not covered by tests
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,7 @@ In group conversations, the group admin can overwrite this setting.</string>
<string name="label_client_device_id">Proteus ID</string>
<string name="label_key_packages_count">Key-packages count</string>
<string name="label_mls_client_id">MLS Client ID</string>
<string name="label_mls_repair_faulty_keys">Repair faulty removal keys</string>
<string name="conversation_empty_list_description">Connect with others or create a new group to start collaborating!</string>
<string name="favorites_empty_list_description">Select your favorite conversations, and you’ll find them here</string>
<string name="group_empty_list_description">You are not part of any group conversation yet.\nStart a new conversation!</string>
Expand Down Expand Up @@ -1794,6 +1795,7 @@ In group conversations, the group admin can overwrite this setting.</string>
<string name="debug_settings_force_api_versioning_update" translatable="false">Force API versioning update</string>
<string name="debug_settings_break_session" translatable="false">⚠️ Break Session</string>
<string name="debug_settings_force_api_versioning_update_button_text" translatable="false">Update</string>
<string name="debug_settings_force_repair_faulty_keys" translatable="false">Repair</string>
<string name="debug_settings_feature_flags" translatable="false">Feature Flags</string>

<!-- Personal to team migration screen-->
Expand Down
Loading