diff --git a/app/src/main/java/im/vector/riotredesign/Riot.kt b/app/src/main/java/im/vector/riotredesign/Riot.kt
index 9332eec737..73b7e150cf 100644
--- a/app/src/main/java/im/vector/riotredesign/Riot.kt
+++ b/app/src/main/java/im/vector/riotredesign/Riot.kt
@@ -23,7 +23,7 @@ import com.facebook.stetho.Stetho
import com.github.piasy.biv.BigImageViewer
import com.github.piasy.biv.loader.glide.GlideImageLoader
import com.jakewharton.threetenabp.AndroidThreeTen
-import im.vector.matrix.android.BuildConfig
+import im.vector.matrix.android.api.Matrix
import im.vector.riotredesign.core.di.AppModule
import im.vector.riotredesign.features.home.HomeModule
import org.koin.log.EmptyLogger
@@ -44,6 +44,8 @@ class Riot : Application() {
val appModule = AppModule(applicationContext).definition
val homeModule = HomeModule().definition
startKoin(listOf(appModule, homeModule), logger = EmptyLogger())
+
+ Matrix.getInstance().setApplicationFlavor(BuildConfig.FLAVOR_DESCRIPTION)
}
override fun attachBaseContext(base: Context) {
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index 3d1c7e1397..9b5c1c8662 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -30,10 +30,25 @@ android {
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ resValue "string", "git_sdk_revision", "\"${gitRevision()}\""
+ resValue "string", "git_sdk_revision_unix_date", "\"${gitRevisionUnixDate()}\""
+ resValue "string", "git_sdk_revision_date", "\"${gitRevisionDate()}\""
}
buildTypes {
+
+ debug {
+ // Set to true to log privacy or sensible data, such as token
+ buildConfigField "boolean", "LOG_PRIVATE_DATA", "false"
+
+ // Set to BODY instead of NONE to enable logging
+ buildConfigField "okhttp3.logging.HttpLoggingInterceptor.Level", "OKHTTP_LOGGING_LEVEL", "okhttp3.logging.HttpLoggingInterceptor.Level.NONE"
+ }
+
release {
+ buildConfigField "boolean", "LOG_PRIVATE_DATA", "false"
+ buildConfigField "okhttp3.logging.HttpLoggingInterceptor.Level", "OKHTTP_LOGGING_LEVEL", "okhttp3.logging.HttpLoggingInterceptor.Level.NONE"
+
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
@@ -44,6 +59,21 @@ android {
}
}
+static def gitRevision() {
+ def cmd = "git rev-parse --short HEAD"
+ return cmd.execute().text.trim()
+}
+
+static def gitRevisionUnixDate() {
+ def cmd = "git show -s --format=%ct HEAD^{commit}"
+ return cmd.execute().text.trim()
+}
+
+static def gitRevisionDate() {
+ def cmd = "git show -s --format=%ci HEAD^{commit}"
+ return cmd.execute().text.trim()
+}
+
dependencies {
def arrow_version = "0.8.0"
diff --git a/matrix-sdk-android/src/debug/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt b/matrix-sdk-android/src/debug/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt
new file mode 100644
index 0000000000..edca01562a
--- /dev/null
+++ b/matrix-sdk-android/src/debug/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 Jeff Gilfelt.
+ * Copyright 2019 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 im.vector.matrix.android.internal.network.interceptors
+
+import okhttp3.Interceptor
+import okhttp3.Response
+import okhttp3.logging.HttpLoggingInterceptor
+import okio.Buffer
+import java.io.IOException
+import java.nio.charset.Charset
+
+/**
+ * An OkHttp interceptor that logs requests as curl shell commands. They can then
+ * be copied, pasted and executed inside a terminal environment. This might be
+ * useful for troubleshooting client/server API interaction during development,
+ * making it easy to isolate and share requests made by the app.
Warning: The
+ * logs generated by this interceptor have the potential to leak sensitive
+ * information. It should only be used in a controlled manner or in a
+ * non-production environment.
+ */
+internal class CurlLoggingInterceptor(private val logger: HttpLoggingInterceptor.Logger = HttpLoggingInterceptor.Logger.DEFAULT)
+ : Interceptor {
+
+ /**
+ * Set any additional curl command options (see 'curl --help').
+ */
+ var curlOptions: String? = null
+
+ @Throws(IOException::class)
+ override fun intercept(chain: Interceptor.Chain): Response {
+ val request = chain.request()
+
+ var compressed = false
+
+ var curlCmd = "curl"
+ if (curlOptions != null) {
+ curlCmd += " " + curlOptions!!
+ }
+ curlCmd += " -X " + request.method()
+
+ val requestBody = request.body()
+ if (requestBody != null) {
+ val buffer = Buffer()
+ requestBody.writeTo(buffer)
+ var charset: Charset? = UTF8
+ val contentType = requestBody.contentType()
+ if (contentType != null) {
+ charset = contentType.charset(UTF8)
+ }
+ // try to keep to a single line and use a subshell to preserve any line breaks
+ curlCmd += " --data $'" + buffer.readString(charset!!).replace("\n", "\\n") + "'"
+ }
+
+ val headers = request.headers()
+ var i = 0
+ val count = headers.size()
+ while (i < count) {
+ val name = headers.name(i)
+ val value = headers.value(i)
+ if ("Accept-Encoding".equals(name, ignoreCase = true) && "gzip".equals(value, ignoreCase = true)) {
+ compressed = true
+ }
+ curlCmd += " -H \"$name: $value\""
+ i++
+ }
+
+ curlCmd += ((if (compressed) " --compressed " else " ") + "'" + request.url().toString()
+ // Replace localhost for emulator by localhost for shell
+ .replace("://10.0.2.2:8080/".toRegex(), "://127.0.0.1:8080/")
+ + "'")
+
+ // Add Json formatting
+ curlCmd += " | python -m json.tool"
+
+ logger.log("--- cURL (" + request.url() + ")")
+ logger.log(curlCmd)
+
+ return chain.proceed(request)
+ }
+
+ companion object {
+ private val UTF8 = Charset.forName("UTF-8")
+ }
+}
diff --git a/matrix-sdk-android/src/debug/java/im/vector/matrix/android/internal/network/interceptors/FormattedJsonHttpLogger.kt b/matrix-sdk-android/src/debug/java/im/vector/matrix/android/internal/network/interceptors/FormattedJsonHttpLogger.kt
new file mode 100644
index 0000000000..655134d1e3
--- /dev/null
+++ b/matrix-sdk-android/src/debug/java/im/vector/matrix/android/internal/network/interceptors/FormattedJsonHttpLogger.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2019 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 im.vector.matrix.android.internal.network.interceptors
+
+import androidx.annotation.NonNull
+import im.vector.matrix.android.BuildConfig
+import okhttp3.logging.HttpLoggingInterceptor
+import org.json.JSONArray
+import org.json.JSONException
+import org.json.JSONObject
+import timber.log.Timber
+
+class FormattedJsonHttpLogger : HttpLoggingInterceptor.Logger {
+
+ companion object {
+ private const val INDENT_SPACE = 2
+ }
+
+ /**
+ * Log the message and try to log it again as a JSON formatted string
+ * Note: it can consume a lot of memory but it is only in DEBUG mode
+ *
+ * @param message
+ */
+ @Synchronized
+ override fun log(@NonNull message: String) {
+ // In RELEASE there is no log, but for sure, test again BuildConfig.DEBUG
+ if (BuildConfig.DEBUG) {
+ Timber.v(message)
+
+ if (message.startsWith("{")) {
+ // JSON Detected
+ try {
+ val o = JSONObject(message)
+ logJson(o.toString(INDENT_SPACE))
+ } catch (e: JSONException) {
+ // Finally this is not a JSON string...
+ Timber.e(e)
+ }
+
+ } else if (message.startsWith("[")) {
+ // JSON Array detected
+ try {
+ val o = JSONArray(message)
+ logJson(o.toString(INDENT_SPACE))
+ } catch (e: JSONException) {
+ // Finally not JSON...
+ Timber.e(e)
+ }
+
+ }
+ // Else not a json string to log
+ }
+ }
+
+ private fun logJson(formattedJson: String) {
+ val arr = formattedJson.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
+ for (s in arr) {
+ Timber.v(s)
+ }
+ }
+}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
index 84b37300e0..67f86d8242 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
@@ -26,6 +26,7 @@ import im.vector.matrix.android.internal.di.MatrixKoinComponent
import im.vector.matrix.android.internal.di.MatrixKoinHolder
import im.vector.matrix.android.internal.di.MatrixModule
import im.vector.matrix.android.internal.di.NetworkModule
+import im.vector.matrix.android.internal.network.UserAgentHolder
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
import org.koin.standalone.inject
import java.util.concurrent.atomic.AtomicBoolean
@@ -38,6 +39,7 @@ import java.util.concurrent.atomic.AtomicBoolean
class Matrix private constructor(context: Context) : MatrixKoinComponent {
private val authenticator by inject()
+ private val userAgent by inject()
private val backgroundDetectionObserver by inject()
lateinit var currentSession: Session
@@ -59,6 +61,13 @@ class Matrix private constructor(context: Context) : MatrixKoinComponent {
return authenticator
}
+ /**
+ * Set application flavor, to alter user agent.
+ */
+ fun setApplicationFlavor(flavor: String) {
+ userAgent.setApplicationFlavor(flavor)
+ }
+
companion object {
private lateinit var instance: Matrix
private val isInit = AtomicBoolean(false)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
index e19c15daca..f1e1a82b59 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
@@ -17,33 +17,45 @@
package im.vector.matrix.android.internal.di
import com.facebook.stetho.okhttp3.StethoInterceptor
-import im.vector.matrix.android.internal.network.AccessTokenInterceptor
-import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
-import im.vector.matrix.android.internal.network.UnitConverterFactory
+import im.vector.matrix.android.BuildConfig
+import im.vector.matrix.android.internal.network.*
+import im.vector.matrix.android.internal.network.interceptors.CurlLoggingInterceptor
+import im.vector.matrix.android.internal.network.interceptors.FormattedJsonHttpLogger
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import okreplay.OkReplayInterceptor
import org.koin.dsl.module.module
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
-import timber.log.Timber
import java.util.concurrent.TimeUnit
class NetworkModule {
val definition = module {
+ single {
+ UserAgentHolder(get())
+ }
+
+ single {
+ UserAgentInterceptor(get())
+ }
+
single {
AccessTokenInterceptor(get())
}
single {
- val logger = HttpLoggingInterceptor.Logger { message -> Timber.v(message) }
+ val logger = FormattedJsonHttpLogger()
val interceptor = HttpLoggingInterceptor(logger)
- interceptor.level = HttpLoggingInterceptor.Level.BASIC
+ interceptor.level = BuildConfig.OKHTTP_LOGGING_LEVEL
interceptor
}
+ single {
+ CurlLoggingInterceptor()
+ }
+
single {
OkReplayInterceptor()
}
@@ -58,8 +70,14 @@ class NetworkModule {
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.addNetworkInterceptor(get())
+ .addInterceptor(get())
.addInterceptor(get())
.addInterceptor(get())
+ .apply {
+ if (BuildConfig.LOG_PRIVATE_DATA) {
+ addInterceptor(get())
+ }
+ }
.addInterceptor(get())
.build()
}
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt
index 864e8400d7..77d2ec926a 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt
@@ -28,7 +28,7 @@ internal class AccessTokenInterceptor(private val sessionParamsStore: SessionPar
// Add the access token to all requests if it is set
val sessionParams = sessionParamsStore.get()
sessionParams?.let {
- newRequestBuilder.addHeader("Authorization", "Bearer " + it.credentials.accessToken)
+ newRequestBuilder.addHeader(HttpHeaders.Authorization, "Bearer " + it.credentials.accessToken)
}
request = newRequestBuilder.build()
return chain.proceed(request)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/HttpHeaders.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/HttpHeaders.kt
new file mode 100644
index 0000000000..f4b93e8a31
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/HttpHeaders.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2019 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 im.vector.matrix.android.internal.network
+
+object HttpHeaders {
+
+ const val Authorization = "Authorization"
+ const val UserAgent = "User-Agent"
+
+}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentHolder.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentHolder.kt
new file mode 100644
index 0000000000..7917f960b6
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentHolder.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2019 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 im.vector.matrix.android.internal.network
+
+import android.content.Context
+import android.text.TextUtils
+import im.vector.matrix.android.BuildConfig
+import timber.log.Timber
+
+internal class UserAgentHolder(val context: Context) {
+
+ var userAgent: String = ""
+ private set
+
+ init {
+ setApplicationFlavor("NoFlavor")
+ }
+
+
+ /**
+ * Create an user agent with the application version.
+ * Ex: RiotX/1.0.0 (Linux; U; Android 6.0.1; SM-A510F Build/MMB29; Flavour GPlay; MatrixAndroidSDK_X 1.0)
+ *
+ * @param flavorDescription the flavor description
+ */
+ fun setApplicationFlavor(flavorDescription: String) {
+ var appName = ""
+ var appVersion = ""
+
+ try {
+ val appPackageName = context.applicationContext.packageName
+ val pm = context.packageManager
+ val appInfo = pm.getApplicationInfo(appPackageName, 0)
+ appName = pm.getApplicationLabel(appInfo).toString()
+
+ val pkgInfo = pm.getPackageInfo(context.applicationContext.packageName, 0)
+ appVersion = pkgInfo.versionName
+
+ // Use appPackageName instead of appName if appName contains any non-ASCII character
+ if (!appName.matches("\\A\\p{ASCII}*\\z".toRegex())) {
+ appName = appPackageName
+ }
+ } catch (e: Exception) {
+ Timber.e(e, "## initUserAgent() : failed " + e.message)
+ }
+
+ var systemUserAgent = System.getProperty("http.agent")
+
+ // cannot retrieve the application version
+ if (TextUtils.isEmpty(appName) || TextUtils.isEmpty(appVersion)) {
+ if (null == systemUserAgent) {
+ userAgent = "Java" + System.getProperty("java.version")
+ }
+ return
+ }
+
+ // if there is no user agent or cannot parse it
+ if (null == systemUserAgent || systemUserAgent.lastIndexOf(")") == -1 || !systemUserAgent.contains("(")) {
+ userAgent = (appName + "/" + appVersion + " ( Flavour " + flavorDescription
+ + "; MatrixAndroidSDK_X " + BuildConfig.VERSION_NAME + ")")
+ } else {
+ // update
+ userAgent = appName + "/" + appVersion + " " +
+ systemUserAgent.substring(systemUserAgent.indexOf("("), systemUserAgent.lastIndexOf(")") - 1) +
+ "; Flavour " + flavorDescription +
+ "; MatrixAndroidSDK_X " + BuildConfig.VERSION_NAME + ")"
+ }
+ }
+}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentInterceptor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentInterceptor.kt
new file mode 100644
index 0000000000..151ba0c361
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/UserAgentInterceptor.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 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 im.vector.matrix.android.internal.network
+
+import okhttp3.Interceptor
+import okhttp3.Response
+
+internal class UserAgentInterceptor(private val userAgentHolder: UserAgentHolder) : Interceptor {
+
+ override fun intercept(chain: Interceptor.Chain): Response {
+ var request = chain.request()
+ val newRequestBuilder = request.newBuilder()
+ // Add the user agent to all requests if it is set
+ userAgentHolder.userAgent
+ .takeIf { it.isNotBlank() }
+ ?.let {
+ newRequestBuilder.addHeader(HttpHeaders.UserAgent, it)
+ }
+ request = newRequestBuilder.build()
+ return chain.proceed(request)
+ }
+
+}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/release/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt b/matrix-sdk-android/src/release/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt
new file mode 100644
index 0000000000..998cdc7ecf
--- /dev/null
+++ b/matrix-sdk-android/src/release/java/im/vector/matrix/android/internal/network/interceptors/CurlLoggingInterceptor.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 Jeff Gilfelt.
+ * Copyright 2019 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 im.vector.matrix.android.internal.network.interceptors
+
+import okhttp3.Interceptor
+import okhttp3.Response
+import java.io.IOException
+
+/**
+ * No op interceptor
+ */
+internal class CurlLoggingInterceptor : Interceptor {
+
+ @Throws(IOException::class)
+ override fun intercept(chain: Interceptor.Chain): Response {
+ return chain.proceed(chain.request())
+ }
+}
diff --git a/matrix-sdk-android/src/release/java/im/vector/matrix/android/internal/network/interceptors/FormattedJsonHttpLogger.kt b/matrix-sdk-android/src/release/java/im/vector/matrix/android/internal/network/interceptors/FormattedJsonHttpLogger.kt
new file mode 100644
index 0000000000..d2fb4ca898
--- /dev/null
+++ b/matrix-sdk-android/src/release/java/im/vector/matrix/android/internal/network/interceptors/FormattedJsonHttpLogger.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019 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 im.vector.matrix.android.internal.network.interceptors
+
+import androidx.annotation.NonNull
+import okhttp3.logging.HttpLoggingInterceptor
+
+/**
+ * No op logger
+ */
+internal class FormattedJsonHttpLogger : HttpLoggingInterceptor.Logger {
+
+ @Synchronized
+ override fun log(@NonNull message: String) {
+ }
+}