diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index 836459f8c7..8f482440e8 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.api.media.MediaPreviewService import io.element.android.libraries.matrix.api.notification.NotificationService import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.oauth.AccountManagementAction +import io.element.android.libraries.matrix.api.paths.SessionPaths import io.element.android.libraries.matrix.api.pusher.PushersService import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.JoinedRoom @@ -53,6 +54,7 @@ import java.util.Optional interface MatrixClient { val sessionId: SessionId val deviceId: DeviceId + val sessionPaths: SessionPaths val userProfile: StateFlow val roomListService: RoomListService val spaceService: SpaceService diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/GetDatabaseSizesUseCase.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/GetDatabaseSizesUseCase.kt index ab11374116..fde02fb2c6 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/GetDatabaseSizesUseCase.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/analytics/GetDatabaseSizesUseCase.kt @@ -10,5 +10,5 @@ package io.element.android.libraries.matrix.api.analytics import io.element.android.libraries.matrix.api.core.SessionId fun interface GetDatabaseSizesUseCase { - suspend operator fun invoke(sessionId: SessionId): Result + operator fun invoke(sessionId: SessionId): Result } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/paths/SessionPaths.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/paths/SessionPaths.kt new file mode 100644 index 0000000000..d481316f9d --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/paths/SessionPaths.kt @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Element Creations 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.paths + +import java.io.File + +data class SessionPaths( + val fileDirectory: File, + val cacheDirectory: File, +) { + fun deleteRecursively() { + fileDirectory.deleteRecursively() + cacheDirectory.deleteRecursively() + } +} 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 bec20aedf2..9167b3e2f3 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 @@ -32,6 +32,7 @@ import io.element.android.libraries.matrix.api.linknewdevice.LinkDesktopHandler import io.element.android.libraries.matrix.api.linknewdevice.LinkMobileHandler import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.oauth.AccountManagementAction +import io.element.android.libraries.matrix.api.paths.SessionPaths import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.JoinedRoom @@ -81,7 +82,6 @@ import io.element.android.libraries.matrix.impl.spaces.RustSpaceService import io.element.android.libraries.matrix.impl.sync.RustSyncService import io.element.android.libraries.matrix.impl.sync.map import io.element.android.libraries.matrix.impl.usersearch.UserSearchResultMapper -import io.element.android.libraries.matrix.impl.util.SessionPathsProvider import io.element.android.libraries.matrix.impl.util.cancelAndDestroy import io.element.android.libraries.matrix.impl.util.mxCallbackFlow import io.element.android.libraries.matrix.impl.verification.RustSessionVerificationService @@ -137,6 +137,7 @@ import org.matrix.rustcomponents.sdk.RoomPreset as RustRoomPreset import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService class RustMatrixClient( + override val sessionPaths: SessionPaths, private val innerClient: Client, private val sessionStore: SessionStore, private val sessionDelegate: RustClientSessionDelegate, @@ -187,8 +188,6 @@ class RustMatrixClient( sessionDispatcher = sessionDispatcher, ) - private val sessionPathsProvider = SessionPathsProvider(sessionStore) - private val roomSyncSubscriber: RoomSyncSubscriber = RoomSyncSubscriber(innerRoomListService, dispatchers) override val roomListService: RoomListService = RustRoomListService( @@ -824,17 +823,16 @@ class RustMatrixClient( private suspend fun getCacheSize( includeCryptoDb: Boolean = false, ): Long = withContext(sessionDispatcher) { - val sessionDirectory = sessionPathsProvider.provides(sessionId) ?: return@withContext 0L - val cacheSize = sessionDirectory.cacheDirectory.getSizeOfFiles() + val cacheSize = sessionPaths.cacheDirectory.getSizeOfFiles() if (includeCryptoDb) { - cacheSize + sessionDirectory.fileDirectory.getSizeOfFiles() + cacheSize + sessionPaths.fileDirectory.getSizeOfFiles() } else { cacheSize + listOf( "matrix-sdk-state.sqlite3", "matrix-sdk-state.sqlite3-shm", "matrix-sdk-state.sqlite3-wal", ).map { fileName -> - File(sessionDirectory.fileDirectory, fileName) + File(sessionPaths.fileDirectory, fileName) }.sumOf { file -> file.length() } @@ -843,7 +841,7 @@ class RustMatrixClient( private suspend fun deleteSessionDirectory() = withContext(sessionDispatcher) { // Delete all the files for this session - sessionPathsProvider.provides(sessionId)?.deleteRecursively() + sessionPaths.deleteRecursively() } private fun scheduleDatabaseVacuum() { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt index 4a91462399..2a90319aad 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt @@ -17,9 +17,9 @@ import io.element.android.libraries.di.CacheDirectory import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.matrix.api.paths.SessionPaths import io.element.android.libraries.matrix.impl.analytics.UtdTracker import io.element.android.libraries.matrix.impl.certificates.UserCertificatesProvider -import io.element.android.libraries.matrix.impl.paths.SessionPaths import io.element.android.libraries.matrix.impl.paths.getSessionPaths import io.element.android.libraries.matrix.impl.proxy.ProxyProvider import io.element.android.libraries.matrix.impl.room.TimelineEventFilterFactory @@ -102,10 +102,10 @@ class RustMatrixClientFactory( client.restoreSession(sessionData.toSession()) - create(client) + create(client, sessionData) } - suspend fun create(client: Client): RustMatrixClient { + suspend fun create(client: Client, sessionData: SessionData): RustMatrixClient { val (anonymizedAccessToken, anonymizedRefreshToken) = client.session().anonymizedTokens() // Must be called before creating the sync service, timelines etc. @@ -121,6 +121,7 @@ class RustMatrixClientFactory( .finish() return RustMatrixClient( + sessionPaths = sessionData.getSessionPaths(), innerClient = client, sessionStore = sessionStore, appCoroutineScope = appCoroutineScope, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultGetDatabaseSizesUseCase.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultGetDatabaseSizesUseCase.kt index 8973483132..8dba525788 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultGetDatabaseSizesUseCase.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/analytics/DefaultGetDatabaseSizesUseCase.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Element Creations Ltd. + * Copyright (c) 2026 Element Creations Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. * Please see LICENSE files in the repository root for full details. @@ -9,19 +9,53 @@ package io.element.android.libraries.matrix.impl.analytics import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.core.data.bytes import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.analytics.GetDatabaseSizesUseCase import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes import io.element.android.libraries.matrix.api.core.SessionId +import java.io.File +import kotlin.math.max +/** + * An implementation of [GetDatabaseSizesUseCase] that manually calculates the database sizes by checking the file system. + * This is not as accurate as the SDK's internal method, but is used as a fallback for Sentry's non-suspendable hook where + * calling the SDK's suspendable method blocks the main thread and causes ANRs. + */ @ContributesBinding(AppScope::class) class DefaultGetDatabaseSizesUseCase( private val clientProvider: Lazy, ) : GetDatabaseSizesUseCase { - override suspend fun invoke(sessionId: SessionId): Result { + override fun invoke(sessionId: SessionId): Result { val client = clientProvider.value.getOrNull(sessionId) ?: return Result.failure(IllegalArgumentException("No MatrixClient for session $sessionId")) - return client.getDatabaseSizes() + val fileDir = client.sessionPaths.fileDirectory + val cacheDir = client.sessionPaths.cacheDirectory + + val cryptoSize = getDatabaseSize(fileDir, "matrix-sdk-crypto") + val stateSize = getDatabaseSize(fileDir, "matrix-sdk-state") + + val eventCacheSize = getDatabaseSize(cacheDir, "matrix-sdk-event-cache") + val mediaCacheSize = getDatabaseSize(cacheDir, "matrix-sdk-media") + + return Result.success(SdkStoreSizes( + stateStore = stateSize.bytes, + cryptoStore = cryptoSize.bytes, + eventCacheStore = eventCacheSize.bytes, + mediaStore = mediaCacheSize.bytes, + )) + } + + private fun getDatabaseSize(baseDirectory: File, databaseFileName: String): Long { + // Check the sizes of both the main database file and the -wal file, and return the max of the two: + // The -wal file can contain additional data not yet merged into the main file, becoming larger than it. + val databaseFile = File(baseDirectory, "$databaseFileName.sqlite3") + val walFile = File(baseDirectory, "$databaseFileName.sqlite3-wal") + + val databaseSize = if (databaseFile.exists()) databaseFile.length() else 0L + val walSize = if (walFile.exists()) walFile.length() else 0L + + return max(databaseSize, walSize) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt index c44f7ffae7..639031334e 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt @@ -29,6 +29,7 @@ import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginDat import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.paths.SessionPaths import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus import io.element.android.libraries.matrix.impl.ClientBuilderSlidingSync import io.element.android.libraries.matrix.impl.RustMatrixClientFactory @@ -38,7 +39,6 @@ import io.element.android.libraries.matrix.impl.auth.qrlogin.toStep import io.element.android.libraries.matrix.impl.exception.mapClientException import io.element.android.libraries.matrix.impl.keys.SecretGenerator import io.element.android.libraries.matrix.impl.mapper.toSessionData -import io.element.android.libraries.matrix.impl.paths.SessionPaths import io.element.android.libraries.matrix.impl.paths.SessionPathsFactory import io.element.android.libraries.matrix.impl.toSession import io.element.android.libraries.sessionstorage.api.LoginType @@ -160,7 +160,7 @@ class RustMatrixAuthenticationService( passphrase = pendingKey.formattedAsString(), sessionPaths = currentSessionPaths, ) - val matrixClient = rustMatrixClientFactory.create(client) + val matrixClient = rustMatrixClientFactory.create(client, sessionData) newMatrixClientObservers.forEach { it.invoke(matrixClient) } sessionStore.addSession(sessionData) @@ -235,7 +235,7 @@ class RustMatrixAuthenticationService( // We restore the client using the just retrieved session data client.restoreSession(sessionData.toSession()) - val matrixClient = rustMatrixClientFactory.create(client) + val matrixClient = rustMatrixClientFactory.create(client, sessionData) // We wait for the verification state to be known matrixClient.waitForKnownVerificationState() @@ -325,7 +325,7 @@ class RustMatrixAuthenticationService( passphrase = pendingKey.formattedAsString(), sessionPaths = currentSessionPaths, ) - val matrixClient = rustMatrixClientFactory.create(client) + val matrixClient = rustMatrixClientFactory.create(client, sessionData) matrixClient.waitForKnownVerificationState() newMatrixClientObservers.forEach { it.invoke(matrixClient) } @@ -390,7 +390,7 @@ class RustMatrixAuthenticationService( passphrase = pendingKey.formattedAsString(), sessionPaths = emptySessionPaths, ) - val matrixClient = rustMatrixClientFactory.create(client) + val matrixClient = rustMatrixClientFactory.create(client, sessionData) newMatrixClientObservers.forEach { it.invoke(matrixClient) } sessionStore.addSession(sessionData) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/mapper/Session.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/mapper/Session.kt index dfda37d7e1..b5964f1a2e 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/mapper/Session.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/mapper/Session.kt @@ -9,7 +9,7 @@ package io.element.android.libraries.matrix.impl.mapper import io.element.android.libraries.matrix.api.auth.external.ExternalSession -import io.element.android.libraries.matrix.impl.paths.SessionPaths +import io.element.android.libraries.matrix.api.paths.SessionPaths import io.element.android.libraries.sessionstorage.api.LoginType import io.element.android.libraries.sessionstorage.api.SessionData import org.matrix.rustcomponents.sdk.Session diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/paths/SessionPaths.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/paths/SessionPaths.kt index 1888cd0f88..8a2403f772 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/paths/SessionPaths.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/paths/SessionPaths.kt @@ -8,19 +8,10 @@ package io.element.android.libraries.matrix.impl.paths +import io.element.android.libraries.matrix.api.paths.SessionPaths import io.element.android.libraries.sessionstorage.api.SessionData import java.io.File -data class SessionPaths( - val fileDirectory: File, - val cacheDirectory: File, -) { - fun deleteRecursively() { - fileDirectory.deleteRecursively() - cacheDirectory.deleteRecursively() - } -} - internal fun SessionData.getSessionPaths(): SessionPaths { return SessionPaths( fileDirectory = File(sessionPath), diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/paths/SessionPathsFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/paths/SessionPathsFactory.kt index d2e519fa9e..f40c134209 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/paths/SessionPathsFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/paths/SessionPathsFactory.kt @@ -11,6 +11,7 @@ package io.element.android.libraries.matrix.impl.paths import dev.zacsweers.metro.Inject import io.element.android.libraries.di.BaseDirectory import io.element.android.libraries.di.CacheDirectory +import io.element.android.libraries.matrix.api.paths.SessionPaths import java.io.File import java.util.UUID diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilder.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilder.kt index 3fdfb7a179..4cfcf1a95e 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilder.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilder.kt @@ -10,7 +10,7 @@ package io.element.android.libraries.matrix.impl.storage import io.element.android.libraries.androidutils.crypto.ClientSecret import io.element.android.libraries.core.data.ByteUnit import io.element.android.libraries.core.data.megaBytes -import io.element.android.libraries.matrix.impl.paths.SessionPaths +import io.element.android.libraries.matrix.api.paths.SessionPaths import org.matrix.rustcomponents.sdk.ClientBuilder import org.matrix.rustcomponents.sdk.SqliteStoreBuilder as SdkSqliteStoreBuilder diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilderProvider.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilderProvider.kt index 29a30f3c56..5d79e72403 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilderProvider.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/storage/SqliteStoreBuilderProvider.kt @@ -9,7 +9,7 @@ package io.element.android.libraries.matrix.impl.storage import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding -import io.element.android.libraries.matrix.impl.paths.SessionPaths +import io.element.android.libraries.matrix.api.paths.SessionPaths interface SqliteStoreBuilderProvider { fun provide(sessionPaths: SessionPaths): SqliteStoreBuilder diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionPathsProvider.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionPathsProvider.kt deleted file mode 100644 index 0030c6e23e..0000000000 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionPathsProvider.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2024, 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.libraries.matrix.impl.util - -import io.element.android.libraries.matrix.api.core.SessionId -import io.element.android.libraries.matrix.impl.paths.SessionPaths -import io.element.android.libraries.matrix.impl.paths.getSessionPaths -import io.element.android.libraries.sessionstorage.api.SessionStore - -class SessionPathsProvider( - private val sessionStore: SessionStore, -) { - suspend fun provides(sessionId: SessionId): SessionPaths? { - val sessionData = sessionStore.getSession(sessionId.value) ?: return null - return sessionData.getSessionPaths() - } -} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt index ed8440fe53..a8e812d031 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientTest.kt @@ -13,6 +13,7 @@ package io.element.android.libraries.matrix.impl import com.google.common.truth.Truth.assertThat import io.element.android.libraries.core.data.bytes import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.libraries.matrix.api.paths.SessionPaths import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClient import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiSyncService import io.element.android.libraries.matrix.impl.room.FakeTimelineEventFilterFactory @@ -141,6 +142,7 @@ class RustMatrixClientTest { ), ) = RustMatrixClient( innerClient = client, + sessionPaths = SessionPaths(fileDirectory = File("files"), cacheDirectory = File("cache")), sessionStore = sessionStore, appCoroutineScope = backgroundScope, sessionDelegate = aRustClientSessionDelegate( diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/mapper/SessionKtTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/mapper/SessionKtTest.kt index fb9ec6625b..6042f195f8 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/mapper/SessionKtTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/mapper/SessionKtTest.kt @@ -10,8 +10,8 @@ package io.element.android.libraries.matrix.impl.mapper import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.auth.external.ExternalSession +import io.element.android.libraries.matrix.api.paths.SessionPaths import io.element.android.libraries.matrix.impl.fixtures.factories.aRustSession -import io.element.android.libraries.matrix.impl.paths.SessionPaths import io.element.android.libraries.matrix.test.A_DEVICE_ID import io.element.android.libraries.matrix.test.A_HOMESERVER_URL import io.element.android.libraries.matrix.test.A_HOMESERVER_URL_2 diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilderProvider.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilderProvider.kt index b196604ca4..af68da7b8a 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilderProvider.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/storage/FakeSqliteStoreBuilderProvider.kt @@ -7,7 +7,7 @@ package io.element.android.libraries.matrix.impl.storage -import io.element.android.libraries.matrix.impl.paths.SessionPaths +import io.element.android.libraries.matrix.api.paths.SessionPaths class FakeSqliteStoreBuilderProvider : SqliteStoreBuilderProvider { override fun provide(sessionPaths: SessionPaths): SqliteStoreBuilder { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/util/SessionPathsProviderTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/util/SessionPathsProviderTest.kt deleted file mode 100644 index 8edc95cdc6..0000000000 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/util/SessionPathsProviderTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2024, 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.libraries.matrix.impl.util - -import com.google.common.truth.Truth.assertThat -import io.element.android.libraries.matrix.test.A_SESSION_ID -import io.element.android.libraries.sessionstorage.test.InMemorySessionStore -import io.element.android.libraries.sessionstorage.test.aSessionData -import kotlinx.coroutines.test.runTest -import org.junit.Test - -class SessionPathsProviderTest { - @Test - fun `if session is not found, provides returns null`() = runTest { - val sut = SessionPathsProvider(InMemorySessionStore()) - val result = sut.provides(A_SESSION_ID) - assertThat(result).isNull() - } - - @Test - fun `if session is found, provides returns the data`() = runTest { - val store = InMemorySessionStore( - initialList = listOf( - aSessionData( - sessionPath = "/a/path/to/a/session", - cachePath = "/a/path/to/a/cache", - ) - ) - ) - val sut = SessionPathsProvider(store) - val result = sut.provides(A_SESSION_ID)!! - assertThat(result.fileDirectory.absolutePath).isEqualTo("/a/path/to/a/session") - assertThat(result.cacheDirectory.absolutePath).isEqualTo("/a/path/to/a/cache") - } -} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 3278eae855..cce99e9d09 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.api.media.MediaPreviewService import io.element.android.libraries.matrix.api.notification.NotificationService import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.oauth.AccountManagementAction +import io.element.android.libraries.matrix.api.paths.SessionPaths import io.element.android.libraries.matrix.api.pusher.PushersService import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.JoinedRoom @@ -66,10 +67,12 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.TestScope +import java.io.File import java.util.Optional class FakeMatrixClient( override val sessionId: SessionId = A_SESSION_ID, + override val sessionPaths: SessionPaths = SessionPaths(fileDirectory = File("files"), cacheDirectory = File("cache")), override val deviceId: DeviceId = A_DEVICE_ID, override val sessionCoroutineScope: CoroutineScope = TestScope(), private val userDisplayName: String? = A_USER_NAME, diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt index 0843c97a78..4e4f08b632 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsProvider.kt @@ -33,7 +33,6 @@ import io.sentry.Sentry import io.sentry.SentryOptions import io.sentry.android.core.SentryAndroid import io.sentry.protocol.SentryTransaction -import kotlinx.coroutines.runBlocking import timber.log.Timber @ContributesIntoSet(AppScope::class) @@ -132,7 +131,7 @@ class SentryAnalyticsProvider( if (sessionId != null) { // This runs in a separate thread, so although using `runBlocking` is not great, at least it shouldn't freeze the app // Also, the method is fairly quick, so the blocking shouldn't take longer than a few ms - val databaseSizes = runBlocking { getDatabaseSizesUseCase(sessionId) }.getOrNull() + val databaseSizes = getDatabaseSizesUseCase(sessionId).getOrNull() databaseSizes?.stateStore?.let { transaction.setExtra(AnalyticsUserData.STATE_STORE_SIZE, it.into(ByteUnit.MB)) } databaseSizes?.eventCacheStore?.let { transaction.setExtra(AnalyticsUserData.EVENT_CACHE_SIZE, it.into(ByteUnit.MB)) }