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:
parent
d7a355bb42
commit
721becf45d
14 changed files with 76 additions and 31 deletions
|
|
@ -174,7 +174,7 @@ jsoup = "org.jsoup:jsoup:1.19.1"
|
||||||
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
||||||
molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0"
|
molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0"
|
||||||
timber = "com.jakewharton.timber:timber:5.0.1"
|
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 = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
|
||||||
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", 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" }
|
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ package io.element.android.libraries.matrix.api.widget
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
interface CallWidgetSettingsProvider {
|
interface CallWidgetSettingsProvider {
|
||||||
fun provide(
|
suspend fun provide(
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
widgetId: String = UUID.randomUUID().toString(),
|
widgetId: String = UUID.randomUUID().toString(),
|
||||||
encrypted: Boolean,
|
encrypted: Boolean,
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ dependencies {
|
||||||
implementation(projects.libraries.network)
|
implementation(projects.libraries.network)
|
||||||
implementation(projects.libraries.preferences.api)
|
implementation(projects.libraries.preferences.api)
|
||||||
implementation(projects.services.analytics.api)
|
implementation(projects.services.analytics.api)
|
||||||
|
implementation(projects.services.analyticsproviders.posthog)
|
||||||
|
implementation(projects.services.analyticsproviders.sentry)
|
||||||
implementation(projects.services.toolbox.api)
|
implementation(projects.services.toolbox.api)
|
||||||
api(projects.libraries.matrix.api)
|
api(projects.libraries.matrix.api)
|
||||||
implementation(libs.dagger)
|
implementation(libs.dagger)
|
||||||
|
|
|
||||||
|
|
@ -477,11 +477,16 @@ class RustMatrixClient(
|
||||||
override fun roomDirectoryService(): RoomDirectoryService = roomDirectoryService
|
override fun roomDirectoryService(): RoomDirectoryService = roomDirectoryService
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
|
innerNotificationClient.close()
|
||||||
|
|
||||||
appCoroutineScope.launch {
|
appCoroutineScope.launch {
|
||||||
roomFactory.destroy()
|
roomFactory.destroy()
|
||||||
rustSyncService.destroy()
|
rustSyncService.destroy()
|
||||||
notificationSettingsService.destroy()
|
notificationSettingsService.destroy()
|
||||||
|
// This is sync, but it can destroy the `Client` instance and block stopping the sync service
|
||||||
|
notificationProcessSetup.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionCoroutineScope.cancel()
|
sessionCoroutineScope.cancel()
|
||||||
clientDelegateTaskHandle?.cancelAndDestroy()
|
clientDelegateTaskHandle?.cancelAndDestroy()
|
||||||
verificationService.destroy()
|
verificationService.destroy()
|
||||||
|
|
@ -489,7 +494,6 @@ class RustMatrixClient(
|
||||||
sessionDelegate.clearCurrentClient()
|
sessionDelegate.clearCurrentClient()
|
||||||
innerRoomListService.close()
|
innerRoomListService.close()
|
||||||
notificationService.close()
|
notificationService.close()
|
||||||
notificationProcessSetup.destroy()
|
|
||||||
encryptionService.close()
|
encryptionService.close()
|
||||||
innerClient.close()
|
innerClient.close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,9 @@ class RustMatrixAuthenticationService @Inject constructor(
|
||||||
override suspend fun cancelOidcLogin(): Result<Unit> {
|
override suspend fun cancelOidcLogin(): Result<Unit> {
|
||||||
return withContext(coroutineDispatchers.io) {
|
return withContext(coroutineDispatchers.io) {
|
||||||
runCatching {
|
runCatching {
|
||||||
pendingOAuthAuthorizationData?.close()
|
pendingOAuthAuthorizationData?.use {
|
||||||
|
currentClient?.abortOidcAuth(it)
|
||||||
|
}
|
||||||
pendingOAuthAuthorizationData = null
|
pendingOAuthAuthorizationData = null
|
||||||
}.mapFailure { failure ->
|
}.mapFailure { failure ->
|
||||||
failure.mapAuthenticationException()
|
failure.mapAuthenticationException()
|
||||||
|
|
@ -221,16 +223,18 @@ class RustMatrixAuthenticationService @Inject constructor(
|
||||||
runCatching {
|
runCatching {
|
||||||
val client = currentClient ?: error("You need to call `setHomeserver()` first")
|
val client = currentClient ?: error("You need to call `setHomeserver()` first")
|
||||||
val currentSessionPaths = sessionPaths ?: 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(callbackUrl)
|
||||||
client.loginWithOidcCallback(urlForOidcLogin, callbackUrl)
|
|
||||||
val sessionData = client.session().toSessionData(
|
val sessionData = client.session().toSessionData(
|
||||||
isTokenValid = true,
|
isTokenValid = true,
|
||||||
loginType = LoginType.OIDC,
|
loginType = LoginType.OIDC,
|
||||||
passphrase = pendingPassphrase,
|
passphrase = pendingPassphrase,
|
||||||
sessionPaths = currentSessionPaths,
|
sessionPaths = currentSessionPaths,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Free the pending data since we won't use it to abort the flow anymore
|
||||||
pendingOAuthAuthorizationData?.close()
|
pendingOAuthAuthorizationData?.close()
|
||||||
pendingOAuthAuthorizationData = null
|
pendingOAuthAuthorizationData = null
|
||||||
|
|
||||||
newMatrixClientObserver?.invoke(rustMatrixClientFactory.create(client))
|
newMatrixClientObserver?.invoke(rustMatrixClientFactory.create(client))
|
||||||
sessionStore.storeData(sessionData)
|
sessionStore.storeData(sessionData)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ class RustSyncService(
|
||||||
stopSync()
|
stopSync()
|
||||||
Timber.d("Destroying sync service")
|
Timber.d("Destroying sync service")
|
||||||
isServiceReady.set(false)
|
isServiceReady.set(false)
|
||||||
|
inner.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val syncState: StateFlow<SyncState> =
|
override val syncState: StateFlow<SyncState> =
|
||||||
|
|
|
||||||
|
|
@ -51,5 +51,7 @@ fun TracingConfiguration.map(): org.matrix.rustcomponents.sdk.TracingConfigurati
|
||||||
writeToStdoutOrSystem = writesToLogcat,
|
writeToStdoutOrSystem = writesToLogcat,
|
||||||
logLevel = logLevel.toRustLogLevel(),
|
logLevel = logLevel.toRustLogLevel(),
|
||||||
extraTargets = extraTargets,
|
extraTargets = extraTargets,
|
||||||
|
// WARNING: this should be used only to debug issues, changes to this value should *never* be published
|
||||||
|
traceLogPacks = emptyList(),
|
||||||
writeToFiles = writesToFilesConfiguration.toTracingFileConfiguration(),
|
writeToFiles = writesToFilesConfiguration.toTracingFileConfiguration(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,30 +8,50 @@
|
||||||
package io.element.android.libraries.matrix.impl.widget
|
package io.element.android.libraries.matrix.impl.widget
|
||||||
|
|
||||||
import com.squareup.anvil.annotations.ContributesBinding
|
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.di.AppScope
|
||||||
import io.element.android.libraries.matrix.api.widget.CallWidgetSettingsProvider
|
import io.element.android.libraries.matrix.api.widget.CallWidgetSettingsProvider
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
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.EncryptionSystem
|
||||||
import org.matrix.rustcomponents.sdk.VirtualElementCallWidgetOptions
|
import org.matrix.rustcomponents.sdk.VirtualElementCallWidgetOptions
|
||||||
import org.matrix.rustcomponents.sdk.newVirtualElementCallWidget
|
import org.matrix.rustcomponents.sdk.newVirtualElementCallWidget
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import org.matrix.rustcomponents.sdk.Intent as CallIntent
|
||||||
|
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
class DefaultCallWidgetSettingsProvider @Inject constructor() : CallWidgetSettingsProvider {
|
class DefaultCallWidgetSettingsProvider @Inject constructor(
|
||||||
override fun provide(baseUrl: String, widgetId: String, encrypted: Boolean): MatrixWidgetSettings {
|
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(
|
val options = VirtualElementCallWidgetOptions(
|
||||||
elementCallUrl = baseUrl,
|
elementCallUrl = baseUrl,
|
||||||
widgetId = widgetId,
|
widgetId = widgetId,
|
||||||
parentUrl = null,
|
|
||||||
hideHeader = null,
|
|
||||||
preload = null,
|
preload = null,
|
||||||
fontScale = null,
|
fontScale = null,
|
||||||
appPrompt = false,
|
appPrompt = false,
|
||||||
skipLobby = true,
|
|
||||||
confineToRoom = true,
|
confineToRoom = true,
|
||||||
font = null,
|
font = null,
|
||||||
analyticsId = null,
|
|
||||||
encryption = if (encrypted) EncryptionSystem.PerParticipantKeys else EncryptionSystem.Unencrypted,
|
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)
|
val rustWidgetSettings = newVirtualElementCallWidget(options)
|
||||||
return MatrixWidgetSettings.fromRustWidgetSettings(rustWidgetSettings)
|
return MatrixWidgetSettings.fromRustWidgetSettings(rustWidgetSettings)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class FakeCallWidgetSettingsProvider(
|
||||||
) : CallWidgetSettingsProvider {
|
) : CallWidgetSettingsProvider {
|
||||||
val providedBaseUrls = mutableListOf<String>()
|
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
|
providedBaseUrls += baseUrl
|
||||||
return provideFn(baseUrl, widgetId)
|
return provideFn(baseUrl, widgetId)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
}
|
||||||
|
|
@ -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.SessionListener
|
||||||
import io.element.android.libraries.sessionstorage.api.observer.SessionObserver
|
import io.element.android.libraries.sessionstorage.api.observer.SessionObserver
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
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.log.analyticsTag
|
||||||
import io.element.android.services.analytics.impl.store.AnalyticsStore
|
|
||||||
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
|
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import com.squareup.anvil.annotations.ContributesBinding
|
||||||
import io.element.android.libraries.core.bool.orFalse
|
import io.element.android.libraries.core.bool.orFalse
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.di.ApplicationContext
|
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.Flow
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
@ -28,22 +29,6 @@ import javax.inject.Inject
|
||||||
*/
|
*/
|
||||||
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_analytics")
|
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)
|
@ContributesBinding(AppScope::class)
|
||||||
class DefaultAnalyticsStore @Inject constructor(
|
class DefaultAnalyticsStore @Inject constructor(
|
||||||
@ApplicationContext private val context: Context
|
@ApplicationContext private val context: Context
|
||||||
|
|
@ -18,7 +18,7 @@ import im.vector.app.features.analytics.plan.SuperProperties
|
||||||
import im.vector.app.features.analytics.plan.UserProperties
|
import im.vector.app.features.analytics.plan.UserProperties
|
||||||
import io.element.android.libraries.sessionstorage.api.observer.SessionObserver
|
import io.element.android.libraries.sessionstorage.api.observer.SessionObserver
|
||||||
import io.element.android.libraries.sessionstorage.test.observer.NoOpSessionObserver
|
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.analytics.impl.store.FakeAnalyticsStore
|
||||||
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
|
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
|
||||||
import io.element.android.services.analyticsproviders.test.FakeAnalyticsProvider
|
import io.element.android.services.analyticsproviders.test.FakeAnalyticsProvider
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
package io.element.android.services.analytics.impl.store
|
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 io.element.android.tests.testutils.lambda.lambdaError
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue