From 5d5a1ebcda40c7e7ee5a19a6d2d8d9cc8ca43b23 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 20:56:43 +0000 Subject: [PATCH 01/11] Update activity to v1.10.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 40fc3c35c3..a258036f06 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,7 +20,7 @@ datastore = "1.0.0" constraintlayout = "2.2.0" constraintlayout_compose = "1.1.0" lifecycle = "2.8.7" -activity = "1.9.3" +activity = "1.10.0" media3 = "1.5.1" camera = "1.4.1" From 5cde21bb661b7fb5d84151931ecc4f1e422a3c70 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2025 00:55:00 +0000 Subject: [PATCH 02/11] Update dependency androidx.recyclerview:recyclerview to v1.4.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 40fc3c35c3..f3712089a0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -95,7 +95,7 @@ androidx_camera_lifecycle = { module = "androidx.camera:camera-lifecycle", versi androidx_camera_view = { module = "androidx.camera:camera-view", version.ref = "camera" } androidx_camera_camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camera" } -androidx_recyclerview = "androidx.recyclerview:recyclerview:1.3.2" +androidx_recyclerview = "androidx.recyclerview:recyclerview:1.4.0" androidx_browser = "androidx.browser:browser:1.8.0" androidx_lifecycle_runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" } androidx_lifecycle_process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "lifecycle" } From 9e396a77cb396223ad64f7f48c993455583f05cc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2025 00:55:05 +0000 Subject: [PATCH 03/11] Update dependency androidx.compose:compose-bom to v2025 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 40fc3c35c3..b8aff4f208 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,7 @@ media3 = "1.5.1" camera = "1.4.1" # Compose -compose_bom = "2024.12.01" +compose_bom = "2025.01.00" composecompiler = "1.5.15" # Coroutines From 4d381c30cb6d4ecad8ca95687fa0a73b07ae9760 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:15:07 +0000 Subject: [PATCH 04/11] Update firebaseAppDistribution to v5.1.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 40fc3c35c3..017712f8f2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ android_gradle_plugin = "8.8.0" kotlin = "2.1.0" kotlinpoet = "2.0.0" ksp = "2.1.0-1.0.29" -firebaseAppDistribution = "5.0.0" +firebaseAppDistribution = "5.1.0" # AndroidX core = "1.15.0" From 3d2abeabe2066c258047877d97a5521743e0d92d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 01:02:56 +0000 Subject: [PATCH 05/11] Update dependency com.google.firebase:firebase-bom to v33.8.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 40fc3c35c3..611ad1e15b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -77,7 +77,7 @@ kover_gradle_plugin = { module = "org.jetbrains.kotlinx:kover-gradle-plugin", ve ksp_gradle_plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } gms_google_services = "com.google.gms:google-services:4.4.2" # https://firebase.google.com/docs/android/setup#available-libraries -google_firebase_bom = "com.google.firebase:firebase-bom:33.7.0" +google_firebase_bom = "com.google.firebase:firebase-bom:33.8.0" firebase_appdistribution_gradle = { module = "com.google.firebase:firebase-appdistribution-gradle", version.ref = "firebaseAppDistribution" } autonomousapps_dependencyanalysis_plugin = { module = "com.autonomousapps:dependency-analysis-gradle-plugin", version.ref = "dependencyAnalysis" } ksp_plugin = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" } From 3dd39855c2c1d4153dadf8d1c0e1ab8a81f75d8e Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 16 Jan 2025 18:07:09 +0100 Subject: [PATCH 06/11] change(flow) : remove developer entry point from OnBoarding --- .../android/appnav/NotLoggedInFlowNode.kt | 12 ------- .../onboarding/api/OnBoardingEntryPoint.kt | 1 - .../onboarding/impl/OnBoardingNode.kt | 5 --- .../onboarding/impl/OnBoardingPresenter.kt | 4 +-- .../onboarding/impl/OnBoardingState.kt | 1 - .../impl/OnBoardingStateProvider.kt | 3 -- .../onboarding/impl/OnBoardingView.kt | 35 ++++--------------- .../impl/OnBoardingPresenterTest.kt | 18 ---------- .../onboarding/impl/OnboardingViewTest.kt | 15 -------- 9 files changed, 7 insertions(+), 87 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt index d6db29169d..c8c88ad02d 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt @@ -24,7 +24,6 @@ import io.element.android.anvilannotations.ContributesNode import io.element.android.features.login.api.LoginEntryPoint import io.element.android.features.login.api.LoginFlowType import io.element.android.features.onboarding.api.OnBoardingEntryPoint -import io.element.android.features.preferences.api.ConfigureTracingEntryPoint import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.designsystem.utils.ForceOrientationInMobileDevices @@ -38,7 +37,6 @@ class NotLoggedInFlowNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, private val onBoardingEntryPoint: OnBoardingEntryPoint, - private val configureTracingEntryPoint: ConfigureTracingEntryPoint, private val loginEntryPoint: LoginEntryPoint, private val notLoggedInImageLoaderFactory: NotLoggedInImageLoaderFactory, ) : BaseFlowNode( @@ -68,9 +66,6 @@ class NotLoggedInFlowNode @AssistedInject constructor( @Parcelize data class LoginFlow(val type: LoginFlowType) : NavTarget - - @Parcelize - data object ConfigureTracing : NavTarget } override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { @@ -89,10 +84,6 @@ class NotLoggedInFlowNode @AssistedInject constructor( backstack.push(NavTarget.LoginFlow(type = LoginFlowType.SIGN_IN_QR_CODE)) } - override fun onOpenDeveloperSettings() { - backstack.push(NavTarget.ConfigureTracing) - } - override fun onReportProblem() { plugins().forEach { it.onOpenBugReport() } } @@ -107,9 +98,6 @@ class NotLoggedInFlowNode @AssistedInject constructor( .params(LoginEntryPoint.Params(flowType = navTarget.type)) .build() } - NavTarget.ConfigureTracing -> { - configureTracingEntryPoint.createNode(this, buildContext) - } } } diff --git a/features/onboarding/api/src/main/kotlin/io/element/android/features/onboarding/api/OnBoardingEntryPoint.kt b/features/onboarding/api/src/main/kotlin/io/element/android/features/onboarding/api/OnBoardingEntryPoint.kt index e40196a0b7..378176a2a7 100644 --- a/features/onboarding/api/src/main/kotlin/io/element/android/features/onboarding/api/OnBoardingEntryPoint.kt +++ b/features/onboarding/api/src/main/kotlin/io/element/android/features/onboarding/api/OnBoardingEntryPoint.kt @@ -24,7 +24,6 @@ interface OnBoardingEntryPoint : FeatureEntryPoint { fun onSignUp() fun onSignIn() fun onSignInWithQrCode() - fun onOpenDeveloperSettings() fun onReportProblem() } } diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt index 786ddbad3e..f26a6fdd78 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt @@ -40,10 +40,6 @@ class OnBoardingNode @AssistedInject constructor( plugins().forEach { it.onSignInWithQrCode() } } - private fun onOpenDeveloperSettings() { - plugins().forEach { it.onOpenDeveloperSettings() } - } - private fun onReportProblem() { plugins().forEach { it.onReportProblem() } } @@ -57,7 +53,6 @@ class OnBoardingNode @AssistedInject constructor( onSignIn = ::onSignIn, onCreateAccount = ::onSignUp, onSignInWithQrCode = ::onSignInWithQrCode, - onOpenDeveloperSettings = ::onOpenDeveloperSettings, onReportProblem = ::onReportProblem, ) } diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt index 0db04ffecf..8d33f60393 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt @@ -13,7 +13,6 @@ import androidx.compose.runtime.produceState import io.element.android.appconfig.OnBoardingConfig import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.meta.BuildMeta -import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import javax.inject.Inject @@ -31,8 +30,7 @@ class OnBoardingPresenter @Inject constructor( val canLoginWithQrCode by produceState(initialValue = false) { value = featureFlagService.isFeatureEnabled(FeatureFlags.QrCodeLogin) } - return OnBoardingState( - isDebugBuild = buildMeta.buildType != BuildType.RELEASE, + return OnBoardingState( productionApplicationName = buildMeta.productionApplicationName, canLoginWithQrCode = canLoginWithQrCode, canCreateAccount = OnBoardingConfig.CAN_CREATE_ACCOUNT, diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt index 155ea94da8..6ffb80c2bd 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt @@ -8,7 +8,6 @@ package io.element.android.features.onboarding.impl data class OnBoardingState( - val isDebugBuild: Boolean, val productionApplicationName: String, val canLoginWithQrCode: Boolean, val canCreateAccount: Boolean, diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt index e375368fc3..25dc697782 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt @@ -16,17 +16,14 @@ open class OnBoardingStateProvider : PreviewParameterProvider { anOnBoardingState(canLoginWithQrCode = true), anOnBoardingState(canCreateAccount = true), anOnBoardingState(canLoginWithQrCode = true, canCreateAccount = true), - anOnBoardingState(isDebugBuild = true), ) } fun anOnBoardingState( - isDebugBuild: Boolean = false, productionApplicationName: String = "Element", canLoginWithQrCode: Boolean = false, canCreateAccount: Boolean = false ) = OnBoardingState( - isDebugBuild = isDebugBuild, productionApplicationName = productionApplicationName, canLoginWithQrCode = canLoginWithQrCode, canCreateAccount = canCreateAccount diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt index 6dcefd36c5..2d84a618fc 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt @@ -18,7 +18,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.QrCode import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.BiasAlignment import androidx.compose.ui.Modifier @@ -28,7 +27,6 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.element.android.compound.theme.ElementTheme -import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.libraries.designsystem.atomic.atoms.ElementLogoAtom import io.element.android.libraries.designsystem.atomic.atoms.ElementLogoAtomSize import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule @@ -36,8 +34,6 @@ import io.element.android.libraries.designsystem.atomic.pages.OnBoardingPage import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Button -import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.IconSource import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextButton @@ -56,17 +52,13 @@ fun OnBoardingView( onSignInWithQrCode: () -> Unit, onSignIn: () -> Unit, onCreateAccount: () -> Unit, - onOpenDeveloperSettings: () -> Unit, onReportProblem: () -> Unit, modifier: Modifier = Modifier, ) { OnBoardingPage( modifier = modifier, content = { - OnBoardingContent( - state = state, - onOpenDeveloperSettings = onOpenDeveloperSettings - ) + OnBoardingContent(state = state) }, footer = { OnBoardingButtons( @@ -81,10 +73,7 @@ fun OnBoardingView( } @Composable -private fun OnBoardingContent( - state: OnBoardingState, - onOpenDeveloperSettings: () -> Unit, -) { +private fun OnBoardingContent(state: OnBoardingState) { Box( modifier = Modifier.fillMaxSize(), ) { @@ -127,17 +116,6 @@ private fun OnBoardingContent( ) } } - if (state.isDebugBuild) { - IconButton( - modifier = Modifier.align(Alignment.TopEnd), - onClick = onOpenDeveloperSettings, - ) { - Icon( - imageVector = CompoundIcons.SettingsSolid(), - contentDescription = stringResource(CommonStrings.common_settings) - ) - } - } } } @@ -167,8 +145,8 @@ private fun OnBoardingButtons( text = stringResource(id = signInButtonStringRes), onClick = onSignIn, modifier = Modifier - .fillMaxWidth() - .testTag(TestTags.onBoardingSignIn) + .fillMaxWidth() + .testTag(TestTags.onBoardingSignIn) ) if (state.canCreateAccount) { TextButton( @@ -181,8 +159,8 @@ private fun OnBoardingButtons( // Add a report problem text button. Use a Text since we need a special theme here. Text( modifier = Modifier - .padding(16.dp) - .clickable(onClick = onReportProblem), + .padding(16.dp) + .clickable(onClick = onReportProblem), text = stringResource(id = CommonStrings.common_report_a_problem), style = ElementTheme.typography.fontBodySmRegular, color = ElementTheme.colors.textSecondary, @@ -200,7 +178,6 @@ internal fun OnBoardingViewPreview( onSignInWithQrCode = {}, onSignIn = {}, onCreateAccount = {}, - onOpenDeveloperSettings = {}, onReportProblem = {}, ) } diff --git a/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt b/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt index 253781117e..e98fbff3db 100644 --- a/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt +++ b/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt @@ -12,7 +12,6 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.appconfig.OnBoardingConfig -import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.test.core.aBuildMeta @@ -44,27 +43,10 @@ class OnBoardingPresenterTest { presenter.present() }.test { val initialState = awaitItem() - assertThat(initialState.isDebugBuild).isTrue() assertThat(initialState.canLoginWithQrCode).isFalse() assertThat(initialState.productionApplicationName).isEqualTo("B") assertThat(initialState.canCreateAccount).isEqualTo(OnBoardingConfig.CAN_CREATE_ACCOUNT) - assertThat(awaitItem().canLoginWithQrCode).isTrue() } } - - @Test - fun `present - initial state release`() = runTest { - val presenter = OnBoardingPresenter( - buildMeta = aBuildMeta(buildType = BuildType.RELEASE), - featureFlagService = FakeFeatureFlagService(), - ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - assertThat(initialState.isDebugBuild).isFalse() - cancelAndIgnoreRemainingEvents() - } - } } diff --git a/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnboardingViewTest.kt b/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnboardingViewTest.kt index 1fcdbb8378..25cb075697 100644 --- a/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnboardingViewTest.kt +++ b/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnboardingViewTest.kt @@ -8,10 +8,8 @@ package io.element.android.features.onboarding.impl import androidx.activity.ComponentActivity -import androidx.compose.ui.test.hasContentDescription import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.junit4.createAndroidComposeRule -import androidx.compose.ui.test.performClick import androidx.test.ext.junit.runners.AndroidJUnit4 import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalled @@ -74,17 +72,6 @@ class OnboardingViewTest { } } - @Test - fun `when on debug build - clicking on the settings icon opens the developer settings`() { - ensureCalledOnce { callback -> - rule.setOnboardingView( - state = anOnBoardingState(isDebugBuild = true), - onOpenDeveloperSettings = callback - ) - rule.onNode(hasContentDescription(rule.activity.getString(CommonStrings.common_settings))).performClick() - } - } - @Test fun `clicking on report a problem calls the sign in callback`() { ensureCalledOnce { callback -> @@ -101,7 +88,6 @@ class OnboardingViewTest { onSignInWithQrCode: () -> Unit = EnsureNeverCalled(), onSignIn: () -> Unit = EnsureNeverCalled(), onCreateAccount: () -> Unit = EnsureNeverCalled(), - onOpenDeveloperSettings: () -> Unit = EnsureNeverCalled(), onReportProblem: () -> Unit = EnsureNeverCalled(), ) { setContent { @@ -110,7 +96,6 @@ class OnboardingViewTest { onSignInWithQrCode = onSignInWithQrCode, onSignIn = onSignIn, onCreateAccount = onCreateAccount, - onOpenDeveloperSettings = onOpenDeveloperSettings, onReportProblem = onReportProblem, ) } From 007555eb569bea0b529140a1aba51e848a8fb4e9 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 17 Jan 2025 09:39:22 +0100 Subject: [PATCH 07/11] dependencies(sdk) : update to 0.2.75 --- gradle/libs.versions.toml | 2 +- .../libraries/matrix/impl/RustMatrixClient.kt | 4 +- .../libraries/matrix/impl/media/ImageInfo.kt | 1 + .../matrix/impl/timeline/RustTimeline.kt | 79 +++++++++++-------- .../matrix/impl/tracing/RustTracingService.kt | 3 + .../fixtures/factories/EventTimelineItem.kt | 2 + .../impl/fixtures/factories/RoomInfo.kt | 3 + .../impl/fixtures/factories/RoomMember.kt | 2 + 8 files changed, 62 insertions(+), 34 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 40fc3c35c3..043acc06ed 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -173,7 +173,7 @@ jsoup = "org.jsoup:jsoup:1.18.3" appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0" timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.73" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.75" matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index bd85a7f849..4f470d556e 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -311,8 +311,8 @@ class RustMatrixClient( isEncrypted = createRoomParams.isEncrypted, isDirect = createRoomParams.isDirect, visibility = when (createRoomParams.visibility) { - RoomVisibility.PUBLIC -> RustRoomVisibility.PUBLIC - RoomVisibility.PRIVATE -> RustRoomVisibility.PRIVATE + RoomVisibility.PUBLIC -> RustRoomVisibility.Public + RoomVisibility.PRIVATE -> RustRoomVisibility.Private }, preset = when (createRoomParams.visibility) { RoomVisibility.PRIVATE -> { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/ImageInfo.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/ImageInfo.kt index 0eb2b70d8c..e43ded8be1 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/ImageInfo.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/ImageInfo.kt @@ -28,4 +28,5 @@ fun ImageInfo.map(): RustImageInfo = RustImageInfo( thumbnailInfo = thumbnailInfo?.map(), thumbnailSource = null, blurhash = blurhash, + isAnimated = null ) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt index 7013b4bb78..3e10ce1a5b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt @@ -71,6 +71,7 @@ import org.matrix.rustcomponents.sdk.FormattedBody import org.matrix.rustcomponents.sdk.MessageFormat import org.matrix.rustcomponents.sdk.PollData import org.matrix.rustcomponents.sdk.SendAttachmentJoinHandle +import org.matrix.rustcomponents.sdk.UploadParameters import org.matrix.rustcomponents.sdk.use import timber.log.Timber import uniffi.matrix_sdk_ui.LiveBackPaginationStatus @@ -323,6 +324,7 @@ class RustTimeline( formattedCaption = formattedCaption?.let { FormattedBody(body = it, format = MessageFormat.Html) }, + mentions = null, ) inner.edit( newContent = editedContent, @@ -355,14 +357,17 @@ class RustTimeline( val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue) return sendAttachment(listOfNotNull(file, thumbnailFile)) { inner.sendImage( - url = file.path, - thumbnailUrl = thumbnailFile?.path, + params = UploadParameters( + filename = file.path, + caption = caption, + formattedCaption = formattedCaption?.let { + FormattedBody(body = it, format = MessageFormat.Html) + }, + useSendQueue = useSendQueue, + mentions = null, + ), + thumbnailPath = thumbnailFile?.path, imageInfo = imageInfo.map(), - caption = caption, - formattedCaption = formattedCaption?.let { - FormattedBody(body = it, format = MessageFormat.Html) - }, - useSendQueue = useSendQueue, progressWatcher = progressCallback?.toProgressWatcher() ) } @@ -379,14 +384,17 @@ class RustTimeline( val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue) return sendAttachment(listOfNotNull(file, thumbnailFile)) { inner.sendVideo( - url = file.path, - thumbnailUrl = thumbnailFile?.path, + params = UploadParameters( + filename = file.path, + caption = caption, + formattedCaption = formattedCaption?.let { + FormattedBody(body = it, format = MessageFormat.Html) + }, + useSendQueue = useSendQueue, + mentions = null, + ), + thumbnailPath = thumbnailFile?.path, videoInfo = videoInfo.map(), - caption = caption, - formattedCaption = formattedCaption?.let { - FormattedBody(body = it, format = MessageFormat.Html) - }, - useSendQueue = useSendQueue, progressWatcher = progressCallback?.toProgressWatcher() ) } @@ -402,13 +410,16 @@ class RustTimeline( val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue) return sendAttachment(listOf(file)) { inner.sendAudio( - url = file.path, + params = UploadParameters( + filename = file.path, + caption = caption, + formattedCaption = formattedCaption?.let { + FormattedBody(body = it, format = MessageFormat.Html) + }, + useSendQueue = useSendQueue, + mentions = null, + ), audioInfo = audioInfo.map(), - caption = caption, - formattedCaption = formattedCaption?.let { - FormattedBody(body = it, format = MessageFormat.Html) - }, - useSendQueue = useSendQueue, progressWatcher = progressCallback?.toProgressWatcher() ) } @@ -424,13 +435,16 @@ class RustTimeline( val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue) return sendAttachment(listOf(file)) { inner.sendFile( - url = file.path, + params = UploadParameters( + filename = file.path, + caption = caption, + formattedCaption = formattedCaption?.let { + FormattedBody(body = it, format = MessageFormat.Html) + }, + useSendQueue = useSendQueue, + mentions = null, + ), fileInfo = fileInfo.map(), - caption = caption, - formattedCaption = formattedCaption?.let { - FormattedBody(body = it, format = MessageFormat.Html) - }, - useSendQueue = useSendQueue, progressWatcher = progressCallback?.toProgressWatcher(), ) } @@ -543,13 +557,16 @@ class RustTimeline( val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue) return sendAttachment(listOf(file)) { inner.sendVoiceMessage( - url = file.path, + params = UploadParameters( + filename = file.path, + // Maybe allow a caption in the future? + caption = null, + formattedCaption = null, + useSendQueue = useSendQueue, + mentions = null, + ), audioInfo = audioInfo.map(), waveform = waveform.toMSC3246range(), - // Maybe allow a caption in the future? - caption = null, - formattedCaption = null, - useSendQueue = useSendQueue, progressWatcher = progressCallback?.toProgressWatcher(), ) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt index 159cfed74f..b9fdeda6ce 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt @@ -20,6 +20,7 @@ import javax.inject.Inject @ContributesBinding(AppScope::class) class RustTracingService @Inject constructor(private val buildMeta: BuildMeta) : TracingService { override fun setupTracing(tracingConfiguration: TracingConfiguration) { + /* val filter = tracingConfiguration.filterConfiguration val rustTracingConfiguration = org.matrix.rustcomponents.sdk.TracingConfiguration( filter = tracingConfiguration.filterConfiguration.filter, @@ -28,6 +29,8 @@ class RustTracingService @Inject constructor(private val buildMeta: BuildMeta) : ) org.matrix.rustcomponents.sdk.setupTracing(rustTracingConfiguration) Timber.v("Tracing config filter = $filter: ${filter.filter}") + + */ } override fun createTimberTree(): Timber.Tree { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt index fcedab0273..ff8fcaa78d 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/EventTimelineItem.kt @@ -37,6 +37,7 @@ fun aRustEventTimelineItem( origin: EventItemOrigin? = EventItemOrigin.SYNC, canBeRepliedTo: Boolean = true, shieldsState: ShieldState? = null, + localCreatedAt: ULong? = null, ) = EventTimelineItem( isRemote = isRemote, eventOrTransactionId = eventOrTransactionId, @@ -51,6 +52,7 @@ fun aRustEventTimelineItem( reactions = reactions, readReceipts = readReceipts, origin = origin, + localCreatedAt = localCreatedAt, lazyProvider = FakeRustLazyTimelineItemProvider( debugInfo = debugInfo, shieldsState = shieldsState, diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomInfo.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomInfo.kt index 2bfd1b8804..f5341a1c5e 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomInfo.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomInfo.kt @@ -13,6 +13,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_NAME import org.matrix.rustcomponents.sdk.JoinRule import org.matrix.rustcomponents.sdk.Membership import org.matrix.rustcomponents.sdk.RoomHero +import org.matrix.rustcomponents.sdk.RoomHistoryVisibility import org.matrix.rustcomponents.sdk.RoomInfo import org.matrix.rustcomponents.sdk.RoomMember import org.matrix.rustcomponents.sdk.RoomNotificationMode @@ -49,6 +50,7 @@ fun aRustRoomInfo( pinnedEventIds: List = listOf(), roomCreator: UserId? = null, joinRule: JoinRule? = null, + historyVisibility: RoomHistoryVisibility = RoomHistoryVisibility.Joined, ) = RoomInfo( id = id, displayName = displayName, @@ -81,4 +83,5 @@ fun aRustRoomInfo( pinnedEventIds = pinnedEventIds, creator = roomCreator?.value, joinRule = joinRule, + historyVisibility = historyVisibility ) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt index d6159088ab..a38496222c 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomMember.kt @@ -21,6 +21,7 @@ fun aRustRoomMember( powerLevel: Long = 0L, isIgnored: Boolean = false, role: RoomMemberRole = RoomMemberRole.USER, + membershipChangeReason: String? = null, ) = RoomMember( userId = userId.value, displayName = displayName, @@ -31,4 +32,5 @@ fun aRustRoomMember( normalizedPowerLevel = powerLevel, isIgnored = isIgnored, suggestedRoleForPowerLevel = role, + membershipChangeReason = membershipChangeReason, ) From fd3b99765dfbfa2b4630a112257d400fafca8a09 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 17 Jan 2025 09:51:56 +0100 Subject: [PATCH 08/11] change(design) : introduce PreferenceDropdown component --- .../preferences/PreferenceDropdown.kt | 189 ++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt new file mode 100644 index 0000000000..44bd714f26 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt @@ -0,0 +1,189 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +@file:OptIn(ExperimentalMaterial3Api::class) + +package io.element.android.libraries.designsystem.components.preferences + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults +import androidx.compose.material3.MenuAnchorType +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.tooling.preview.Preview +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.libraries.designsystem.components.list.ListItemContent +import io.element.android.libraries.designsystem.components.preferences.components.preferenceIcon +import io.element.android.libraries.designsystem.preview.ElementThemedPreview +import io.element.android.libraries.designsystem.preview.PreviewGroup +import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem +import io.element.android.libraries.designsystem.theme.components.ListItem +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.toEnabledColor +import io.element.android.libraries.designsystem.toSecondaryEnabledColor +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList + +@Composable +fun PreferenceDropdown( + title: String, + selectedOption: T?, + options: ImmutableList, + onSelectOption: (T) -> Unit, + modifier: Modifier = Modifier, + supportingText: String? = null, + enabled: Boolean = true, + icon: ImageVector? = null, + @DrawableRes iconResourceId: Int? = null, + showIconAreaIfNoIcon: Boolean = false, +) { + var isDropdownExpanded by remember { mutableStateOf(false) } + ListItem( + modifier = modifier, + leadingContent = preferenceIcon( + icon = icon, + iconResourceId = iconResourceId, + enabled = enabled, + showIconAreaIfNoIcon = showIconAreaIfNoIcon, + ), + headlineContent = { + Text( + style = ElementTheme.typography.fontBodyLgRegular, + modifier = Modifier.fillMaxWidth(), + text = title, + color = enabled.toEnabledColor(), + ) + }, + supportingContent = supportingText?.let { + { + Text( + style = ElementTheme.typography.fontBodyMdRegular, + text = it, + color = enabled.toSecondaryEnabledColor(), + ) + } + }, + trailingContent = ListItemContent.Custom( + content = { + DropdownTrailingContent( + selectedOption = selectedOption, + options = options, + onSelectOption = onSelectOption, + expanded = isDropdownExpanded, + onExpandedChange = { isDropdownExpanded = it }, + ) + } + ), + onClick = { isDropdownExpanded = true }.takeIf { !isDropdownExpanded }, + ) +} + +/** + * A dropdown option that can be used in a [PreferenceDropdown]. + */ +interface DropdownOption { + /** + * The text to display for this option. + */ + val text: String +} + +@Composable +private fun DropdownTrailingContent( + selectedOption: T?, + options: ImmutableList, + expanded: Boolean, + onExpandedChange: (Boolean) -> Unit, + onSelectOption: (T) -> Unit, + modifier: Modifier = Modifier, +) { + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = onExpandedChange, + modifier = modifier, + ) { + Row( + modifier = Modifier.menuAnchor(MenuAnchorType.PrimaryNotEditable), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = selectedOption?.text.orEmpty(), + maxLines = 1, + style = ElementTheme.typography.fontBodyMdRegular, + color = ElementTheme.colors.textSecondary, + ) + ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) + } + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { onExpandedChange(false) }, + matchTextFieldWidth = false, + ) { + options.forEach { option -> + DropdownMenuItem( + text = { + Text( + text = option.text, + style = ElementTheme.typography.fontBodyMdRegular + ) + }, + onClick = { + onSelectOption(option) + onExpandedChange(false) + }, + ) + } + } + } +} + +@Preview(group = PreviewGroup.Preferences) +@Composable +internal fun PreferenceDropdownPreview() = ElementThemedPreview { + val options = listOf( + object : DropdownOption { + override val text = "Option 1" + }, + object : DropdownOption { + override val text = "Option 2" + }, + object : DropdownOption { + override val text = "Option 3" + }, + ).toImmutableList() + + Column { + PreferenceDropdown( + title = "Dropdown", + supportingText = "Options for dropdown", + icon = CompoundIcons.Threads(), + selectedOption = null, + options = options, + onSelectOption = {}, + ) + PreferenceDropdown( + title = "Dropdown", + supportingText = "Options for dropdown", + icon = CompoundIcons.Threads(), + selectedOption = options.first(), + options = options, + onSelectOption = {}, + ) + } +} From 7d27e6581be745fd9ebaf1f5e276c279e25b72ae Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 17 Jan 2025 09:52:32 +0100 Subject: [PATCH 09/11] change(tracing) : change how tracing is configured (ui and logic) --- .../x/initializer/TracingInitializer.kt | 44 ++-- .../api/ConfigureTracingEntryPoint.kt | 12 - .../impl/DefaultConfigureTracingEntryPoint.kt | 24 -- .../preferences/impl/PreferencesFlowNode.kt | 14 +- .../impl/developer/DeveloperSettingsEvents.kt | 2 + .../impl/developer/DeveloperSettingsNode.kt | 10 - .../developer/DeveloperSettingsPresenter.kt | 12 + .../impl/developer/DeveloperSettingsState.kt | 2 + .../DeveloperSettingsStateProvider.kt | 2 + .../impl/developer/DeveloperSettingsView.kt | 16 +- .../tracing/ConfigureTracingEvents.kt | 16 -- .../developer/tracing/ConfigureTracingNode.kt | 35 --- .../tracing/ConfigureTracingPresenter.kt | 44 ---- .../tracing/ConfigureTracingState.kt | 17 -- .../tracing/ConfigureTracingStateProvider.kt | 29 --- .../developer/tracing/ConfigureTracingView.kt | 234 ------------------ .../impl/developer/tracing/LogLevelItem.kt | 28 +++ .../impl/developer/tracing/LogLevelMapper.kt | 30 +++ .../tracing/TargetLogLevelMapBuilder.kt | 31 --- .../tracing/TracingConfigurationStore.kt | 50 ---- .../DeveloperSettingsPresenterTest.kt | 19 ++ .../developer/DeveloperSettingsViewTest.kt | 24 +- .../tracing/ConfigureTracingPresenterTest.kt | 101 -------- .../InMemoryTracingConfigurationStore.kt | 35 --- .../rageshake/api/reporter/BugReporter.kt | 4 +- .../impl/reporter/DefaultBugReporter.kt | 8 +- .../impl/bugreport/FakeBugReporter.kt | 2 +- .../libraries/matrix/api/tracing/LogLevel.kt | 19 ++ .../api/tracing/TracingConfiguration.kt | 3 +- .../api/tracing/TracingFilterConfiguration.kt | 102 -------- .../matrix/api/tracing/TracingService.kt | 2 +- .../matrix/impl/di/TracingMatrixModule.kt | 30 --- .../matrix/impl/tracing/RustTracingService.kt | 24 +- .../matrix/impl/tracing/RustTracingTree.kt | 8 +- .../matrix/impl/di/TracingMatrixModuleTest.kt | 34 --- .../api/store/AppPreferencesStore.kt | 4 + .../impl/store/DefaultAppPreferencesStore.kt | 22 ++ .../test/InMemoryAppPreferencesStore.kt | 13 +- 38 files changed, 220 insertions(+), 886 deletions(-) delete mode 100644 features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/ConfigureTracingEntryPoint.kt delete mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultConfigureTracingEntryPoint.kt delete mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingEvents.kt delete mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingNode.kt delete mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt delete mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt delete mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt delete mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingView.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelItem.kt create mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelMapper.kt delete mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt delete mode 100644 features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TracingConfigurationStore.kt delete mode 100644 features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt delete mode 100644 features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/InMemoryTracingConfigurationStore.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/LogLevel.kt delete mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt delete mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/TracingMatrixModule.kt delete mode 100644 libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/di/TracingMatrixModuleTest.kt diff --git a/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt b/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt index 642895790e..5c53968ece 100644 --- a/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt +++ b/app/src/main/kotlin/io/element/android/x/initializer/TracingInitializer.kt @@ -9,50 +9,34 @@ package io.element.android.x.initializer import android.content.Context import android.system.Os -import androidx.preference.PreferenceManager import androidx.startup.Initializer -import io.element.android.features.preferences.impl.developer.tracing.SharedPreferencesTracingConfigurationStore -import io.element.android.features.preferences.impl.developer.tracing.TargetLogLevelMapBuilder import io.element.android.features.rageshake.api.reporter.BugReporter import io.element.android.libraries.architecture.bindings -import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.matrix.api.tracing.TracingConfiguration -import io.element.android.libraries.matrix.api.tracing.TracingFilterConfigurations import io.element.android.libraries.matrix.api.tracing.WriteToFilesConfiguration import io.element.android.x.BuildConfig import io.element.android.x.di.AppBindings +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking import timber.log.Timber +private const val ELEMENT_X_TARGET = "elementx" + class TracingInitializer : Initializer { override fun create(context: Context) { val appBindings = context.bindings() val tracingService = appBindings.tracingService() val bugReporter = appBindings.bugReporter() - Timber.plant(tracingService.createTimberTree()) - val tracingConfiguration = if (BuildConfig.BUILD_TYPE == BuildType.RELEASE.name) { - TracingConfiguration( - filterConfiguration = TracingFilterConfigurations.release, - writesToLogcat = false, - writesToFilesConfiguration = defaultWriteToDiskConfiguration(bugReporter), - ) - } else { - val prefs = PreferenceManager.getDefaultSharedPreferences(context) - val store = SharedPreferencesTracingConfigurationStore(prefs) - val builder = TargetLogLevelMapBuilder( - tracingConfigurationStore = store, - defaultConfig = if (BuildConfig.BUILD_TYPE == BuildType.NIGHTLY.name) { - TracingFilterConfigurations.nightly - } else { - TracingFilterConfigurations.debug - } - ) - TracingConfiguration( - filterConfiguration = TracingFilterConfigurations.custom(builder.getCurrentMap()), - writesToLogcat = BuildConfig.DEBUG, - writesToFilesConfiguration = defaultWriteToDiskConfiguration(bugReporter), - ) - } - bugReporter.setCurrentTracingFilter(tracingConfiguration.filterConfiguration.filter) + Timber.plant(tracingService.createTimberTree(ELEMENT_X_TARGET)) + val preferencesStore = appBindings.preferencesStore() + val logLevel = runBlocking { preferencesStore.getTracingLogLevelFlow().first() } + val tracingConfiguration = TracingConfiguration( + writesToLogcat = BuildConfig.DEBUG, + writesToFilesConfiguration = defaultWriteToDiskConfiguration(bugReporter), + logLevel = logLevel, + extraTargets = listOf(ELEMENT_X_TARGET), + ) + bugReporter.setCurrentTracingLogLevel(logLevel.name) tracingService.setupTracing(tracingConfiguration) // Also set env variable for rust back trace Os.setenv("RUST_BACKTRACE", "1", true) diff --git a/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/ConfigureTracingEntryPoint.kt b/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/ConfigureTracingEntryPoint.kt deleted file mode 100644 index 86c1aa93c1..0000000000 --- a/features/preferences/api/src/main/kotlin/io/element/android/features/preferences/api/ConfigureTracingEntryPoint.kt +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.api - -import io.element.android.libraries.architecture.SimpleFeatureEntryPoint - -interface ConfigureTracingEntryPoint : SimpleFeatureEntryPoint diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultConfigureTracingEntryPoint.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultConfigureTracingEntryPoint.kt deleted file mode 100644 index fc2176cd6e..0000000000 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/DefaultConfigureTracingEntryPoint.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl - -import com.bumble.appyx.core.modality.BuildContext -import com.bumble.appyx.core.node.Node -import com.squareup.anvil.annotations.ContributesBinding -import io.element.android.features.preferences.api.ConfigureTracingEntryPoint -import io.element.android.features.preferences.impl.developer.tracing.ConfigureTracingNode -import io.element.android.libraries.architecture.createNode -import io.element.android.libraries.di.AppScope -import javax.inject.Inject - -@ContributesBinding(AppScope::class) -class DefaultConfigureTracingEntryPoint @Inject constructor() : ConfigureTracingEntryPoint { - override fun createNode(parentNode: Node, buildContext: BuildContext): Node { - return parentNode.createNode(buildContext) - } -} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt index 77291d9319..27987e7960 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt @@ -30,7 +30,6 @@ import io.element.android.features.preferences.impl.advanced.AdvancedSettingsNod import io.element.android.features.preferences.impl.analytics.AnalyticsSettingsNode import io.element.android.features.preferences.impl.blockedusers.BlockedUsersNode import io.element.android.features.preferences.impl.developer.DeveloperSettingsNode -import io.element.android.features.preferences.impl.developer.tracing.ConfigureTracingNode import io.element.android.features.preferences.impl.notifications.NotificationSettingsNode import io.element.android.features.preferences.impl.notifications.edit.EditDefaultNotificationSettingNode import io.element.android.features.preferences.impl.root.PreferencesRootNode @@ -72,9 +71,6 @@ class PreferencesFlowNode @AssistedInject constructor( @Parcelize data object AdvancedSettings : NavTarget - @Parcelize - data object ConfigureTracing : NavTarget - @Parcelize data object AnalyticsSettings : NavTarget @@ -164,15 +160,7 @@ class PreferencesFlowNode @AssistedInject constructor( createNode(buildContext, plugins = listOf(callback)) } NavTarget.DeveloperSettings -> { - val callback = object : DeveloperSettingsNode.Callback { - override fun openConfigureTracing() { - backstack.push(NavTarget.ConfigureTracing) - } - } - createNode(buildContext, listOf(callback)) - } - NavTarget.ConfigureTracing -> { - createNode(buildContext) + createNode(buildContext) } NavTarget.About -> { val callback = object : AboutNode.Callback { diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsEvents.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsEvents.kt index 3bcc1ac067..11a11ada72 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsEvents.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsEvents.kt @@ -7,6 +7,7 @@ package io.element.android.features.preferences.impl.developer +import io.element.android.features.preferences.impl.developer.tracing.LogLevelItem import io.element.android.libraries.featureflag.ui.model.FeatureUiModel sealed interface DeveloperSettingsEvents { @@ -14,5 +15,6 @@ sealed interface DeveloperSettingsEvents { data class SetCustomElementCallBaseUrl(val baseUrl: String?) : DeveloperSettingsEvents data class SetSimplifiedSlidingSyncEnabled(val isEnabled: Boolean) : DeveloperSettingsEvents data class SetHideImagesAndVideos(val value: Boolean) : DeveloperSettingsEvents + data class SetTracingLogLevel(val logLevel: LogLevelItem) : DeveloperSettingsEvents data object ClearCache : DeveloperSettingsEvents } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt index 588c411755..91f8afcb8e 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt @@ -15,7 +15,6 @@ import com.airbnb.android.showkase.models.Showkase import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin -import com.bumble.appyx.core.plugin.plugins import dagger.assisted.Assisted import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode @@ -28,14 +27,6 @@ class DeveloperSettingsNode @AssistedInject constructor( @Assisted plugins: List, private val presenter: DeveloperSettingsPresenter, ) : Node(buildContext, plugins = plugins) { - interface Callback : Plugin { - fun openConfigureTracing() - } - - private fun onOpenConfigureTracing() { - plugins().forEach { it.openConfigureTracing() } - } - @Composable override fun View(modifier: Modifier) { val activity = LocalContext.current as Activity @@ -49,7 +40,6 @@ class DeveloperSettingsNode @AssistedInject constructor( state = state, modifier = modifier, onOpenShowkase = ::openShowkase, - onOpenConfigureTracing = ::onOpenConfigureTracing, onBackClick = ::navigateUp ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt index 05635033de..66c8d8d7b3 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt @@ -20,6 +20,8 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.snapshots.SnapshotStateMap import io.element.android.appconfig.ElementCallConfig import io.element.android.features.logout.api.LogoutUseCase +import io.element.android.features.preferences.impl.developer.tracing.toLogLevel +import io.element.android.features.preferences.impl.developer.tracing.toLogLevelItem import io.element.android.features.preferences.impl.tasks.ClearCacheUseCase import io.element.android.features.preferences.impl.tasks.ComputeCacheSizeUseCase import io.element.android.features.rageshake.api.preferences.RageshakePreferencesState @@ -37,6 +39,7 @@ import io.element.android.libraries.featureflag.ui.model.FeatureUiModel import io.element.android.libraries.preferences.api.store.AppPreferencesStore import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import java.net.URL import javax.inject.Inject @@ -76,6 +79,11 @@ class DeveloperSettingsPresenter @Inject constructor( .doesHideImagesAndVideosFlow() .collectAsState(initial = false) + val tracingLogLevel by appPreferencesStore + .getTracingLogLevelFlow() + .map { AsyncData.Success(it.toLogLevelItem()) } + .collectAsState(initial = AsyncData.Uninitialized) + LaunchedEffect(Unit) { FeatureFlags.entries .filter { it.isFinished.not() } @@ -123,6 +131,9 @@ class DeveloperSettingsPresenter @Inject constructor( is DeveloperSettingsEvents.SetHideImagesAndVideos -> coroutineScope.launch { appPreferencesStore.setHideImagesAndVideos(event.value) } + is DeveloperSettingsEvents.SetTracingLogLevel -> coroutineScope.launch { + appPreferencesStore.setTracingLogLevel(event.logLevel.toLogLevel()) + } } } @@ -138,6 +149,7 @@ class DeveloperSettingsPresenter @Inject constructor( ), isSimpleSlidingSyncEnabled = isSimplifiedSlidingSyncEnabled, hideImagesAndVideos = hideImagesAndVideos, + tracingLogLevel = tracingLogLevel, eventSink = ::handleEvents ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt index b60121e69f..c9641ab686 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt @@ -7,6 +7,7 @@ package io.element.android.features.preferences.impl.developer +import io.element.android.features.preferences.impl.developer.tracing.LogLevelItem import io.element.android.features.rageshake.api.preferences.RageshakePreferencesState import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData @@ -21,6 +22,7 @@ data class DeveloperSettingsState( val customElementCallBaseUrlState: CustomElementCallBaseUrlState, val isSimpleSlidingSyncEnabled: Boolean, val hideImagesAndVideos: Boolean, + val tracingLogLevel: AsyncData, val eventSink: (DeveloperSettingsEvents) -> Unit ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt index a6974a0af4..869c010529 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt @@ -8,6 +8,7 @@ package io.element.android.features.preferences.impl.developer import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.features.preferences.impl.developer.tracing.LogLevelItem import io.element.android.features.rageshake.api.preferences.aRageshakePreferencesState import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData @@ -42,6 +43,7 @@ fun aDeveloperSettingsState( customElementCallBaseUrlState = customElementCallBaseUrlState, isSimpleSlidingSyncEnabled = isSimplifiedSlidingSyncEnabled, hideImagesAndVideos = hideImagesAndVideos, + tracingLogLevel = AsyncData.Success(LogLevelItem.INFO), eventSink = eventSink, ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt index 248756dffc..7b0b39db90 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsView.kt @@ -14,8 +14,10 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.features.preferences.impl.R +import io.element.android.features.preferences.impl.developer.tracing.LogLevelItem import io.element.android.features.rageshake.api.preferences.RageshakePreferencesView import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory +import io.element.android.libraries.designsystem.components.preferences.PreferenceDropdown import io.element.android.libraries.designsystem.components.preferences.PreferencePage import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch import io.element.android.libraries.designsystem.components.preferences.PreferenceText @@ -25,12 +27,12 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.featureflag.ui.FeatureListView import io.element.android.libraries.featureflag.ui.model.FeatureUiModel import io.element.android.libraries.ui.strings.CommonStrings +import kotlinx.collections.immutable.toPersistentList @Composable fun DeveloperSettingsView( state: DeveloperSettingsState, onOpenShowkase: () -> Unit, - onOpenConfigureTracing: () -> Unit, onBackClick: () -> Unit, modifier: Modifier = Modifier, ) { @@ -49,9 +51,14 @@ fun DeveloperSettingsView( } ElementCallCategory(state = state) PreferenceCategory(title = "Rust SDK") { - PreferenceText( - title = "Configure tracing", - onClick = onOpenConfigureTracing, + PreferenceDropdown( + title = "Tracing log level", + supportingText = "Requires app reboot", + selectedOption = state.tracingLogLevel.dataOrNull(), + options = LogLevelItem.entries.toPersistentList(), + onSelectOption = { logLevel -> + state.eventSink(DeveloperSettingsEvents.SetTracingLogLevel(logLevel)) + } ) PreferenceSwitch( title = "Enable Simplified Sliding Sync", @@ -157,7 +164,6 @@ internal fun DeveloperSettingsViewPreview(@PreviewParameter(DeveloperSettingsSta DeveloperSettingsView( state = state, onOpenShowkase = {}, - onOpenConfigureTracing = {}, onBackClick = {} ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingEvents.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingEvents.kt deleted file mode 100644 index 04a4dbabc2..0000000000 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingEvents.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl.developer.tracing - -import io.element.android.libraries.matrix.api.tracing.LogLevel -import io.element.android.libraries.matrix.api.tracing.Target - -sealed interface ConfigureTracingEvents { - data class UpdateFilter(val target: Target, val logLevel: LogLevel) : ConfigureTracingEvents - data object ResetFilters : ConfigureTracingEvents -} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingNode.kt deleted file mode 100644 index 99fdde68e9..0000000000 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingNode.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl.developer.tracing - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import com.bumble.appyx.core.modality.BuildContext -import com.bumble.appyx.core.node.Node -import com.bumble.appyx.core.plugin.Plugin -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject -import io.element.android.anvilannotations.ContributesNode -import io.element.android.libraries.di.AppScope - -@ContributesNode(AppScope::class) -class ConfigureTracingNode @AssistedInject constructor( - @Assisted buildContext: BuildContext, - @Assisted plugins: List, - private val presenter: ConfigureTracingPresenter, -) : Node(buildContext, plugins = plugins) { - @Composable - override fun View(modifier: Modifier) { - val state = presenter.present() - ConfigureTracingView( - state = state, - onBackClick = ::navigateUp, - modifier = modifier - ) - } -} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt deleted file mode 100644 index 89087f2f12..0000000000 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenter.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl.developer.tracing - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import io.element.android.libraries.architecture.Presenter -import kotlinx.collections.immutable.toImmutableMap -import javax.inject.Inject - -class ConfigureTracingPresenter @Inject constructor( - private val tracingConfigurationStore: TracingConfigurationStore, - private val targetLogLevelMapBuilder: TargetLogLevelMapBuilder, -) : Presenter { - @Composable - override fun present(): ConfigureTracingState { - val modifiedMap = remember { mutableStateOf(targetLogLevelMapBuilder.getCurrentMap()) } - - fun handleEvents(event: ConfigureTracingEvents) { - when (event) { - is ConfigureTracingEvents.UpdateFilter -> { - modifiedMap.value = modifiedMap.value.toMutableMap() - .apply { this[event.target] = event.logLevel } - tracingConfigurationStore.storeLogLevel(event.target, event.logLevel) - } - ConfigureTracingEvents.ResetFilters -> { - modifiedMap.value = targetLogLevelMapBuilder.getDefaultMap() - tracingConfigurationStore.reset() - } - } - } - - return ConfigureTracingState( - targetsToLogLevel = modifiedMap.value.toImmutableMap(), - eventSink = ::handleEvents - ) - } -} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt deleted file mode 100644 index 2e945a7244..0000000000 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingState.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl.developer.tracing - -import io.element.android.libraries.matrix.api.tracing.LogLevel -import io.element.android.libraries.matrix.api.tracing.Target -import kotlinx.collections.immutable.ImmutableMap - -data class ConfigureTracingState( - val targetsToLogLevel: ImmutableMap, - val eventSink: (ConfigureTracingEvents) -> Unit -) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt deleted file mode 100644 index 2e9601f985..0000000000 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingStateProvider.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl.developer.tracing - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.matrix.api.tracing.LogLevel -import io.element.android.libraries.matrix.api.tracing.Target -import kotlinx.collections.immutable.persistentMapOf - -open class ConfigureTracingStateProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf( - aConfigureTracingState(), - ) -} - -fun aConfigureTracingState() = ConfigureTracingState( - targetsToLogLevel = persistentMapOf( - Target.ELEMENT to LogLevel.INFO, - Target.MATRIX_SDK_FFI to LogLevel.WARN, - Target.MATRIX_SDK_BASE_SLIDING_SYNC to LogLevel.ERROR, - ), - eventSink = {} -) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingView.kt deleted file mode 100644 index 471113cff2..0000000000 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingView.kt +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl.developer.tracing - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.consumeWindowInsets -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.statusBars -import androidx.compose.foundation.layout.systemBarsPadding -import androidx.compose.foundation.layout.widthIn -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.rotate -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.unit.dp -import io.element.android.compound.theme.ElementTheme -import io.element.android.compound.tokens.generated.CompoundIcons -import io.element.android.libraries.designsystem.components.button.BackButton -import io.element.android.libraries.designsystem.components.list.ListItemContent -import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.aliasScreenTitle -import io.element.android.libraries.designsystem.theme.components.DropdownMenu -import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem -import io.element.android.libraries.designsystem.theme.components.HorizontalDivider -import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.IconButton -import io.element.android.libraries.designsystem.theme.components.ListItem -import io.element.android.libraries.designsystem.theme.components.Scaffold -import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.designsystem.theme.components.TopAppBar -import io.element.android.libraries.matrix.api.tracing.LogLevel -import io.element.android.libraries.matrix.api.tracing.Target -import kotlinx.collections.immutable.ImmutableMap - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ConfigureTracingView( - state: ConfigureTracingState, - onBackClick: () -> Unit, - modifier: Modifier = Modifier, -) { - var showMenu by remember { mutableStateOf(false) } - Scaffold( - modifier = modifier - .fillMaxSize() - .systemBarsPadding() - .imePadding(), - contentWindowInsets = WindowInsets.statusBars, - topBar = { - TopAppBar( - navigationIcon = { - BackButton(onClick = onBackClick) - }, - title = { - Text( - text = "Configure tracing", - style = ElementTheme.typography.aliasScreenTitle, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - }, - actions = { - IconButton( - onClick = { showMenu = !showMenu } - ) { - Icon( - imageVector = CompoundIcons.OverflowVertical(), - tint = ElementTheme.materialColors.secondary, - contentDescription = null, - ) - } - DropdownMenu( - expanded = showMenu, - onDismissRequest = { showMenu = false } - ) { - DropdownMenuItem( - onClick = { - showMenu = false - state.eventSink.invoke(ConfigureTracingEvents.ResetFilters) - }, - text = { Text("Reset to default") }, - leadingIcon = { - Icon( - imageVector = CompoundIcons.Delete(), - tint = ElementTheme.materialColors.secondary, - contentDescription = null, - ) - } - ) - } - } - ) - }, - content = { - Column( - modifier = Modifier - .padding(it) - .consumeWindowInsets(it) - .verticalScroll(state = rememberScrollState()) - ) { - ListItem( - headlineContent = { - Text( - modifier = Modifier.clickable { Runtime.getRuntime().exit(0) }, - text = "Tap here to kill the app and apply the changes. You'll have to re-open the app manually.", - style = ElementTheme.typography.fontHeadingSmMedium, - ) - }, - ) - HorizontalDivider() - CrateListContent(state) - } - } - ) -} - -@Composable -private fun CrateListContent( - state: ConfigureTracingState, -) { - fun onLogLevelChange(target: Target, logLevel: LogLevel) { - state.eventSink(ConfigureTracingEvents.UpdateFilter(target, logLevel)) - } - - TargetAndLogLevelListView( - data = state.targetsToLogLevel, - onLogLevelChange = ::onLogLevelChange, - ) -} - -@Composable -private fun TargetAndLogLevelListView( - data: ImmutableMap, - onLogLevelChange: (Target, LogLevel) -> Unit, -) { - Column { - data.forEach { item -> - fun onLogLevelChange(logLevel: LogLevel) { - onLogLevelChange(item.key, logLevel) - } - - TargetAndLogLevelView( - target = item.key, - logLevel = item.value, - onLogLevelChange = ::onLogLevelChange - ) - } - } -} - -@Composable -private fun TargetAndLogLevelView( - target: Target, - logLevel: LogLevel, - onLogLevelChange: (LogLevel) -> Unit, -) { - ListItem( - headlineContent = { Text(text = target.filter.takeIf { it.isNotEmpty() } ?: "(common)") }, - trailingContent = ListItemContent.Custom { - LogLevelDropdownMenu( - logLevel = logLevel, - onLogLevelChange = onLogLevelChange, - ) - }, - ) -} - -@Composable -private fun LogLevelDropdownMenu( - logLevel: LogLevel, - onLogLevelChange: (LogLevel) -> Unit, -) { - var expanded by remember { mutableStateOf(false) } - Box { - DropdownMenuItem( - modifier = Modifier.widthIn(max = 120.dp), - text = { Text(text = logLevel.filter) }, - onClick = { expanded = !expanded }, - trailingIcon = { - Icon( - modifier = Modifier.rotate(if (expanded) 180f else 0f), - imageVector = CompoundIcons.ChevronDown(), - contentDescription = null, - ) - }, - ) - DropdownMenu( - expanded = expanded, - onDismissRequest = { expanded = false }, - ) { - LogLevel.values().forEach { logLevel -> - DropdownMenuItem( - text = { - Text(text = logLevel.filter) - }, - onClick = { - expanded = false - onLogLevelChange(logLevel) - } - ) - } - } - } -} - -@PreviewsDayNight -@Composable -internal fun ConfigureTracingViewPreview( - @PreviewParameter(ConfigureTracingStateProvider::class) state: ConfigureTracingState -) = ElementPreview { - ConfigureTracingView( - state = state, - onBackClick = {}, - ) -} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelItem.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelItem.kt new file mode 100644 index 0000000000..9707fc30e7 --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelItem.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.preferences.impl.developer.tracing + +import io.element.android.libraries.designsystem.components.preferences.DropdownOption + +enum class LogLevelItem : DropdownOption { + ERROR { + override val text: String = "Error" + }, + WARN { + override val text: String = "Warn" + }, + INFO { + override val text: String = "Info" + }, + DEBUG { + override val text: String = "Debug" + }, + TRACE { + override val text: String = "Trace" + } +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelMapper.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelMapper.kt new file mode 100644 index 0000000000..fabfffa2cc --- /dev/null +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelMapper.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.preferences.impl.developer.tracing + +import io.element.android.libraries.matrix.api.tracing.LogLevel + +fun LogLevelItem.toLogLevel(): LogLevel { + return when (this) { + LogLevelItem.ERROR -> io.element.android.libraries.matrix.api.tracing.LogLevel.ERROR + LogLevelItem.WARN -> io.element.android.libraries.matrix.api.tracing.LogLevel.WARN + LogLevelItem.INFO -> io.element.android.libraries.matrix.api.tracing.LogLevel.INFO + LogLevelItem.DEBUG -> io.element.android.libraries.matrix.api.tracing.LogLevel.DEBUG + LogLevelItem.TRACE -> io.element.android.libraries.matrix.api.tracing.LogLevel.TRACE + } +} + +fun LogLevel.toLogLevelItem(): LogLevelItem { + return when (this) { + LogLevel.ERROR -> LogLevelItem.ERROR + LogLevel.WARN -> LogLevelItem.WARN + LogLevel.INFO -> LogLevelItem.INFO + LogLevel.DEBUG -> LogLevelItem.DEBUG + LogLevel.TRACE -> LogLevelItem.TRACE + } +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt deleted file mode 100644 index e7962ed8d7..0000000000 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TargetLogLevelMapBuilder.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl.developer.tracing - -import io.element.android.libraries.matrix.api.tracing.LogLevel -import io.element.android.libraries.matrix.api.tracing.Target -import io.element.android.libraries.matrix.api.tracing.TracingFilterConfiguration -import javax.inject.Inject - -class TargetLogLevelMapBuilder @Inject constructor( - private val tracingConfigurationStore: TracingConfigurationStore, - private val defaultConfig: TracingFilterConfiguration, -) { - fun getDefaultMap(): Map { - return Target.entries.associateWith { target -> - defaultConfig.getLogLevel(target) - } - } - - fun getCurrentMap(): Map { - return Target.entries.associateWith { target -> - tracingConfigurationStore.getLogLevel(target) - ?: defaultConfig.getLogLevel(target) - } - } -} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TracingConfigurationStore.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TracingConfigurationStore.kt deleted file mode 100644 index ca0f5fa087..0000000000 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/TracingConfigurationStore.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl.developer.tracing - -import android.content.SharedPreferences -import androidx.core.content.edit -import com.squareup.anvil.annotations.ContributesBinding -import io.element.android.libraries.di.AppScope -import io.element.android.libraries.matrix.api.tracing.LogLevel -import io.element.android.libraries.matrix.api.tracing.Target -import javax.inject.Inject - -interface TracingConfigurationStore { - fun getLogLevel(target: Target): LogLevel? - fun storeLogLevel(target: Target, logLevel: LogLevel) - fun reset() -} - -@ContributesBinding(AppScope::class) -class SharedPreferencesTracingConfigurationStore @Inject constructor( - private val sharedPreferences: SharedPreferences -) : TracingConfigurationStore { - override fun getLogLevel(target: Target): LogLevel? { - return sharedPreferences.getString("$KEY_PREFIX${target.name}", null) - ?.let { LogLevel.valueOf(it) } - } - - override fun storeLogLevel(target: Target, logLevel: LogLevel) { - sharedPreferences.edit { - putString("$KEY_PREFIX${target.name}", logLevel.name) - } - } - - override fun reset() { - sharedPreferences.edit { - sharedPreferences.all.keys.filter { it.startsWith(KEY_PREFIX) }.forEach { - remove(it) - } - } - } - - companion object { - private const val KEY_PREFIX = "tracing_log_level_" - } -} diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt index 3f9b951b03..a73114ea2c 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt @@ -12,6 +12,7 @@ package io.element.android.features.preferences.impl.developer import com.google.common.truth.Truth.assertThat import io.element.android.appconfig.ElementCallConfig import io.element.android.features.logout.test.FakeLogoutUseCase +import io.element.android.features.preferences.impl.developer.tracing.LogLevelItem import io.element.android.features.preferences.impl.tasks.FakeClearCacheUseCase import io.element.android.features.preferences.impl.tasks.FakeComputeCacheSizeUseCase import io.element.android.features.rageshake.api.preferences.aRageshakePreferencesState @@ -52,11 +53,13 @@ class DeveloperSettingsPresenterTest { assertThat(state.rageshakeState.isEnabled).isFalse() assertThat(state.rageshakeState.isSupported).isTrue() assertThat(state.rageshakeState.sensitivity).isEqualTo(0.3f) + assertThat(state.tracingLogLevel).isEqualTo(AsyncData.Uninitialized) } awaitItem().also { state -> assertThat(state.features).isNotEmpty() val numberOfModifiableFeatureFlags = FeatureFlags.entries.count { it.isFinished.not() } assertThat(state.features).hasSize(numberOfModifiableFeatureFlags) + assertThat(state.tracingLogLevel.dataOrNull()).isEqualTo(LogLevelItem.INFO) } awaitItem().also { state -> assertThat(state.cacheSize).isInstanceOf(AsyncData.Success::class.java) @@ -200,6 +203,22 @@ class DeveloperSettingsPresenterTest { } } + @Test + fun `present - changing tracing log level`() = runTest { + val preferences = InMemoryAppPreferencesStore() + val presenter = createDeveloperSettingsPresenter(preferencesStore = preferences) + presenter.test { + skipItems(2) + awaitItem().also { state -> + assertThat(state.tracingLogLevel.dataOrNull()).isEqualTo(LogLevelItem.INFO) + state.eventSink(DeveloperSettingsEvents.SetTracingLogLevel(LogLevelItem.TRACE)) + } + awaitItem().also { state -> + assertThat(state.tracingLogLevel.dataOrNull()).isEqualTo(LogLevelItem.TRACE) + } + } + } + private fun createDeveloperSettingsPresenter( featureFlagService: FakeFeatureFlagService = FakeFeatureFlagService(), cacheSizeUseCase: FakeComputeCacheSizeUseCase = FakeComputeCacheSizeUseCase(), diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsViewTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsViewTest.kt index 31596a4cd2..7d31517bf5 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsViewTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsViewTest.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.test.ext.junit.runners.AndroidJUnit4 import io.element.android.features.preferences.impl.R +import io.element.android.features.preferences.impl.developer.tracing.LogLevelItem import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalled import io.element.android.tests.testutils.EventsRecorder @@ -76,17 +77,16 @@ class DeveloperSettingsViewTest { @Config(qualifiers = "h1024dp") @Test - fun `clicking on configure tracing invokes the expected callback`() { - val eventsRecorder = EventsRecorder(expectEvents = false) - ensureCalledOnce { - rule.setDeveloperSettingsView( - state = aDeveloperSettingsState( - eventSink = eventsRecorder - ), - onOpenConfigureTracing = it - ) - rule.onNodeWithText("Configure tracing").performClick() - } + fun `clicking on log level emits the expected event`() { + val eventsRecorder = EventsRecorder() + rule.setDeveloperSettingsView( + state = aDeveloperSettingsState( + eventSink = eventsRecorder + ), + ) + rule.onNodeWithText("Tracing log level").performClick() + rule.onNodeWithText("Debug").performClick() + eventsRecorder.assertSingle(DeveloperSettingsEvents.SetTracingLogLevel(LogLevelItem.DEBUG)) } @Config(qualifiers = "h1500dp") @@ -131,14 +131,12 @@ class DeveloperSettingsViewTest { private fun AndroidComposeTestRule.setDeveloperSettingsView( state: DeveloperSettingsState, onOpenShowkase: () -> Unit = EnsureNeverCalled(), - onOpenConfigureTracing: () -> Unit = EnsureNeverCalled(), onBackClick: () -> Unit = EnsureNeverCalled() ) { setContent { DeveloperSettingsView( state = state, onOpenShowkase = onOpenShowkase, - onOpenConfigureTracing = onOpenConfigureTracing, onBackClick = onBackClick, ) } diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt deleted file mode 100644 index 4ec0353aaa..0000000000 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/ConfigureTracingPresenterTest.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl.developer.tracing - -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow -import app.cash.turbine.test -import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.matrix.api.tracing.LogLevel -import io.element.android.libraries.matrix.api.tracing.Target -import io.element.android.libraries.matrix.api.tracing.TracingFilterConfigurations -import io.element.android.tests.testutils.WarmUpRule -import io.element.android.tests.testutils.waitForPredicate -import kotlinx.coroutines.test.runTest -import org.junit.Rule -import org.junit.Test - -class ConfigureTracingPresenterTest { - @get:Rule - val warmUpRule = WarmUpRule() - - @Test - fun `present - initial state`() = runTest { - val store = InMemoryTracingConfigurationStore() - val presenter = ConfigureTracingPresenter( - store, - TargetLogLevelMapBuilder(store, TracingFilterConfigurations.debug), - ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - assertThat(initialState.targetsToLogLevel).isNotEmpty() - assertThat(initialState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.DEBUG) - } - } - - @Test - fun `present - store is taken into account`() = runTest { - val store = InMemoryTracingConfigurationStore() - store.givenLogLevel(LogLevel.ERROR) - val presenter = ConfigureTracingPresenter( - store, - TargetLogLevelMapBuilder(store, TracingFilterConfigurations.debug), - ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - assertThat(initialState.targetsToLogLevel).isNotEmpty() - assertThat(initialState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.ERROR) - } - } - - @Test - fun `present - change a value`() = runTest { - val store = InMemoryTracingConfigurationStore() - val presenter = ConfigureTracingPresenter( - store, - TargetLogLevelMapBuilder(store, TracingFilterConfigurations.debug), - ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - assertThat(initialState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.DEBUG) - initialState.eventSink.invoke(ConfigureTracingEvents.UpdateFilter(Target.MATRIX_SDK_CRYPTO, LogLevel.WARN)) - val finalState = awaitItem() - assertThat(finalState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.WARN) - waitForPredicate { store.hasStoreLogLevelBeenCalled } - } - } - - @Test - fun `present - reset`() = runTest { - val store = InMemoryTracingConfigurationStore() - val presenter = ConfigureTracingPresenter( - store, - TargetLogLevelMapBuilder(store, TracingFilterConfigurations.debug), - ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - assertThat(initialState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.DEBUG) - initialState.eventSink.invoke(ConfigureTracingEvents.UpdateFilter(Target.MATRIX_SDK_CRYPTO, LogLevel.WARN)) - val finalState = awaitItem() - assertThat(finalState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.WARN) - waitForPredicate { store.hasStoreLogLevelBeenCalled } - finalState.eventSink.invoke(ConfigureTracingEvents.ResetFilters) - val resetState = awaitItem() - assertThat(resetState.targetsToLogLevel[Target.MATRIX_SDK_CRYPTO]).isEqualTo(LogLevel.DEBUG) - waitForPredicate { store.hasResetBeenCalled } - } - } -} diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/InMemoryTracingConfigurationStore.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/InMemoryTracingConfigurationStore.kt deleted file mode 100644 index c8af0d2caf..0000000000 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/tracing/InMemoryTracingConfigurationStore.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2023, 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.preferences.impl.developer.tracing - -import io.element.android.libraries.matrix.api.tracing.LogLevel -import io.element.android.libraries.matrix.api.tracing.Target - -class InMemoryTracingConfigurationStore : TracingConfigurationStore { - var hasResetBeenCalled = false - private set - var hasStoreLogLevelBeenCalled = false - private set - private var logLevel: LogLevel? = null - - fun givenLogLevel(logLevel: LogLevel?) { - this.logLevel = logLevel - } - - override fun getLogLevel(target: Target): LogLevel? { - return logLevel - } - - override fun storeLogLevel(target: Target, logLevel: LogLevel) { - hasStoreLogLevelBeenCalled = true - } - - override fun reset() { - hasResetBeenCalled = true - } -} diff --git a/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/reporter/BugReporter.kt b/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/reporter/BugReporter.kt index 266ebbffa3..1cc3cc8908 100644 --- a/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/reporter/BugReporter.kt +++ b/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/reporter/BugReporter.kt @@ -35,9 +35,9 @@ interface BugReporter { fun logDirectory(): File /** - * Set the current tracing filter. + * Set the current tracing log level. */ - fun setCurrentTracingFilter(tracingFilter: String) + fun setCurrentTracingLogLevel(logLevel: String) /** * Save the logcat. diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt index 94dfbec6b0..d2e034be16 100755 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt @@ -79,7 +79,7 @@ class DefaultBugReporter @Inject constructor( } private val logcatCommandDebug = arrayOf("logcat", "-d", "-v", "threadtime", "*:*") - private var currentTracingFilter: String? = null + private var currentTracingLogLevel: String? = null private val logCatErrFile = File(logDirectory().absolutePath, LOG_CAT_FILENAME) @@ -156,7 +156,7 @@ class DefaultBugReporter @Inject constructor( if (crashCallStack.isNotEmpty() && withCrashLogs) { builder.addFormDataPart("label", "crash") } - currentTracingFilter?.let { + currentTracingLogLevel?.let { builder.addFormDataPart("tracing_filter", it) } if (buildMeta.isEnterpriseBuild) { @@ -299,8 +299,8 @@ class DefaultBugReporter @Inject constructor( } } - override fun setCurrentTracingFilter(tracingFilter: String) { - currentTracingFilter = tracingFilter + override fun setCurrentTracingLogLevel(logLevel: String) { + currentTracingLogLevel = logLevel } /** diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/FakeBugReporter.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/FakeBugReporter.kt index 55098d8320..1f10cd0ab1 100644 --- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/FakeBugReporter.kt +++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/FakeBugReporter.kt @@ -53,7 +53,7 @@ class FakeBugReporter(val mode: Mode = Mode.Success) : BugReporter { return File("fake") } - override fun setCurrentTracingFilter(tracingFilter: String) { + override fun setCurrentTracingLogLevel(logLevel: String) { // No op } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/LogLevel.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/LogLevel.kt new file mode 100644 index 0000000000..9485f14e1e --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/LogLevel.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2022-2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.matrix.api.tracing + +/** + * Log levels for tracing in the SDK. + */ +enum class LogLevel { + ERROR, + WARN, + INFO, + DEBUG, + TRACE, +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingConfiguration.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingConfiguration.kt index 908b740323..db2c946bf5 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingConfiguration.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingConfiguration.kt @@ -8,7 +8,8 @@ package io.element.android.libraries.matrix.api.tracing data class TracingConfiguration( - val filterConfiguration: TracingFilterConfiguration, + val logLevel: LogLevel, + val extraTargets: List, val writesToLogcat: Boolean, val writesToFilesConfiguration: WriteToFilesConfiguration, ) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt deleted file mode 100644 index 1af057a6fe..0000000000 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2022-2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.libraries.matrix.api.tracing - -data class TracingFilterConfiguration( - val overrides: Map = emptyMap(), -) { - private val defaultLogLevel = LogLevel.INFO - - // Order should matters - private val targetsToLogLevel: Map = mapOf( - Target.HYPER to LogLevel.WARN, - Target.MATRIX_SDK_CRYPTO to LogLevel.DEBUG, - Target.MATRIX_SDK_CRYPTO_ACCOUNT to LogLevel.TRACE, - Target.MATRIX_SDK_HTTP_CLIENT to LogLevel.DEBUG, - Target.MATRIX_SDK_SLIDING_SYNC to LogLevel.INFO, - Target.MATRIX_SDK_BASE_SLIDING_SYNC to LogLevel.INFO, - Target.MATRIX_SDK_UI_TIMELINE to LogLevel.INFO, - Target.MATRIX_SDK_BASE_CLIENT to LogLevel.TRACE, - // To debug OIDC logouts - Target.MATRIX_SDK_OIDC to LogLevel.TRACE, - ) - - fun getLogLevel(target: Target): LogLevel { - return overrides[target] ?: targetsToLogLevel[target] ?: defaultLogLevel - } - - val filter: String - get() { - val fullMap = Target.entries.associateWith { - overrides[it] ?: targetsToLogLevel[it] ?: defaultLogLevel - } - return fullMap.map { - if (it.key.filter.isEmpty()) { - it.value.filter - } else { - "${it.key.filter}=${it.value.filter}" - } - }.joinToString(separator = ",") - } -} - -enum class Target(open val filter: String) { - // COMMON(""), - ELEMENT("elementx"), - HYPER("hyper"), - MATRIX_SDK_FFI("matrix_sdk_ffi"), - MATRIX_SDK_UNIFFI_API("matrix_sdk_ffi::uniffi_api"), - MATRIX_SDK_CRYPTO("matrix_sdk_crypto"), - MATRIX_SDK_CRYPTO_ACCOUNT("matrix_sdk_crypto::olm::account"), - MATRIX_SDK("matrix_sdk"), - MATRIX_SDK_HTTP_CLIENT("matrix_sdk::http_client"), - MATRIX_SDK_CLIENT("matrix_sdk::client"), - MATRIX_SDK_OIDC("matrix_sdk::oidc"), - MATRIX_SDK_SEND_QUEUE("matrix_sdk::send_queue"), - MATRIX_SDK_SLIDING_SYNC("matrix_sdk::sliding_sync"), - MATRIX_SDK_BASE_SLIDING_SYNC("matrix_sdk_base::sliding_sync"), - MATRIX_SDK_UI_TIMELINE("matrix_sdk_ui::timeline"), - MATRIX_SDK_BASE_READ_RECEIPTS("matrix_sdk_base::read_receipts"), - MATRIX_SDK_BASE_CLIENT("matrix_sdk_base"), -} - -enum class LogLevel(open val filter: String) { - ERROR("error"), - WARN("warn"), - INFO("info"), - DEBUG("debug"), - TRACE("trace"), -} - -object TracingFilterConfigurations { - val release = TracingFilterConfiguration( - overrides = mapOf( - Target.ELEMENT to LogLevel.DEBUG - ), - ) - val nightly = TracingFilterConfiguration( - overrides = mapOf( - Target.ELEMENT to LogLevel.TRACE, - ), - ) - val debug = TracingFilterConfiguration( - overrides = mapOf( - Target.ELEMENT to LogLevel.TRACE - ) - ) - - /** - * Use this method to create a custom configuration where all targets will have the same log level. - */ - fun custom(logLevel: LogLevel) = TracingFilterConfiguration(overrides = Target.entries.associateWith { logLevel }) - - /** - * Use this method to override the log level of specific targets. - */ - fun custom(overrides: Map) = TracingFilterConfiguration(overrides) -} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingService.kt index 0a9c57f33a..53ee37ca78 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingService.kt @@ -11,5 +11,5 @@ import timber.log.Timber interface TracingService { fun setupTracing(tracingConfiguration: TracingConfiguration) - fun createTimberTree(): Timber.Tree + fun createTimberTree(target: String): Timber.Tree } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/TracingMatrixModule.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/TracingMatrixModule.kt deleted file mode 100644 index 1927b2f24d..0000000000 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/di/TracingMatrixModule.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.libraries.matrix.impl.di - -import com.squareup.anvil.annotations.ContributesTo -import dagger.Module -import dagger.Provides -import io.element.android.libraries.core.meta.BuildMeta -import io.element.android.libraries.core.meta.BuildType -import io.element.android.libraries.di.AppScope -import io.element.android.libraries.matrix.api.tracing.TracingFilterConfiguration -import io.element.android.libraries.matrix.api.tracing.TracingFilterConfigurations - -@Module -@ContributesTo(AppScope::class) -object TracingMatrixModule { - @Provides - fun providesTracingFilterConfiguration(buildMeta: BuildMeta): TracingFilterConfiguration { - return when (buildMeta.buildType) { - BuildType.DEBUG -> TracingFilterConfigurations.debug - BuildType.NIGHTLY -> TracingFilterConfigurations.nightly - BuildType.RELEASE -> TracingFilterConfigurations.release - } - } -} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt index b9fdeda6ce..74fb2e9db1 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingService.kt @@ -10,6 +10,7 @@ package io.element.android.libraries.matrix.impl.tracing import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.di.AppScope +import io.element.android.libraries.matrix.api.tracing.LogLevel import io.element.android.libraries.matrix.api.tracing.TracingConfiguration import io.element.android.libraries.matrix.api.tracing.TracingService import io.element.android.libraries.matrix.api.tracing.WriteToFilesConfiguration @@ -20,21 +21,28 @@ import javax.inject.Inject @ContributesBinding(AppScope::class) class RustTracingService @Inject constructor(private val buildMeta: BuildMeta) : TracingService { override fun setupTracing(tracingConfiguration: TracingConfiguration) { - /* - val filter = tracingConfiguration.filterConfiguration val rustTracingConfiguration = org.matrix.rustcomponents.sdk.TracingConfiguration( - filter = tracingConfiguration.filterConfiguration.filter, writeToStdoutOrSystem = tracingConfiguration.writesToLogcat, + logLevel = tracingConfiguration.logLevel.toRustLogLevel(), + extraTargets = tracingConfiguration.extraTargets, writeToFiles = tracingConfiguration.writesToFilesConfiguration.toTracingFileConfiguration(), ) org.matrix.rustcomponents.sdk.setupTracing(rustTracingConfiguration) - Timber.v("Tracing config filter = $filter: ${filter.filter}") - - */ + Timber.d("setupTracing: $rustTracingConfiguration") } - override fun createTimberTree(): Timber.Tree { - return RustTracingTree(retrieveFromStackTrace = buildMeta.isDebuggable) + override fun createTimberTree(target: String): Timber.Tree { + return RustTracingTree(target = target, retrieveFromStackTrace = buildMeta.isDebuggable) + } +} + +private fun LogLevel.toRustLogLevel(): org.matrix.rustcomponents.sdk.LogLevel { + return when (this) { + LogLevel.ERROR -> org.matrix.rustcomponents.sdk.LogLevel.ERROR + LogLevel.WARN -> org.matrix.rustcomponents.sdk.LogLevel.WARN + LogLevel.INFO -> org.matrix.rustcomponents.sdk.LogLevel.INFO + LogLevel.DEBUG -> org.matrix.rustcomponents.sdk.LogLevel.DEBUG + LogLevel.TRACE -> org.matrix.rustcomponents.sdk.LogLevel.TRACE } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingTree.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingTree.kt index 47b2c8482d..cdd545197b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingTree.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/tracing/RustTracingTree.kt @@ -8,7 +8,6 @@ package io.element.android.libraries.matrix.impl.tracing import android.util.Log -import io.element.android.libraries.matrix.api.tracing.Target import org.matrix.rustcomponents.sdk.LogLevel import org.matrix.rustcomponents.sdk.logEvent import timber.log.Timber @@ -26,7 +25,10 @@ private val fqcnIgnore = listOf( /** * A Timber tree that passes logs to the Rust SDK. */ -internal class RustTracingTree(private val retrieveFromStackTrace: Boolean) : Timber.Tree() { +internal class RustTracingTree( + private val target: String, + private val retrieveFromStackTrace: Boolean, +) : Timber.Tree() { override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { val location = if (retrieveFromStackTrace) { getLogEventLocationFromStackTrace() @@ -38,7 +40,7 @@ internal class RustTracingTree(private val retrieveFromStackTrace: Boolean) : Ti file = location.file, line = location.line, level = logLevel, - target = Target.ELEMENT.filter, + target = target, message = if (tag != null) "[$tag] $message" else message, ) } diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/di/TracingMatrixModuleTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/di/TracingMatrixModuleTest.kt deleted file mode 100644 index e11e8741ec..0000000000 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/di/TracingMatrixModuleTest.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2024 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.libraries.matrix.impl.di - -import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.core.meta.BuildType -import io.element.android.libraries.matrix.api.tracing.TracingFilterConfigurations -import io.element.android.libraries.matrix.test.core.aBuildMeta -import org.junit.Test - -class TracingMatrixModuleTest { - @Test - fun `providesTracingFilterConfiguration returns debug config for debug build`() { - assertThat(TracingMatrixModule.providesTracingFilterConfiguration(aBuildMeta(BuildType.DEBUG))) - .isEqualTo(TracingFilterConfigurations.debug) - } - - @Test - fun `providesTracingFilterConfiguration returns nightly config for nightly build`() { - assertThat(TracingMatrixModule.providesTracingFilterConfiguration(aBuildMeta(BuildType.NIGHTLY))) - .isEqualTo(TracingFilterConfigurations.nightly) - } - - @Test - fun `providesTracingFilterConfiguration returns release config for release build`() { - assertThat(TracingMatrixModule.providesTracingFilterConfiguration(aBuildMeta(BuildType.RELEASE))) - .isEqualTo(TracingFilterConfigurations.release) - } -} diff --git a/libraries/preferences/api/src/main/kotlin/io/element/android/libraries/preferences/api/store/AppPreferencesStore.kt b/libraries/preferences/api/src/main/kotlin/io/element/android/libraries/preferences/api/store/AppPreferencesStore.kt index bbf3ed37e0..865e2992d2 100644 --- a/libraries/preferences/api/src/main/kotlin/io/element/android/libraries/preferences/api/store/AppPreferencesStore.kt +++ b/libraries/preferences/api/src/main/kotlin/io/element/android/libraries/preferences/api/store/AppPreferencesStore.kt @@ -7,6 +7,7 @@ package io.element.android.libraries.preferences.api.store +import io.element.android.libraries.matrix.api.tracing.LogLevel import kotlinx.coroutines.flow.Flow interface AppPreferencesStore { @@ -25,5 +26,8 @@ interface AppPreferencesStore { suspend fun setHideImagesAndVideos(value: Boolean) fun doesHideImagesAndVideosFlow(): Flow + suspend fun setTracingLogLevel(logLevel: LogLevel) + fun getTracingLogLevelFlow(): Flow + suspend fun reset() } diff --git a/libraries/preferences/impl/src/main/kotlin/io/element/android/libraries/preferences/impl/store/DefaultAppPreferencesStore.kt b/libraries/preferences/impl/src/main/kotlin/io/element/android/libraries/preferences/impl/store/DefaultAppPreferencesStore.kt index 5d7bab4b04..1874b08b0e 100644 --- a/libraries/preferences/impl/src/main/kotlin/io/element/android/libraries/preferences/impl/store/DefaultAppPreferencesStore.kt +++ b/libraries/preferences/impl/src/main/kotlin/io/element/android/libraries/preferences/impl/store/DefaultAppPreferencesStore.kt @@ -19,6 +19,7 @@ import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildType import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext +import io.element.android.libraries.matrix.api.tracing.LogLevel import io.element.android.libraries.preferences.api.store.AppPreferencesStore import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map @@ -31,6 +32,7 @@ private val customElementCallBaseUrlKey = stringPreferencesKey("elementCallBaseU private val themeKey = stringPreferencesKey("theme") private val simplifiedSlidingSyncKey = booleanPreferencesKey("useSimplifiedSlidingSync") private val hideImagesAndVideosKey = booleanPreferencesKey("hideImagesAndVideos") +private val logLevelKey = stringPreferencesKey("logLevel") @ContributesBinding(AppScope::class) class DefaultAppPreferencesStore @Inject constructor( @@ -104,7 +106,27 @@ class DefaultAppPreferencesStore @Inject constructor( } } + override suspend fun setTracingLogLevel(logLevel: LogLevel) { + store.edit { prefs -> + prefs[logLevelKey] = logLevel.name + } + } + + override fun getTracingLogLevelFlow(): Flow { + return store.data.map { prefs -> + prefs[logLevelKey]?.let { LogLevel.valueOf(it) } ?: buildMeta.defaultLogLevel() + } + } + override suspend fun reset() { store.edit { it.clear() } } } + +private fun BuildMeta.defaultLogLevel(): LogLevel { + return when (buildType) { + BuildType.DEBUG -> LogLevel.TRACE + BuildType.NIGHTLY -> LogLevel.DEBUG + BuildType.RELEASE -> LogLevel.INFO + } +} diff --git a/libraries/preferences/test/src/main/kotlin/io/element/android/libraries/preferences/test/InMemoryAppPreferencesStore.kt b/libraries/preferences/test/src/main/kotlin/io/element/android/libraries/preferences/test/InMemoryAppPreferencesStore.kt index 9415811e71..3191b22073 100644 --- a/libraries/preferences/test/src/main/kotlin/io/element/android/libraries/preferences/test/InMemoryAppPreferencesStore.kt +++ b/libraries/preferences/test/src/main/kotlin/io/element/android/libraries/preferences/test/InMemoryAppPreferencesStore.kt @@ -7,6 +7,7 @@ package io.element.android.libraries.preferences.test +import io.element.android.libraries.matrix.api.tracing.LogLevel import io.element.android.libraries.preferences.api.store.AppPreferencesStore import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -16,13 +17,15 @@ class InMemoryAppPreferencesStore( hideImagesAndVideos: Boolean = false, customElementCallBaseUrl: String? = null, theme: String? = null, - simplifiedSlidingSyncEnabled: Boolean = false + simplifiedSlidingSyncEnabled: Boolean = false, + logLevel: LogLevel = LogLevel.INFO, ) : AppPreferencesStore { private val isDeveloperModeEnabled = MutableStateFlow(isDeveloperModeEnabled) private val hideImagesAndVideos = MutableStateFlow(hideImagesAndVideos) private val customElementCallBaseUrl = MutableStateFlow(customElementCallBaseUrl) private val theme = MutableStateFlow(theme) private val simplifiedSlidingSyncEnabled = MutableStateFlow(simplifiedSlidingSyncEnabled) + private val logLevel = MutableStateFlow(logLevel) override suspend fun setDeveloperModeEnabled(enabled: Boolean) { isDeveloperModeEnabled.value = enabled @@ -64,6 +67,14 @@ class InMemoryAppPreferencesStore( return hideImagesAndVideos } + override suspend fun setTracingLogLevel(logLevel: LogLevel) { + this.logLevel.value = logLevel + } + + override fun getTracingLogLevelFlow(): Flow { + return logLevel + } + override suspend fun reset() { // No op } From b6d5e9c6de1493b937c85788edbe770dbb913d87 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 17 Jan 2025 09:07:05 +0000 Subject: [PATCH 10/11] Update screenshots --- .../features.onboarding.impl_OnBoardingView_Day_4_en.png | 3 --- .../features.onboarding.impl_OnBoardingView_Night_4_en.png | 3 --- ...es.impl.developer.tracing_ConfigureTracingView_Day_0_en.png | 3 --- ....impl.developer.tracing_ConfigureTracingView_Night_0_en.png | 3 --- ...omponents.preferences_PreferenceDropdown_Preferences_en.png | 3 +++ 5 files changed, 3 insertions(+), 12 deletions(-) delete mode 100644 tests/uitests/src/test/snapshots/images/features.onboarding.impl_OnBoardingView_Day_4_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.onboarding.impl_OnBoardingView_Night_4_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.developer.tracing_ConfigureTracingView_Day_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.developer.tracing_ConfigureTracingView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.onboarding.impl_OnBoardingView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.onboarding.impl_OnBoardingView_Day_4_en.png deleted file mode 100644 index 1b1e654182..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.onboarding.impl_OnBoardingView_Day_4_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f756552f2d88693ae654f92c24b5c23a31cfa6086309e0996444f17bd33f07a -size 312449 diff --git a/tests/uitests/src/test/snapshots/images/features.onboarding.impl_OnBoardingView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.onboarding.impl_OnBoardingView_Night_4_en.png deleted file mode 100644 index f8bfd58281..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.onboarding.impl_OnBoardingView_Night_4_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6992b4234fab8b623c05c01c6823791f09bf561b83052cd57d69952380762557 -size 393746 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.developer.tracing_ConfigureTracingView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.developer.tracing_ConfigureTracingView_Day_0_en.png deleted file mode 100644 index c4148bcdef..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.developer.tracing_ConfigureTracingView_Day_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7f1df59fddb1576e385b2fb02cefa904b445376ceb4f1d6ee307e1fcd897d25d -size 38164 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.developer.tracing_ConfigureTracingView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.developer.tracing_ConfigureTracingView_Night_0_en.png deleted file mode 100644 index a303fc1b0c..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.developer.tracing_ConfigureTracingView_Night_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:98bd0b6bf5d549ccb7c306dedc807aeb6bd98e77be7b6d8f73ce444000872624 -size 36727 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png new file mode 100644 index 0000000000..2ec789f448 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.components.preferences_PreferenceDropdown_Preferences_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca9a1d1bb7d4de0b8a5f5efd62cde248f0c9e07b88b2fbdbc598d922003a7f02 +size 31032 From 599972adea4afc069982bb014d432afeaad91bac Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 17 Jan 2025 16:59:31 +0100 Subject: [PATCH 11/11] change(tracing) : update bug reporter tracing form data. --- .../features/rageshake/impl/reporter/DefaultBugReporter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt index d2e034be16..4ec8500417 100755 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt @@ -157,7 +157,7 @@ class DefaultBugReporter @Inject constructor( builder.addFormDataPart("label", "crash") } currentTracingLogLevel?.let { - builder.addFormDataPart("tracing_filter", it) + builder.addFormDataPart("tracing_log_level", it) } if (buildMeta.isEnterpriseBuild) { builder.addFormDataPart("label", "Enterprise")