diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06.kt new file mode 100644 index 0000000000..6672ae1f8a --- /dev/null +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration06.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.migration.impl.migrations + +import com.squareup.anvil.annotations.ContributesMultibinding +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.di.CacheDirectory +import io.element.android.libraries.sessionstorage.api.SessionStore +import java.io.File +import javax.inject.Inject + +/** + * Create the cache directory for the existing sessions. + */ +@ContributesMultibinding(AppScope::class) +class AppMigration06 @Inject constructor( + private val sessionStore: SessionStore, + @CacheDirectory private val cacheDirectory: File, +) : AppMigration { + override val order: Int = 6 + + override suspend fun migrate() { + val allSessions = sessionStore.getAllSessions() + for (session in allSessions) { + if (session.cachePath.isEmpty()) { + val sessionFile = File(session.sessionPath) + val sessionFolder = sessionFile.name + val cachePath = File(cacheDirectory, sessionFolder).absolutePath + sessionStore.updateData(session.copy(cachePath = cachePath)) + } + } + } +} diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt index fa78a164b1..18e78fb212 100755 --- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt +++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt @@ -289,6 +289,7 @@ class DefaultBugReporterTest { slidingSyncProxy = null, passphrase = null, sessionPath = "session", + cachePath = "cache", ) @Test fun `test sendBugReport error`() = runTest { diff --git a/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutStateProvider.kt b/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutStateProvider.kt index bd303f7945..33cbcd8f66 100644 --- a/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutStateProvider.kt +++ b/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutStateProvider.kt @@ -52,5 +52,6 @@ fun aSessionData( loginType = LoginType.UNKNOWN, passphrase = null, sessionPath = "/a/path/to/a/session", + cachePath = "/a/path/to/a/cache", ) } 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 3aab5bebed..f346100de1 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 @@ -56,6 +56,7 @@ import io.element.android.libraries.matrix.impl.media.RustMediaLoader import io.element.android.libraries.matrix.impl.notification.RustNotificationService import io.element.android.libraries.matrix.impl.notificationsettings.RustNotificationSettingsService import io.element.android.libraries.matrix.impl.oidc.toRustAction +import io.element.android.libraries.matrix.impl.paths.getSessionPaths import io.element.android.libraries.matrix.impl.pushers.RustPushersService import io.element.android.libraries.matrix.impl.room.RoomContentForwarder import io.element.android.libraries.matrix.impl.room.RoomSyncSubscriber @@ -67,7 +68,7 @@ import io.element.android.libraries.matrix.impl.roomlist.RustRoomListService import io.element.android.libraries.matrix.impl.sync.RustSyncService import io.element.android.libraries.matrix.impl.usersearch.UserProfileMapper import io.element.android.libraries.matrix.impl.usersearch.UserSearchResultMapper -import io.element.android.libraries.matrix.impl.util.SessionDirectoryProvider +import io.element.android.libraries.matrix.impl.util.SessionPathsProvider import io.element.android.libraries.matrix.impl.util.anonymizedTokens import io.element.android.libraries.matrix.impl.util.cancelAndDestroy import io.element.android.libraries.matrix.impl.util.mxCallbackFlow @@ -161,7 +162,7 @@ class RustMatrixClient( sessionDispatcher = sessionDispatcher, ) - private val sessionDirectoryProvider = SessionDirectoryProvider(sessionStore) + private val sessionPathsProvider = SessionPathsProvider(sessionStore) private val isLoggingOut = AtomicBoolean(false) @@ -186,7 +187,7 @@ class RustMatrixClient( isTokenValid = false, loginType = existingData.loginType, passphrase = existingData.passphrase, - sessionPath = existingData.sessionPath, + sessionPaths = existingData.getSessionPaths(), ) sessionStore.updateData(newData) clientLog.d("Removed session data with access token: '$anonymizedAccessToken'.") @@ -217,7 +218,7 @@ class RustMatrixClient( isTokenValid = true, loginType = existingData.loginType, passphrase = existingData.passphrase, - sessionPath = existingData.sessionPath, + sessionPaths = existingData.getSessionPaths(), ) sessionStore.updateData(newData) clientLog.d("Saved new session data with access token: '$anonymizedAccessToken'.") @@ -617,16 +618,17 @@ class RustMatrixClient( private suspend fun File.getCacheSize( includeCryptoDb: Boolean = false, ): Long = withContext(sessionDispatcher) { - val sessionDirectory = sessionDirectoryProvider.provides(sessionId) ?: return@withContext 0L + val sessionDirectory = sessionPathsProvider.provides(sessionId) ?: return@withContext 0L + val cacheSize = sessionDirectory.cacheDirectory.getSizeOfFiles() if (includeCryptoDb) { - sessionDirectory.getSizeOfFiles() + cacheSize + sessionDirectory.fileDirectory.getSizeOfFiles() } else { - listOf( + cacheSize + listOf( "matrix-sdk-state.sqlite3", "matrix-sdk-state.sqlite3-shm", "matrix-sdk-state.sqlite3-wal", ).map { fileName -> - File(sessionDirectory, fileName) + File(sessionDirectory.fileDirectory, fileName) }.sumOf { file -> file.length() } @@ -636,13 +638,15 @@ class RustMatrixClient( private suspend fun deleteSessionDirectory( deleteCryptoDb: Boolean = false, ): Boolean = withContext(sessionDispatcher) { - val sessionDirectory = sessionDirectoryProvider.provides(sessionId) ?: return@withContext false + val sessionPaths = sessionPathsProvider.provides(sessionId) ?: return@withContext false + // Always delete the cache directory + sessionPaths.cacheDirectory.deleteRecursively() if (deleteCryptoDb) { // Delete the folder and all its content - sessionDirectory.deleteRecursively() + sessionPaths.fileDirectory.deleteRecursively() } else { // Delete only the state.db file - sessionDirectory.listFiles().orEmpty() + sessionPaths.fileDirectory.listFiles().orEmpty() .filter { it.name.contains("matrix-sdk-state") } .forEach { file -> Timber.w("Deleting file ${file.name}...") 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 a3304dc5bf..2dfb215116 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 @@ -20,6 +20,8 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.di.CacheDirectory 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.util.anonymizedTokens import io.element.android.libraries.network.useragent.UserAgentProvider @@ -52,7 +54,7 @@ class RustMatrixClientFactory @Inject constructor( ) { suspend fun create(sessionData: SessionData): RustMatrixClient = withContext(coroutineDispatchers.io) { val client = getBaseClientBuilder( - sessionPath = sessionData.sessionPath, + sessionPaths = sessionData.getSessionPaths(), passphrase = sessionData.passphrase, slidingSync = if (appPreferencesStore.isSimplifiedSlidingSyncEnabledFlow().first()) { ClientBuilderSlidingSync.Simplified @@ -87,14 +89,16 @@ class RustMatrixClientFactory @Inject constructor( } internal fun getBaseClientBuilder( - sessionPath: String, + sessionPaths: SessionPaths, passphrase: String?, slidingSyncProxy: String? = null, slidingSync: ClientBuilderSlidingSync, ): ClientBuilder { return ClientBuilder() - // TODO SDK claims it's valid to use the same path for data and cache, but would be better to use different paths - .sessionPaths(dataPath = sessionPath, cachePath = sessionPath) + .sessionPaths( + dataPath = sessionPaths.fileDirectory.absolutePath, + cachePath = sessionPaths.cacheDirectory.absolutePath, + ) .passphrase(passphrase) .slidingSyncProxy(slidingSyncProxy) .userAgent(userAgentProvider.provide()) 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 b447dd584b..c373172b31 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 @@ -21,6 +21,7 @@ import io.element.android.appconfig.AuthenticationConfig import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.core.extensions.mapFailure import io.element.android.libraries.di.AppScope +import io.element.android.libraries.di.CacheDirectory import io.element.android.libraries.di.SingleIn import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService @@ -31,6 +32,7 @@ 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.impl.ClientBuilderSlidingSync import io.element.android.libraries.matrix.impl.RustMatrixClientFactory +import io.element.android.libraries.matrix.impl.paths.SessionPaths import io.element.android.libraries.matrix.impl.auth.qrlogin.QrErrorMapper import io.element.android.libraries.matrix.impl.auth.qrlogin.SdkQrCodeLoginData import io.element.android.libraries.matrix.impl.auth.qrlogin.toStep @@ -61,6 +63,7 @@ import javax.inject.Inject @SingleIn(AppScope::class) class RustMatrixAuthenticationService @Inject constructor( private val baseDirectory: File, + @CacheDirectory private val cacheDirectory: File, private val coroutineDispatchers: CoroutineDispatchers, private val sessionStore: SessionStore, private val rustMatrixClientFactory: RustMatrixClientFactory, @@ -73,14 +76,18 @@ class RustMatrixAuthenticationService @Inject constructor( // Need to keep a copy of the current session path to eventually delete it. // Ideally it would be possible to get the sessionPath from the Client to avoid doing this. - private var sessionPath: File? = null + private var sessionPaths: SessionPaths? = null private var currentClient: Client? = null private var currentHomeserver = MutableStateFlow(null) - private fun rotateSessionPath(): File { - sessionPath?.deleteRecursively() - return File(baseDirectory, UUID.randomUUID().toString()) - .also { sessionPath = it } + private fun rotateSessionPath(): SessionPaths { + sessionPaths?.deleteRecursively() + val subPath = UUID.randomUUID().toString() + return SessionPaths( + fileDirectory = File(baseDirectory, subPath), + cacheDirectory = File(cacheDirectory, subPath), + ) + .also { sessionPaths = it } } override fun loggedInStateFlow(): Flow { @@ -145,14 +152,14 @@ class RustMatrixAuthenticationService @Inject constructor( withContext(coroutineDispatchers.io) { runCatching { val client = currentClient ?: error("You need to call `setHomeserver()` first") - val currentSessionPath = sessionPath ?: error("You need to call `setHomeserver()` first") + val currentSessionPaths = sessionPaths ?: error("You need to call `setHomeserver()` first") client.login(username, password, "Element X Android", null) val sessionData = client.session() .toSessionData( isTokenValid = true, loginType = LoginType.PASSWORD, passphrase = pendingPassphrase, - sessionPath = currentSessionPath.absolutePath, + sessionPaths = currentSessionPaths, ) clear() sessionStore.storeData(sessionData) @@ -196,14 +203,14 @@ class RustMatrixAuthenticationService @Inject constructor( return withContext(coroutineDispatchers.io) { runCatching { val client = currentClient ?: error("You need to call `setHomeserver()` first") - val currentSessionPath = sessionPath ?: error("You need to call `setHomeserver()` first") + val currentSessionPaths = sessionPaths ?: error("You need to call `setHomeserver()` first") val urlForOidcLogin = pendingOidcAuthorizationData ?: error("You need to call `getOidcUrl()` first") client.loginWithOidcCallback(urlForOidcLogin, callbackUrl) val sessionData = client.session().toSessionData( isTokenValid = true, loginType = LoginType.OIDC, passphrase = pendingPassphrase, - sessionPath = currentSessionPath.absolutePath, + sessionPaths = currentSessionPaths, ) clear() pendingOidcAuthorizationData?.close() @@ -218,10 +225,10 @@ class RustMatrixAuthenticationService @Inject constructor( override suspend fun loginWithQrCode(qrCodeData: MatrixQrCodeLoginData, progress: (QrCodeLoginStep) -> Unit) = withContext(coroutineDispatchers.io) { - val emptySessionPath = rotateSessionPath() + val emptySessionPaths = rotateSessionPath() runCatching { val client = rustMatrixClientFactory.getBaseClientBuilder( - sessionPath = emptySessionPath.absolutePath, + sessionPaths = emptySessionPaths, passphrase = pendingPassphrase, slidingSyncProxy = AuthenticationConfig.SLIDING_SYNC_PROXY_URL, slidingSync = ClientBuilderSlidingSync.Discovered, @@ -242,7 +249,7 @@ class RustMatrixAuthenticationService @Inject constructor( isTokenValid = true, loginType = LoginType.QR, passphrase = pendingPassphrase, - sessionPath = emptySessionPath.absolutePath, + sessionPaths = emptySessionPaths, ) sessionStore.storeData(sessionData) SessionId(sessionData.userId) @@ -262,10 +269,10 @@ class RustMatrixAuthenticationService @Inject constructor( } private fun getBaseClientBuilder( - sessionPath: File, + sessionPaths: SessionPaths, ) = rustMatrixClientFactory .getBaseClientBuilder( - sessionPath = sessionPath.absolutePath, + sessionPaths = sessionPaths, passphrase = pendingPassphrase, slidingSyncProxy = AuthenticationConfig.SLIDING_SYNC_PROXY_URL, slidingSync = ClientBuilderSlidingSync.Discovered, 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 402f86ce4f..280d76691c 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 @@ -16,6 +16,7 @@ package io.element.android.libraries.matrix.impl.mapper +import io.element.android.libraries.matrix.impl.paths.SessionPaths import io.element.android.libraries.sessionstorage.api.LoginType import io.element.android.libraries.sessionstorage.api.SessionData import org.matrix.rustcomponents.sdk.Session @@ -25,7 +26,7 @@ internal fun Session.toSessionData( isTokenValid: Boolean, loginType: LoginType, passphrase: String?, - sessionPath: String, + sessionPaths: SessionPaths, homeserverUrl: String? = null, ) = SessionData( userId = userId, @@ -39,5 +40,6 @@ internal fun Session.toSessionData( isTokenValid = isTokenValid, loginType = loginType, passphrase = passphrase, - sessionPath = sessionPath, + sessionPath = sessionPaths.fileDirectory.absolutePath, + cachePath = sessionPaths.cacheDirectory.absolutePath, ) 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 new file mode 100644 index 0000000000..0634f3f935 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/paths/SessionPaths.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.matrix.impl.paths + +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), + cacheDirectory = File(cachePath), + ) +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionDirectoryProvider.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionPathsProvider.kt similarity index 70% rename from libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionDirectoryProvider.kt rename to libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionPathsProvider.kt index f9b8edbd8e..63b01f4c88 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionDirectoryProvider.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionPathsProvider.kt @@ -17,15 +17,15 @@ 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 -import java.io.File -import javax.inject.Inject -class SessionDirectoryProvider @Inject constructor( +class SessionPathsProvider( private val sessionStore: SessionStore, ) { - suspend fun provides(sessionId: SessionId): File? { - val path = sessionStore.getSession(sessionId.value)?.sessionPath ?: return null - return File(path) + suspend fun provides(sessionId: SessionId): SessionPaths? { + val sessionData = sessionStore.getSession(sessionId.value) ?: return null + return sessionData.getSessionPaths() } } diff --git a/libraries/session-storage/api/src/main/kotlin/io/element/android/libraries/sessionstorage/api/SessionData.kt b/libraries/session-storage/api/src/main/kotlin/io/element/android/libraries/sessionstorage/api/SessionData.kt index 30f721d68a..71504ff562 100644 --- a/libraries/session-storage/api/src/main/kotlin/io/element/android/libraries/sessionstorage/api/SessionData.kt +++ b/libraries/session-storage/api/src/main/kotlin/io/element/android/libraries/sessionstorage/api/SessionData.kt @@ -44,6 +44,8 @@ data class SessionData( val loginType: LoginType, /** The optional passphrase used to encrypt data in the SDK local store. */ val passphrase: String?, - /** The path to the session data stored in the filesystem. */ + /** The paths to the session data stored in the filesystem. */ val sessionPath: String, + /** The path to the cache data stored for the session in the filesystem. */ + val cachePath: String, ) diff --git a/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/SessionDataMapper.kt b/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/SessionDataMapper.kt index 026c13eadc..1033286807 100644 --- a/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/SessionDataMapper.kt +++ b/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/SessionDataMapper.kt @@ -35,6 +35,7 @@ internal fun SessionData.toDbModel(): DbSessionData { loginType = loginType.name, passphrase = passphrase, sessionPath = sessionPath, + cachePath = cachePath, ) } @@ -52,5 +53,6 @@ internal fun DbSessionData.toApiModel(): SessionData { loginType = LoginType.fromName(loginType ?: LoginType.UNKNOWN.name), passphrase = passphrase, sessionPath = sessionPath, + cachePath = cachePath, ) } diff --git a/libraries/session-storage/impl/src/main/sqldelight/databases/9.db b/libraries/session-storage/impl/src/main/sqldelight/databases/9.db new file mode 100644 index 0000000000..906384dd8e Binary files /dev/null and b/libraries/session-storage/impl/src/main/sqldelight/databases/9.db differ diff --git a/libraries/session-storage/impl/src/main/sqldelight/io/element/android/libraries/matrix/session/SessionData.sq b/libraries/session-storage/impl/src/main/sqldelight/io/element/android/libraries/matrix/session/SessionData.sq index 74f268606a..6e4c817475 100644 --- a/libraries/session-storage/impl/src/main/sqldelight/io/element/android/libraries/matrix/session/SessionData.sq +++ b/libraries/session-storage/impl/src/main/sqldelight/io/element/android/libraries/matrix/session/SessionData.sq @@ -25,7 +25,9 @@ CREATE TABLE SessionData ( -- added in version 5 passphrase TEXT, -- added in version 6 - sessionPath TEXT NOT NULL DEFAULT "" + sessionPath TEXT NOT NULL DEFAULT "", + -- added in version 9 + cachePath TEXT NOT NULL DEFAULT "" ); diff --git a/libraries/session-storage/impl/src/main/sqldelight/migrations/8.sqm b/libraries/session-storage/impl/src/main/sqldelight/migrations/8.sqm new file mode 100644 index 0000000000..02a8d438ed --- /dev/null +++ b/libraries/session-storage/impl/src/main/sqldelight/migrations/8.sqm @@ -0,0 +1,4 @@ +-- Migrate DB from version 8 +-- Add cachePath so we can track the anonymized path for the session cache dir + +ALTER TABLE SessionData ADD COLUMN cachePath TEXT NOT NULL DEFAULT ""; diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt index cab4c09660..68273a088e 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt @@ -50,6 +50,7 @@ class MainActivity : ComponentActivity() { val proxyProvider = NoOpProxyProvider() RustMatrixAuthenticationService( baseDirectory = baseDirectory, + cacheDirectory = applicationContext.cacheDir, coroutineDispatchers = Singleton.coroutineDispatchers, sessionStore = sessionStore, rustMatrixClientFactory = RustMatrixClientFactory(