fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.3.24 (#4394)

* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.3.24

* Fix SDK changes related to:
    - OIDC authentication.
    - Element Call widget URL generation.
    - Forced trace logging in the SDK.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
This commit is contained in:
renovate[bot]
2025-03-24 17:07:44 +01:00
committed by GitHub
parent d7a355bb42
commit 721becf45d
14 changed files with 76 additions and 31 deletions

View File

@@ -174,7 +174,7 @@ jsoup = "org.jsoup:jsoup:1.19.1"
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:25.3.20"
matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.3.24"
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" }

View File

@@ -10,7 +10,7 @@ package io.element.android.libraries.matrix.api.widget
import java.util.UUID
interface CallWidgetSettingsProvider {
fun provide(
suspend fun provide(
baseUrl: String,
widgetId: String = UUID.randomUUID().toString(),
encrypted: Boolean,

View File

@@ -33,6 +33,8 @@ dependencies {
implementation(projects.libraries.network)
implementation(projects.libraries.preferences.api)
implementation(projects.services.analytics.api)
implementation(projects.services.analyticsproviders.posthog)
implementation(projects.services.analyticsproviders.sentry)
implementation(projects.services.toolbox.api)
api(projects.libraries.matrix.api)
implementation(libs.dagger)

View File

@@ -477,11 +477,16 @@ class RustMatrixClient(
override fun roomDirectoryService(): RoomDirectoryService = roomDirectoryService
override fun close() {
innerNotificationClient.close()
appCoroutineScope.launch {
roomFactory.destroy()
rustSyncService.destroy()
notificationSettingsService.destroy()
// This is sync, but it can destroy the `Client` instance and block stopping the sync service
notificationProcessSetup.destroy()
}
sessionCoroutineScope.cancel()
clientDelegateTaskHandle?.cancelAndDestroy()
verificationService.destroy()
@@ -489,7 +494,6 @@ class RustMatrixClient(
sessionDelegate.clearCurrentClient()
innerRoomListService.close()
notificationService.close()
notificationProcessSetup.destroy()
encryptionService.close()
innerClient.close()
}

View File

@@ -205,7 +205,9 @@ class RustMatrixAuthenticationService @Inject constructor(
override suspend fun cancelOidcLogin(): Result<Unit> {
return withContext(coroutineDispatchers.io) {
runCatching {
pendingOAuthAuthorizationData?.close()
pendingOAuthAuthorizationData?.use {
currentClient?.abortOidcAuth(it)
}
pendingOAuthAuthorizationData = null
}.mapFailure { failure ->
failure.mapAuthenticationException()
@@ -221,16 +223,18 @@ class RustMatrixAuthenticationService @Inject constructor(
runCatching {
val client = currentClient ?: error("You need to call `setHomeserver()` first")
val currentSessionPaths = sessionPaths ?: error("You need to call `setHomeserver()` first")
val urlForOidcLogin = pendingOAuthAuthorizationData ?: error("You need to call `getOidcUrl()` first")
client.loginWithOidcCallback(urlForOidcLogin, callbackUrl)
client.loginWithOidcCallback(callbackUrl)
val sessionData = client.session().toSessionData(
isTokenValid = true,
loginType = LoginType.OIDC,
passphrase = pendingPassphrase,
sessionPaths = currentSessionPaths,
)
// Free the pending data since we won't use it to abort the flow anymore
pendingOAuthAuthorizationData?.close()
pendingOAuthAuthorizationData = null
newMatrixClientObserver?.invoke(rustMatrixClientFactory.create(client))
sessionStore.storeData(sessionData)

View File

@@ -62,6 +62,7 @@ class RustSyncService(
stopSync()
Timber.d("Destroying sync service")
isServiceReady.set(false)
inner.destroy()
}
override val syncState: StateFlow<SyncState> =

View File

@@ -51,5 +51,7 @@ fun TracingConfiguration.map(): org.matrix.rustcomponents.sdk.TracingConfigurati
writeToStdoutOrSystem = writesToLogcat,
logLevel = logLevel.toRustLogLevel(),
extraTargets = extraTargets,
// WARNING: this should be used only to debug issues, changes to this value should *never* be published
traceLogPacks = emptyList(),
writeToFiles = writesToFilesConfiguration.toTracingFileConfiguration(),
)

View File

@@ -8,30 +8,50 @@
package io.element.android.libraries.matrix.impl.widget
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.appconfig.RageshakeConfig
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.widget.CallWidgetSettingsProvider
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
import io.element.android.services.analytics.api.store.AnalyticsStore
import io.element.android.services.analyticsproviders.posthog.PosthogEndpointConfigProvider
import io.element.android.services.analyticsproviders.sentry.SentryConfig
import kotlinx.coroutines.flow.first
import org.matrix.rustcomponents.sdk.EncryptionSystem
import org.matrix.rustcomponents.sdk.VirtualElementCallWidgetOptions
import org.matrix.rustcomponents.sdk.newVirtualElementCallWidget
import javax.inject.Inject
import org.matrix.rustcomponents.sdk.Intent as CallIntent
@ContributesBinding(AppScope::class)
class DefaultCallWidgetSettingsProvider @Inject constructor() : CallWidgetSettingsProvider {
override fun provide(baseUrl: String, widgetId: String, encrypted: Boolean): MatrixWidgetSettings {
class DefaultCallWidgetSettingsProvider @Inject constructor(
private val buildMeta: BuildMeta,
private val posthogEndpointConfigProvider: PosthogEndpointConfigProvider,
private val analyticsStore: AnalyticsStore,
) : CallWidgetSettingsProvider {
override suspend fun provide(baseUrl: String, widgetId: String, encrypted: Boolean): MatrixWidgetSettings {
val analyticsEnabled = analyticsStore.userConsentFlow.first()
val posthogEndpointConfig = posthogEndpointConfigProvider.provide()
val options = VirtualElementCallWidgetOptions(
elementCallUrl = baseUrl,
widgetId = widgetId,
parentUrl = null,
hideHeader = null,
preload = null,
fontScale = null,
appPrompt = false,
skipLobby = true,
confineToRoom = true,
font = null,
analyticsId = null,
encryption = if (encrypted) EncryptionSystem.PerParticipantKeys else EncryptionSystem.Unencrypted,
intent = CallIntent.START_CALL,
hideScreensharing = false,
posthogUserId = null,
posthogApiHost = posthogEndpointConfig.host.takeIf { analyticsEnabled },
posthogApiKey = posthogEndpointConfig.apiKey.takeIf { analyticsEnabled },
rageshakeSubmitUrl = RageshakeConfig.BUG_REPORT_URL,
sentryDsn = SentryConfig.DSN.takeIf { analyticsEnabled },
sentryEnvironment = if (buildMeta.buildType == BuildType.RELEASE) SentryConfig.ENV_RELEASE else SentryConfig.ENV_DEBUG,
parentUrl = null,
hideHeader = true,
)
val rustWidgetSettings = newVirtualElementCallWidget(options)
return MatrixWidgetSettings.fromRustWidgetSettings(rustWidgetSettings)

View File

@@ -15,7 +15,7 @@ class FakeCallWidgetSettingsProvider(
) : CallWidgetSettingsProvider {
val providedBaseUrls = mutableListOf<String>()
override fun provide(baseUrl: String, widgetId: String, encrypted: Boolean): MatrixWidgetSettings {
override suspend fun provide(baseUrl: String, widgetId: String, encrypted: Boolean): MatrixWidgetSettings {
providedBaseUrls += baseUrl
return provideFn(baseUrl, widgetId)
}

View File

@@ -0,0 +1,26 @@
/*
* 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.services.analytics.api.store
import kotlinx.coroutines.flow.Flow
/**
* Local storage for:
* - user consent (Boolean);
* - did ask user consent (Boolean);
* - analytics Id (String).
*/
interface AnalyticsStore {
val userConsentFlow: Flow<Boolean>
val didAskUserConsentFlow: Flow<Boolean>
val analyticsIdFlow: Flow<String>
suspend fun setUserConsent(newUserConsent: Boolean)
suspend fun setDidAskUserConsent(newValue: Boolean = true)
suspend fun setAnalyticsId(newAnalyticsId: String)
suspend fun reset()
}

View File

@@ -17,8 +17,8 @@ import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.sessionstorage.api.observer.SessionListener
import io.element.android.libraries.sessionstorage.api.observer.SessionObserver
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analytics.api.store.AnalyticsStore
import io.element.android.services.analytics.impl.log.analyticsTag
import io.element.android.services.analytics.impl.store.AnalyticsStore
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow

View File

@@ -18,6 +18,7 @@ import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.services.analytics.api.store.AnalyticsStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
@@ -28,22 +29,6 @@ import javax.inject.Inject
*/
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_analytics")
/**
* Local storage for:
* - user consent (Boolean);
* - did ask user consent (Boolean);
* - analytics Id (String).
*/
interface AnalyticsStore {
val userConsentFlow: Flow<Boolean>
val didAskUserConsentFlow: Flow<Boolean>
val analyticsIdFlow: Flow<String>
suspend fun setUserConsent(newUserConsent: Boolean)
suspend fun setDidAskUserConsent(newValue: Boolean = true)
suspend fun setAnalyticsId(newAnalyticsId: String)
suspend fun reset()
}
@ContributesBinding(AppScope::class)
class DefaultAnalyticsStore @Inject constructor(
@ApplicationContext private val context: Context

View File

@@ -18,7 +18,7 @@ import im.vector.app.features.analytics.plan.SuperProperties
import im.vector.app.features.analytics.plan.UserProperties
import io.element.android.libraries.sessionstorage.api.observer.SessionObserver
import io.element.android.libraries.sessionstorage.test.observer.NoOpSessionObserver
import io.element.android.services.analytics.impl.store.AnalyticsStore
import io.element.android.services.analytics.api.store.AnalyticsStore
import io.element.android.services.analytics.impl.store.FakeAnalyticsStore
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
import io.element.android.services.analyticsproviders.test.FakeAnalyticsProvider

View File

@@ -7,6 +7,7 @@
package io.element.android.services.analytics.impl.store
import io.element.android.services.analytics.api.store.AnalyticsStore
import io.element.android.tests.testutils.lambda.lambdaError
import kotlinx.coroutines.flow.MutableStateFlow