Configure user agent for all network request (#677)
This commit is contained in:
parent
469b54f204
commit
f4b4e4d316
12 changed files with 183 additions and 2 deletions
|
|
@ -34,6 +34,7 @@ dependencies {
|
|||
anvil(projects.anvilcodegen)
|
||||
implementation(projects.libraries.androidutils)
|
||||
implementation(projects.libraries.core)
|
||||
implementation(projects.libraries.network)
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.libraries.designsystem)
|
||||
implementation(projects.libraries.uiStrings)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import io.element.android.libraries.core.extensions.toOnOff
|
|||
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import io.element.android.libraries.network.useragent.UserAgentProvider
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.Call
|
||||
|
|
@ -64,6 +65,7 @@ class DefaultBugReporter @Inject constructor(
|
|||
private val crashDataStore: CrashDataStore,
|
||||
private val coroutineDispatchers: CoroutineDispatchers,
|
||||
private val okHttpClient: Provider<OkHttpClient>,
|
||||
private val userAgentProvider: UserAgentProvider,
|
||||
/*
|
||||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
private val versionProvider: VersionProvider,
|
||||
|
|
@ -222,7 +224,7 @@ class DefaultBugReporter @Inject constructor(
|
|||
val builder = BugReporterMultipartBody.Builder()
|
||||
.addFormDataPart("text", text)
|
||||
.addFormDataPart("app", rageShakeAppNameForReport(reportType))
|
||||
// .addFormDataPart("user_agent", matrix.getUserAgent())
|
||||
.addFormDataPart("user_agent", userAgentProvider.provide())
|
||||
.addFormDataPart("user_id", userId)
|
||||
.addFormDataPart("can_contact", canContact.toString())
|
||||
.addFormDataPart("device_id", deviceId)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ dependencies {
|
|||
implementation(libs.matrix.sdk)
|
||||
implementation(projects.libraries.di)
|
||||
implementation(projects.libraries.androidutils)
|
||||
implementation(projects.libraries.network)
|
||||
implementation(projects.services.toolbox.api)
|
||||
api(projects.libraries.matrix.api)
|
||||
implementation(libs.dagger)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import io.element.android.libraries.matrix.api.auth.MatrixHomeServerDetails
|
|||
import io.element.android.libraries.matrix.api.auth.OidcDetails
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.impl.RustMatrixClient
|
||||
import io.element.android.libraries.network.useragent.UserAgentProvider
|
||||
import io.element.android.libraries.sessionstorage.api.SessionData
|
||||
import io.element.android.libraries.sessionstorage.api.SessionStore
|
||||
import io.element.android.services.toolbox.api.systemclock.SystemClock
|
||||
|
|
@ -56,6 +57,7 @@ class RustMatrixAuthenticationService @Inject constructor(
|
|||
private val coroutineDispatchers: CoroutineDispatchers,
|
||||
private val sessionStore: SessionStore,
|
||||
private val clock: SystemClock,
|
||||
private val userAgentProvider: UserAgentProvider,
|
||||
) : MatrixAuthenticationService {
|
||||
|
||||
private val authService: RustAuthenticationService = RustAuthenticationService(
|
||||
|
|
@ -84,6 +86,7 @@ class RustMatrixAuthenticationService @Inject constructor(
|
|||
.basePath(baseDirectory.absolutePath)
|
||||
.homeserverUrl(sessionData.homeserverUrl)
|
||||
.username(sessionData.userId)
|
||||
.userAgent(userAgentProvider.provide())
|
||||
.use { it.build() }
|
||||
client.restoreSession(sessionData.toSession())
|
||||
createMatrixClient(client)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import io.element.android.libraries.core.meta.BuildMeta
|
|||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.SingleIn
|
||||
import io.element.android.libraries.network.interceptors.FormattedJsonHttpLogger
|
||||
import io.element.android.libraries.network.interceptors.UserAgentInterceptor
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
|
|
@ -35,10 +36,12 @@ object NetworkModule {
|
|||
@SingleIn(AppScope::class)
|
||||
fun providesOkHttpClient(
|
||||
buildMeta: BuildMeta,
|
||||
userAgentInterceptor: UserAgentInterceptor,
|
||||
): OkHttpClient = OkHttpClient.Builder().apply {
|
||||
connectTimeout(30, TimeUnit.SECONDS)
|
||||
readTimeout(60, TimeUnit.SECONDS)
|
||||
writeTimeout(60, TimeUnit.SECONDS)
|
||||
addInterceptor(userAgentInterceptor)
|
||||
if (buildMeta.isDebuggable) addInterceptor(providesHttpLoggingInterceptor())
|
||||
}.build()
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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.libraries.network.headers
|
||||
|
||||
internal object HttpHeaders {
|
||||
const val Authorization = "Authorization"
|
||||
const val UserAgent = "User-Agent"
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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.libraries.network.interceptors
|
||||
|
||||
import io.element.android.libraries.network.headers.HttpHeaders
|
||||
import io.element.android.libraries.network.useragent.UserAgentProvider
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
class UserAgentInterceptor @Inject constructor(
|
||||
private val userAgentProvider: UserAgentProvider,
|
||||
) : Interceptor {
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val newRequest = chain.request()
|
||||
.newBuilder()
|
||||
.header(HttpHeaders.UserAgent, userAgentProvider.provide())
|
||||
.build()
|
||||
return chain.proceed(newRequest)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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.libraries.network.useragent
|
||||
|
||||
import android.os.Build
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.SingleIn
|
||||
import javax.inject.Inject
|
||||
|
||||
@SingleIn(AppScope::class)
|
||||
@ContributesBinding(AppScope::class)
|
||||
class DefaultUserAgentProvider @Inject constructor(
|
||||
private val buildMeta: BuildMeta,
|
||||
) : UserAgentProvider {
|
||||
private val userAgent: String by lazy { buildUserAgent() }
|
||||
|
||||
override fun provide(): String = userAgent
|
||||
|
||||
/**
|
||||
* Create an user agent with the application version.
|
||||
* Ex: Element X/1.5.0 (Xiaomi Mi 9T; Android 11; RKQ1.200826.002; Sdk 0.1.0)
|
||||
*/
|
||||
private fun buildUserAgent(): String {
|
||||
val appName = buildMeta.applicationName
|
||||
val appVersion = buildMeta.versionName
|
||||
val deviceManufacturer = Build.MANUFACTURER
|
||||
val deviceModel = Build.MODEL
|
||||
val androidVersion = Build.VERSION.RELEASE
|
||||
val deviceBuildId = Build.DISPLAY
|
||||
val matrixSdkVersion = "TODO"
|
||||
|
||||
return buildString {
|
||||
append(appName)
|
||||
append("/")
|
||||
append(appVersion)
|
||||
append(" (")
|
||||
append(deviceManufacturer)
|
||||
append(" ")
|
||||
append(deviceModel)
|
||||
append("; ")
|
||||
append("Android ")
|
||||
append(androidVersion)
|
||||
append("; ")
|
||||
append(deviceBuildId)
|
||||
append("; ")
|
||||
append("Sdk ")
|
||||
append(matrixSdkVersion)
|
||||
append(")")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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.libraries.network.useragent
|
||||
|
||||
class SimpleUserAgentProvider(
|
||||
private val userAgent: String = "User agent"
|
||||
) : UserAgentProvider {
|
||||
override fun provide(): String = userAgent
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2023 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.libraries.network.useragent
|
||||
|
||||
interface UserAgentProvider {
|
||||
fun provide(): String
|
||||
}
|
||||
|
|
@ -54,6 +54,7 @@ dependencies {
|
|||
implementation(projects.libraries.designsystem)
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.libraries.core)
|
||||
implementation(projects.libraries.network)
|
||||
implementation(projects.libraries.dateformatter.impl)
|
||||
implementation(projects.libraries.eventformatter.impl)
|
||||
implementation(projects.features.invitelist.impl)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import androidx.core.view.WindowCompat
|
|||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
||||
import io.element.android.libraries.matrix.impl.auth.RustMatrixAuthenticationService
|
||||
import io.element.android.libraries.network.useragent.SimpleUserAgentProvider
|
||||
import io.element.android.libraries.sessionstorage.impl.memory.InMemorySessionStore
|
||||
import io.element.android.services.toolbox.impl.systemclock.DefaultSystemClock
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
|
@ -45,7 +46,8 @@ class MainActivity : ComponentActivity() {
|
|||
appCoroutineScope = Singleton.appScope,
|
||||
coroutineDispatchers = Singleton.coroutineDispatchers,
|
||||
sessionStore = InMemorySessionStore(),
|
||||
clock = DefaultSystemClock()
|
||||
clock = DefaultSystemClock(),
|
||||
userAgentProvider = SimpleUserAgentProvider("MinimalSample")
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue