Fix ANRs when calculating DB sizes for Sentry (#7017)
* Fix ANRs when calculating DB sizes for Sentry Instead of using the SDK's `Client.getStoreSizes()` method, manually check the sizes using the file system. For this, the `SessionPaths` need to be synchronously accessible from a `MatrixClient`. I removed `SessionPathsProvider` too since it's not needed anymore.
This commit is contained in:
committed by
GitHub
parent
8e9c0bedf2
commit
ac93044f49
+2
@@ -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<MatrixUser>
|
||||
val roomListService: RoomListService
|
||||
val spaceService: SpaceService
|
||||
|
||||
+1
-1
@@ -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<SdkStoreSizes>
|
||||
operator fun invoke(sessionId: SessionId): Result<SdkStoreSizes>
|
||||
}
|
||||
|
||||
+20
@@ -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()
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -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() {
|
||||
|
||||
+4
-3
@@ -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,
|
||||
|
||||
+37
-3
@@ -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<MatrixClientProvider>,
|
||||
) : GetDatabaseSizesUseCase {
|
||||
override suspend fun invoke(sessionId: SessionId): Result<SdkStoreSizes> {
|
||||
override fun invoke(sessionId: SessionId): Result<SdkStoreSizes> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -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)
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-10
@@ -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),
|
||||
|
||||
+1
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-23
@@ -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()
|
||||
}
|
||||
}
|
||||
+2
@@ -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(
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
-41
@@ -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")
|
||||
}
|
||||
}
|
||||
+3
@@ -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,
|
||||
|
||||
+1
-2
@@ -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)) }
|
||||
|
||||
Reference in New Issue
Block a user