Initial content scanner integration (#7139)

* Create a `ContentScanner` component:

- Add `:features:contentscanner:api` module with the interface.
- Implement the concrete component using the Rust SDK in `:libraries:matrix:impl`.

This can be used to both set up the content scanner media fetching in the SDK Client and manually scanning media sources from the Android side

* Create `ContentScannerUrlProvider` in a new `:features:contentscaner:api` module as a noop implementation

Use it as a placeholder for the code to instantiate a `RustContentScanner` with the fetched URL and set it as part of the SDK client.

* Expose the optional `ContentScanner` in the `@SessionScope`

* Split the storage part of the Element well-known retriever so it can be reused for the non-session bound retriever.

Also add the new `content_scanner_url` field to it.

This will be used by the enterprise code to fetch the actual content scanner url.

* Bump enterprise commit to have access to the actual content scanner url provider implementation

* Fix tests and lint issues

* Use the right namespace for `:features:contentscanner:api`, also use the right namespace for `impl`

---------

Co-authored-by: Benoit Marty <benoitm@element.io>
This commit is contained in:
Jorge Martin Espinosa
2026-07-08 09:50:22 +02:00
committed by GitHub
parent 7c3d1e2e80
commit 885e042c12
33 changed files with 988 additions and 74 deletions
@@ -16,6 +16,7 @@ import dev.zacsweers.metro.SingleIn
import io.element.android.libraries.network.interceptors.DynamicHttpLoggingInterceptor
import io.element.android.libraries.network.interceptors.FormattedJsonHttpLogger
import io.element.android.libraries.network.interceptors.UserAgentInterceptor
import okhttp3.Call
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import java.util.concurrent.TimeUnit
@@ -36,6 +37,9 @@ object NetworkModule {
addInterceptor(dynamicHttpLoggingInterceptor)
}.build()
@Provides
fun providesCallFactory(okHttpClient: OkHttpClient): Call.Factory = Call.Factory { request -> okHttpClient.newCall(request) }
@Provides
@SingleIn(AppScope::class)
fun providesHttpLoggingInterceptor(): HttpLoggingInterceptor {
@@ -11,19 +11,19 @@ package io.element.android.libraries.network
import dev.zacsweers.metro.Inject
import io.element.android.libraries.androidutils.json.JsonProvider
import io.element.android.libraries.core.uri.ensureTrailingSlash
import okhttp3.Call
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.kotlinx.serialization.asConverterFactory
@Inject
class RetrofitFactory(
private val okHttpClient: () -> OkHttpClient,
private val callFactory: () -> Call.Factory,
private val json: () -> JsonProvider,
) {
fun create(baseUrl: String): Retrofit = Retrofit.Builder()
.baseUrl(baseUrl.ensureTrailingSlash())
.addConverterFactory(json()().asConverterFactory("application/json".toMediaType()))
.callFactory { request -> okHttpClient().newCall(request) }
.callFactory(callFactory())
.build()
}