Add TemporaryMatrixClient interface

This is an abstraction over an actual unauthenticated `Client` from the SDK that implements `GetUrlResolver`, and is supposed to be short-lived.

With this, we can use the SDK network stack to perform arbitrary GET url operations.

The `AutoCloseable` implementation makes it easier to clean up any leftover local config after using this temporary client.
This commit is contained in:
Jorge Martín
2026-08-10 14:19:41 +02:00
committed by Jorge Martin Espinosa
parent d48f5bd8b9
commit 3f19100427
4 changed files with 105 additions and 0 deletions
@@ -0,0 +1,18 @@
/*
* 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
import java.lang.AutoCloseable
/**
* A Matrix client in an 'unauthenticated' state that can still be used to resolve URLs.
*
* Note: this client implements an [AutoCloseable] interface, so using [AutoCloseable.close] or [AutoCloseable.use] will clean up any resources associated
* with it, such as temporary files.
*/
interface TemporaryMatrixClient : GetUrlResolver, AutoCloseable
@@ -0,0 +1,15 @@
/*
* 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
/**
* Factory to create a temporary [TemporaryMatrixClient] for a given home server URL.
*/
interface TemporaryMatrixClientFactory {
suspend fun createTemporaryMatrixClient(homeServerUrl: String): Result<TemporaryMatrixClient>
}
@@ -0,0 +1,36 @@
/*
* 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.impl
import io.element.android.libraries.core.extensions.mapFailure
import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.matrix.api.TemporaryMatrixClient
import io.element.android.libraries.matrix.api.paths.SessionPaths
import io.element.android.libraries.matrix.impl.exception.mapClientException
import org.matrix.rustcomponents.sdk.Client
class RustTemporaryMatrixClient(
private val client: Client,
private val paths: SessionPaths?,
) : TemporaryMatrixClient {
override suspend fun getUrl(url: String): Result<ByteArray> = runCatchingExceptions {
client.getUrl(url)
}.mapFailure { it.mapClientException() }
override fun close() {
client.close()
paths?.let {
if (it.fileDirectory.exists()) {
it.fileDirectory.deleteRecursively()
}
if (it.cacheDirectory.exists()) {
it.cacheDirectory.deleteRecursively()
}
}
}
}
@@ -0,0 +1,36 @@
/*
* 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.impl
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.matrix.api.TemporaryMatrixClientFactory
import io.element.android.libraries.matrix.api.TemporaryMatrixClient
import io.element.android.libraries.matrix.impl.paths.SessionPathsFactory
@ContributesBinding(AppScope::class)
class RustTemporaryMatrixClientFactory(
private val sessionPathsFactory: SessionPathsFactory,
private val rustMatrixClientFactory: RustMatrixClientFactory,
) : TemporaryMatrixClientFactory {
override suspend fun createTemporaryMatrixClient(homeServerUrl: String): Result<TemporaryMatrixClient> {
return runCatchingExceptions {
val sessionPaths = sessionPathsFactory.create()
val client = rustMatrixClientFactory.getBaseClientBuilder(
sessionPaths = sessionPaths,
clientSecret = null,
slidingSyncType = ClientBuilderSlidingSync.Native,
isMessageSearchAvailable = false,
)
.homeserverUrl(homeServerUrl)
.build()
RustTemporaryMatrixClient(client, sessionPaths)
}
}
}