From e12103387de8ae67d04ebf97df544eaa9338a98d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 14 Jun 2022 11:54:14 +0200 Subject: [PATCH 1/4] Setup Flipper Move getLastSession() to the SessionManager Create `DebugService` Move `logDbUsageInfo()` to `DebugService` --- changelog.d/6300.misc | 1 + dependencies_groups.gradle | 4 ++ docs/flipper.md | 7 ++ .../android/sdk/common/TestMatrixComponent.kt | 2 + .../java/org/matrix/android/sdk/api/Matrix.kt | 7 ++ .../android/sdk/api/MatrixConfiguration.kt | 5 ++ .../android/sdk/api/debug/DebugService.kt | 34 +++++++++ .../matrix/android/sdk/api/session/Session.kt | 8 ++- .../sdk/api/session/crypto/CryptoService.kt | 2 - .../android/sdk/internal/SessionManager.kt | 7 ++ .../auth/DefaultAuthenticationService.kt | 5 +- .../internal/crypto/DefaultCryptoService.kt | 4 -- .../internal/crypto/store/IMXCryptoStore.kt | 1 - .../crypto/store/db/RealmCryptoStore.kt | 8 --- .../android/sdk/internal/debug/DebugModule.kt | 29 ++++++++ .../sdk/internal/debug/DefaultDebugService.kt | 44 ++++++++++++ .../sdk/internal/di/MatrixComponent.kt | 2 + .../android/sdk/internal/di/NetworkModule.kt | 3 + .../sdk/internal/session/DefaultSession.kt | 18 +++++ vector/build.gradle | 10 +++ vector/src/debug/AndroidManifest.xml | 4 ++ .../im/vector/app/flipper/FlipperProxy.kt | 72 +++++++++++++++++++ .../java/im/vector/app/VectorApplication.kt | 3 + .../im/vector/app/core/di/SingletonModule.kt | 7 +- .../app/features/rageshake/BugReporter.kt | 6 +- .../im/vector/app/flipper/FlipperProxy.kt | 31 ++++++++ 26 files changed, 298 insertions(+), 26 deletions(-) create mode 100644 changelog.d/6300.misc create mode 100644 docs/flipper.md create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/debug/DebugService.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DebugModule.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DefaultDebugService.kt create mode 100644 vector/src/debug/java/im/vector/app/flipper/FlipperProxy.kt create mode 100644 vector/src/release/java/im/vector/app/flipper/FlipperProxy.kt diff --git a/changelog.d/6300.misc b/changelog.d/6300.misc new file mode 100644 index 0000000000..0ac762e595 --- /dev/null +++ b/changelog.d/6300.misc @@ -0,0 +1 @@ +Setup [Flipper](https://fbflipper.com/) diff --git a/dependencies_groups.gradle b/dependencies_groups.gradle index 59cefe7e89..47d53c6ed9 100644 --- a/dependencies_groups.gradle +++ b/dependencies_groups.gradle @@ -31,6 +31,7 @@ ext.groups = [ ], group: [ 'com.android', + 'com.android.ndk.thirdparty', 'com.android.tools', 'com.google.firebase', 'com.google.testing.platform', @@ -52,6 +53,7 @@ ext.groups = [ 'com.dropbox.core', 'com.soywiz.korlibs.korte', 'com.facebook.fbjni', + 'com.facebook.flipper', 'com.facebook.fresco', 'com.facebook.infer.annotation', 'com.facebook.soloader', @@ -93,6 +95,7 @@ ext.groups = [ 'com.ibm.icu', 'com.jakewharton.android.repackaged', 'com.jakewharton.timber', + 'com.kgurgul.flipper', 'com.linkedin.dexmaker', 'com.mapbox.mapboxsdk', 'com.nulab-inc', @@ -168,6 +171,7 @@ ext.groups = [ 'org.glassfish.jaxb', 'org.hamcrest', 'org.jacoco', + 'org.java-websocket', 'org.jetbrains', 'org.jetbrains.dokka', 'org.jetbrains.intellij.deps', diff --git a/docs/flipper.md b/docs/flipper.md new file mode 100644 index 0000000000..490a2b5322 --- /dev/null +++ b/docs/flipper.md @@ -0,0 +1,7 @@ +# Flipper + +TODO Write doc +- Setup env +- Debug activity +>adb shell am start -n im.vector.app.debug/com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity + diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt index daf6b73313..52beb1b484 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt @@ -21,6 +21,7 @@ import dagger.BindsInstance import dagger.Component import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.internal.auth.AuthModule +import org.matrix.android.sdk.internal.debug.DebugModule import org.matrix.android.sdk.internal.di.MatrixComponent import org.matrix.android.sdk.internal.di.MatrixModule import org.matrix.android.sdk.internal.di.MatrixScope @@ -36,6 +37,7 @@ import org.matrix.android.sdk.internal.util.system.SystemModule NetworkModule::class, AuthModule::class, RawModule::class, + DebugModule::class, SettingsModule::class, SystemModule::class ] diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt index 979201706b..55569580a4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt @@ -25,6 +25,7 @@ import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.HomeServerHistoryService +import org.matrix.android.sdk.api.debug.DebugService import org.matrix.android.sdk.api.legacy.LegacySessionImporter import org.matrix.android.sdk.api.network.ApiInterceptorListener import org.matrix.android.sdk.api.network.ApiPath @@ -54,6 +55,7 @@ class Matrix(context: Context, matrixConfiguration: MatrixConfiguration) { @Inject internal lateinit var legacySessionImporter: LegacySessionImporter @Inject internal lateinit var authenticationService: AuthenticationService @Inject internal lateinit var rawService: RawService + @Inject internal lateinit var debugService: DebugService @Inject internal lateinit var userAgentHolder: UserAgentHolder @Inject internal lateinit var backgroundDetectionObserver: BackgroundDetectionObserver @Inject internal lateinit var olmManager: OlmManager @@ -93,6 +95,11 @@ class Matrix(context: Context, matrixConfiguration: MatrixConfiguration) { */ fun rawService() = rawService + /** + * Return the DebugService. + */ + fun debugService() = debugService + /** * Return the LightweightSettingsStorage. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt index 21106fba6c..893e90fb3e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.api import okhttp3.ConnectionSpec +import okhttp3.Interceptor import org.matrix.android.sdk.api.crypto.MXCryptoConfig import java.net.Proxy @@ -65,4 +66,8 @@ data class MatrixConfiguration( * Thread messages default enable/disabled value. */ val threadMessagesEnabledDefault: Boolean = false, + /** + * List of network interceptors, they will be added when building an OkHttp client. + */ + val networkInterceptors: List = emptyList(), ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/debug/DebugService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/debug/DebugService.kt new file mode 100644 index 0000000000..d0cee08831 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/debug/DebugService.kt @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.api.debug + +import io.realm.RealmConfiguration + +/** + * Useful methods to access to some private data managed by the SDK. + */ +interface DebugService { + /** + * Get all the available Realm Configuration. + */ + fun getAllRealmConfigurations(): List + + /** + * Prints out info on DB size to logcat. + */ + fun logDbUsageInfo() +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt index b3a629094c..a0d122635d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/Session.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.api.session import androidx.annotation.MainThread +import io.realm.RealmConfiguration import okhttp3.OkHttpClient import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.auth.data.SessionParams @@ -334,7 +335,12 @@ interface Session { fun getUiaSsoFallbackUrl(authenticationSessionId: String): String /** - * Maintenance API, allows to print outs info on DB size to logcat. + * Debug API, will print out info on DB size to logcat. */ fun logDbUsageInfo() + + /** + * Debug API, return the list of all RealmConfiguration used by this session. + */ + fun getRealmConfigurations(): List } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 9cc87b6f71..638da11804 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -171,8 +171,6 @@ interface CryptoService { fun getSharedWithInfo(roomId: String?, sessionId: String): MXUsersDevicesMap fun getWithHeldMegolmSession(roomId: String, sessionId: String): RoomKeyWithHeldContent? - fun logDbUsageInfo() - /** * Perform any background tasks that can be done before a message is ready to * send, in order to speed up sending of the message. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt index bd2dac9e3c..5f5bb1f951 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/SessionManager.kt @@ -40,6 +40,13 @@ internal class SessionManager @Inject constructor( return getOrCreateSessionComponent(sessionParams) } + fun getLastSession(): Session? { + val sessionParams = sessionParamsStore.getLast() + return sessionParams?.let { + getOrCreateSession(it) + } + } + fun getOrCreateSession(sessionParams: SessionParams): Session { return getOrCreateSessionComponent(sessionParams).session() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt index 61a423669c..92852e4722 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt @@ -73,10 +73,7 @@ internal class DefaultAuthenticationService @Inject constructor( } override fun getLastAuthenticatedSession(): Session? { - val sessionParams = sessionParamsStore.getLast() - return sessionParams?.let { - sessionManager.getOrCreateSession(it) - } + return sessionManager.getLastSession() } override suspend fun getLoginFlowOfSession(sessionId: String): LoginFlowResult { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 719f366518..e0bcde2296 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -1298,10 +1298,6 @@ internal class DefaultCryptoService @Inject constructor( return cryptoStore.getWithHeldMegolmSession(roomId, sessionId) } - override fun logDbUsageInfo() { - cryptoStore.logDbUsageInfo() - } - override fun prepareToEncrypt(roomId: String, callback: MatrixCallback) { cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { Timber.tag(loggerTag.value).d("prepareToEncrypt() roomId:$roomId Check room members up to date") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index b18de34329..b5b8d8e974 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -513,6 +513,5 @@ internal interface IMXCryptoStore { fun setDeviceKeysUploaded(uploaded: Boolean) fun areDeviceKeysUploaded(): Boolean fun tidyUpDataBase() - fun logDbUsageInfo() fun getOutgoingRoomKeyRequests(inStates: Set): List } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index c56e4d320b..028d8f73f9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -88,7 +88,6 @@ import org.matrix.android.sdk.internal.crypto.store.db.query.get import org.matrix.android.sdk.internal.crypto.store.db.query.getById import org.matrix.android.sdk.internal.crypto.store.db.query.getOrCreate import org.matrix.android.sdk.internal.crypto.util.RequestIdHelper -import org.matrix.android.sdk.internal.database.tools.RealmDebugTools import org.matrix.android.sdk.internal.di.CryptoDatabase import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.MoshiProvider @@ -1709,11 +1708,4 @@ internal class RealmCryptoStore @Inject constructor( // Can we do something for WithHeldSessionEntity? } } - - /** - * Prints out database info. - */ - override fun logDbUsageInfo() { - RealmDebugTools(realmConfiguration).logInfo("Crypto") - } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DebugModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DebugModule.kt new file mode 100644 index 0000000000..f392d39d7b --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DebugModule.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.debug + +import dagger.Binds +import dagger.Module +import org.matrix.android.sdk.api.debug.DebugService + +@Module +internal abstract class DebugModule { + + @Binds + abstract fun bindDebugService(service: DefaultDebugService): DebugService +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DefaultDebugService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DefaultDebugService.kt new file mode 100644 index 0000000000..3f2e6fafc8 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/debug/DefaultDebugService.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.debug + +import io.realm.RealmConfiguration +import org.matrix.android.sdk.api.debug.DebugService +import org.matrix.android.sdk.internal.SessionManager +import org.matrix.android.sdk.internal.database.tools.RealmDebugTools +import org.matrix.android.sdk.internal.di.AuthDatabase +import org.matrix.android.sdk.internal.di.GlobalDatabase +import javax.inject.Inject + +internal class DefaultDebugService @Inject constructor( + @AuthDatabase private val realmConfigurationAuth: RealmConfiguration, + @GlobalDatabase private val realmConfigurationGlobal: RealmConfiguration, + private val sessionManager: SessionManager, +) : DebugService { + + override fun getAllRealmConfigurations(): List { + return sessionManager.getLastSession()?.getRealmConfigurations().orEmpty() + + realmConfigurationAuth + + realmConfigurationGlobal + } + + override fun logDbUsageInfo() { + RealmDebugTools(realmConfigurationAuth).logInfo("Auth") + RealmDebugTools(realmConfigurationGlobal).logInfo("Global") + sessionManager.getLastSession()?.logDbUsageInfo() + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt index 095916643c..d668c0498f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt @@ -32,6 +32,7 @@ import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.auth.AuthModule import org.matrix.android.sdk.internal.auth.SessionParamsStore +import org.matrix.android.sdk.internal.debug.DebugModule import org.matrix.android.sdk.internal.raw.RawModule import org.matrix.android.sdk.internal.session.MockHttpInterceptor import org.matrix.android.sdk.internal.session.TestInterceptor @@ -49,6 +50,7 @@ import java.io.File NetworkModule::class, AuthModule::class, RawModule::class, + DebugModule::class, SettingsModule::class, SystemModule::class, NoOpTestModule::class diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt index 862cf463b2..4d0708bdb3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt @@ -95,6 +95,9 @@ internal object NetworkModule { matrixConfiguration.proxy?.let { proxy(it) } + matrixConfiguration.networkInterceptors.forEach { + addInterceptor(it) + } } .connectionSpecs(Collections.singletonList(spec)) .build() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt index 32269c9afd..36d3f0606b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultSession.kt @@ -71,6 +71,9 @@ import org.matrix.android.sdk.internal.auth.SSO_UIA_FALLBACK_PATH import org.matrix.android.sdk.internal.auth.SessionParamsStore import org.matrix.android.sdk.internal.crypto.DefaultCryptoService import org.matrix.android.sdk.internal.database.tools.RealmDebugTools +import org.matrix.android.sdk.internal.di.ContentScannerDatabase +import org.matrix.android.sdk.internal.di.CryptoDatabase +import org.matrix.android.sdk.internal.di.IdentityDatabase import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate @@ -88,6 +91,9 @@ internal class DefaultSession @Inject constructor( override val sessionId: String, override val coroutineDispatchers: MatrixCoroutineDispatchers, @SessionDatabase private val realmConfiguration: RealmConfiguration, + @CryptoDatabase private val realmConfigurationCrypto: RealmConfiguration, + @IdentityDatabase private val realmConfigurationIdentity: RealmConfiguration, + @ContentScannerDatabase private val realmConfigurationContentScanner: RealmConfiguration, private val lifecycleObservers: Set<@JvmSuppressWildcards SessionLifecycleObserver>, private val sessionListeners: SessionListeners, private val roomService: Lazy, @@ -265,5 +271,17 @@ internal class DefaultSession @Inject constructor( override fun logDbUsageInfo() { RealmDebugTools(realmConfiguration).logInfo("Session") + RealmDebugTools(realmConfigurationCrypto).logInfo("Crypto") + RealmDebugTools(realmConfigurationIdentity).logInfo("Identity") + RealmDebugTools(realmConfigurationContentScanner).logInfo("ContentScanner") + } + + override fun getRealmConfigurations(): List { + return listOf( + realmConfiguration, + realmConfigurationCrypto, + realmConfigurationIdentity, + realmConfigurationContentScanner, + ) } } diff --git a/vector/build.gradle b/vector/build.gradle index 46659f66a8..7b73acda42 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -525,6 +525,16 @@ dependencies { exclude group: "org.jetbrains.kotlinx", module: "kotlinx-coroutines-debug" } + // Flipper, debug builds only + debugImplementation('com.facebook.flipper:flipper:0.149.0') { + exclude group: 'com.facebook.fbjni', module: 'fbjni' + } + debugImplementation('com.facebook.flipper:flipper-network-plugin:0.149.0') { + exclude group: 'com.facebook.fbjni', module: 'fbjni' + } + debugImplementation 'com.facebook.soloader:soloader:0.10.3' + debugImplementation "com.kgurgul.flipper:flipper-realm-android:2.1.0" + // Activate when you want to check for leaks, from time to time. //debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3' diff --git a/vector/src/debug/AndroidManifest.xml b/vector/src/debug/AndroidManifest.xml index 0b2b5cf90f..4ef1f41130 100644 --- a/vector/src/debug/AndroidManifest.xml +++ b/vector/src/debug/AndroidManifest.xml @@ -9,6 +9,10 @@ + + diff --git a/vector/src/debug/java/im/vector/app/flipper/FlipperProxy.kt b/vector/src/debug/java/im/vector/app/flipper/FlipperProxy.kt new file mode 100644 index 0000000000..76be7e1b46 --- /dev/null +++ b/vector/src/debug/java/im/vector/app/flipper/FlipperProxy.kt @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022 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.app.flipper + +import android.content.Context +import com.facebook.flipper.android.AndroidFlipperClient +import com.facebook.flipper.android.utils.FlipperUtils +import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin +import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin +import com.facebook.flipper.plugins.inspector.DescriptorMapping +import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin +import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor +import com.facebook.flipper.plugins.network.NetworkFlipperPlugin +import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin +import com.facebook.soloader.SoLoader +import com.kgurgul.flipper.RealmDatabaseDriver +import com.kgurgul.flipper.RealmDatabaseProvider +import io.realm.RealmConfiguration +import okhttp3.Interceptor +import org.matrix.android.sdk.api.Matrix +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class FlipperProxy @Inject constructor( + private val context: Context, +) { + private val networkFlipperPlugin = NetworkFlipperPlugin() + + fun init(matrix: Matrix) { + SoLoader.init(context, false) + + if (FlipperUtils.shouldEnableFlipper(context)) { + val client = AndroidFlipperClient.getInstance(context) + client.addPlugin(CrashReporterPlugin.getInstance()) + client.addPlugin(SharedPreferencesFlipperPlugin(context)) + client.addPlugin(InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())) + client.addPlugin(networkFlipperPlugin) + client.addPlugin( + DatabasesFlipperPlugin( + RealmDatabaseDriver( + context = context, + realmDatabaseProvider = object : RealmDatabaseProvider { + override fun getRealmConfigurations(): List { + return matrix.debugService().getAllRealmConfigurations() + } + }) + ) + ) + client.start() + } + } + + @Suppress("RedundantNullableReturnType") + fun getNetworkInterceptor(): Interceptor? { + return FlipperOkhttpInterceptor(networkFlipperPlugin) + } +} diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt index 7db0f99f5f..05cb4fb9bc 100644 --- a/vector/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector/src/main/java/im/vector/app/VectorApplication.kt @@ -60,6 +60,7 @@ import im.vector.app.features.settings.VectorLocale import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.version.VersionProvider +import im.vector.app.flipper.FlipperProxy import im.vector.app.push.fcm.FcmHelper import org.jitsi.meet.sdk.log.JitsiMeetDefaultLogHandler import org.matrix.android.sdk.api.Matrix @@ -99,6 +100,7 @@ class VectorApplication : @Inject lateinit var autoRageShaker: AutoRageShaker @Inject lateinit var vectorFileLogger: VectorFileLogger @Inject lateinit var vectorAnalytics: VectorAnalytics + @Inject lateinit var flipperProxy: FlipperProxy @Inject lateinit var matrix: Matrix // font thread handler @@ -117,6 +119,7 @@ class VectorApplication : enableStrictModeIfNeeded() super.onCreate() appContext = this + flipperProxy.init(matrix) vectorAnalytics.init() invitesAcceptor.initialize() autoRageShaker.initialize() diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt index 085a9a5d12..bc0bccfa1b 100644 --- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt @@ -50,6 +50,7 @@ import im.vector.app.features.room.VectorRoomDisplayNameFallbackProvider import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.ui.SharedPreferencesUiStateRepository import im.vector.app.features.ui.UiStateRepository +import im.vector.app.flipper.FlipperProxy import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers @@ -119,12 +120,16 @@ object VectorStaticModule { @Provides fun providesMatrixConfiguration( vectorPreferences: VectorPreferences, - vectorRoomDisplayNameFallbackProvider: VectorRoomDisplayNameFallbackProvider + vectorRoomDisplayNameFallbackProvider: VectorRoomDisplayNameFallbackProvider, + flipperProxy: FlipperProxy, ): MatrixConfiguration { return MatrixConfiguration( applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION, roomDisplayNameFallbackProvider = vectorRoomDisplayNameFallbackProvider, threadMessagesEnabledDefault = vectorPreferences.areThreadMessagesEnabled(), + networkInterceptors = listOfNotNull( + flipperProxy.getNetworkInterceptor(), + ) ) } diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt index 2612e63841..09453e5b02 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt @@ -492,11 +492,7 @@ class BugReporter @Inject constructor( */ fun openBugReportScreen(activity: FragmentActivity, reportType: ReportType = ReportType.BUG_REPORT) { screenshot = takeScreenshot(activity) - activeSessionHolder.getSafeActiveSession()?.let { - it.logDbUsageInfo() - it.cryptoService().logDbUsageInfo() - } - + matrix.debugService().logDbUsageInfo() activity.startActivity(BugReportActivity.intent(activity, reportType)) } diff --git a/vector/src/release/java/im/vector/app/flipper/FlipperProxy.kt b/vector/src/release/java/im/vector/app/flipper/FlipperProxy.kt new file mode 100644 index 0000000000..03b1977a45 --- /dev/null +++ b/vector/src/release/java/im/vector/app/flipper/FlipperProxy.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 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.app.flipper + +import okhttp3.Interceptor +import org.matrix.android.sdk.api.Matrix +import javax.inject.Inject + +/** + * No op version. + */ +@Suppress("UNUSED_PARAMETER") +class FlipperProxy @Inject constructor() { + fun init(matrix: Matrix) {} + + fun getNetworkInterceptor(): Interceptor? = null +} From aea94d79eb9fd19e17656176a3b898592d7d39bd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 14 Jun 2022 12:43:21 +0200 Subject: [PATCH 2/4] Add documentation for Flipper --- docs/flipper.md | 58 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/docs/flipper.md b/docs/flipper.md index 490a2b5322..cc3b7eb5e0 100644 --- a/docs/flipper.md +++ b/docs/flipper.md @@ -1,7 +1,57 @@ # Flipper -TODO Write doc -- Setup env -- Debug activity ->adb shell am start -n im.vector.app.debug/com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity + +* [Introduction](#introduction) +* [Setup](#setup) + * [Troubleshoot](#troubleshoot) + * [No device found issue](#no-device-found-issue) + * [Diagnostic Activity](#diagnostic-activity) + * [Other](#other) +* [Links](#links) + + + +## Introduction + +[Flipper](https://fbflipper.com) is a powerful tool from Meta, which allow to inspect the running application details and states from your computer. + +Flipper is configured in the Element Android project to let the developers be able to: +- inspect all the Realm databases content; +- do layout inspection; +- see the crash logs; +- see the logcat; +- see all the network requests; +- see all the SharedPreferences; +- take screenshots and record videos of the device; +- and more! + +## Setup + +- Install Flipper on your computer. Follow instructions here: https://fbflipper.com/docs/getting-started/index/ +- Run the debug version of Element on an emulator or on a real device. + +### Troubleshoot + +#### No device found issue + +The configuration of the Flipper application has to be updated. The issue has been asked and answered here: https://stackoverflow.com/questions/71744103/android-emulator-unable-to-connect-to-flipper/72608113#72608113 + +#### Diagnostic Activity + +Flipper comes with a Diagnostic Activity that you can start from command line using: + +```shell +adb shell am start -n im.vector.app.debug/com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity +``` + +It provides some log which can help to figure out what's going on client side. + +#### Other + +https://fbflipper.com/docs/getting-started/troubleshooting/android/ may help. + +## Links + +- https://fbflipper.com +- Realm Plugin for Flipper: https://github.com/kamgurgul/Flipper-Realm From 514c4234f2edbf8cb582692b83a175479632d5cf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 15 Jun 2022 10:30:38 +0200 Subject: [PATCH 3/4] Add MatrixConfiguration network interceptors after all the other, to ensure to view all the network request headers in Flipper. --- .../android/sdk/internal/di/NetworkModule.kt | 8 ++------ .../network/httpclient/OkHttpClientUtil.kt | 15 +++++++++++++++ .../sdk/internal/session/SessionModule.kt | 17 ++++++++++++----- .../internal/session/identity/IdentityModule.kt | 6 +++++- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt index 4d0708bdb3..b5b46a3f5a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt @@ -29,6 +29,7 @@ import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.internal.network.ApiInterceptor import org.matrix.android.sdk.internal.network.TimeOutInterceptor import org.matrix.android.sdk.internal.network.UserAgentInterceptor +import org.matrix.android.sdk.internal.network.httpclient.applyMatrixConfiguration import org.matrix.android.sdk.internal.network.interceptors.CurlLoggingInterceptor import org.matrix.android.sdk.internal.network.interceptors.FormattedJsonHttpLogger import java.util.Collections @@ -92,14 +93,9 @@ internal object NetworkModule { if (BuildConfig.LOG_PRIVATE_DATA) { addInterceptor(curlLoggingInterceptor) } - matrixConfiguration.proxy?.let { - proxy(it) - } - matrixConfiguration.networkInterceptors.forEach { - addInterceptor(it) - } } .connectionSpecs(Collections.singletonList(spec)) + .applyMatrixConfiguration(matrixConfiguration) .build() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/httpclient/OkHttpClientUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/httpclient/OkHttpClientUtil.kt index 3920c3b527..1c395c2d61 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/httpclient/OkHttpClientUtil.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/httpclient/OkHttpClientUtil.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.network.httpclient import okhttp3.OkHttpClient +import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.internal.network.AccessTokenInterceptor import org.matrix.android.sdk.internal.network.interceptors.CurlLoggingInterceptor @@ -51,3 +52,17 @@ internal fun OkHttpClient.Builder.addSocketFactory(homeServerConnectionConfig: H return this } + +internal fun OkHttpClient.Builder.applyMatrixConfiguration(matrixConfiguration: MatrixConfiguration): OkHttpClient.Builder { + matrixConfiguration.proxy?.let { + proxy(it) + } + + // Move networkInterceptors provided in the configuration after all the others + interceptors().removeAll(matrixConfiguration.networkInterceptors) + matrixConfiguration.networkInterceptors.forEach { + addInterceptor(it) + } + + return this +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt index 2c2317de0d..2cb9768231 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt @@ -73,6 +73,7 @@ import org.matrix.android.sdk.internal.network.PreferredNetworkCallbackStrategy import org.matrix.android.sdk.internal.network.RetrofitFactory import org.matrix.android.sdk.internal.network.httpclient.addAccessTokenInterceptor import org.matrix.android.sdk.internal.network.httpclient.addSocketFactory +import org.matrix.android.sdk.internal.network.httpclient.applyMatrixConfiguration import org.matrix.android.sdk.internal.network.interceptors.CurlLoggingInterceptor import org.matrix.android.sdk.internal.network.token.AccessTokenProvider import org.matrix.android.sdk.internal.network.token.HomeserverAccessTokenProvider @@ -212,7 +213,7 @@ internal abstract class SessionModule { @UnauthenticatedWithCertificate fun providesOkHttpClientWithCertificate( @Unauthenticated okHttpClient: OkHttpClient, - homeServerConnectionConfig: HomeServerConnectionConfig + homeServerConnectionConfig: HomeServerConnectionConfig, ): OkHttpClient { return okHttpClient .newBuilder() @@ -228,7 +229,8 @@ internal abstract class SessionModule { @UnauthenticatedWithCertificate okHttpClient: OkHttpClient, @Authenticated accessTokenProvider: AccessTokenProvider, @SessionId sessionId: String, - @MockHttpInterceptor testInterceptor: TestInterceptor? + @MockHttpInterceptor testInterceptor: TestInterceptor?, + matrixConfiguration: MatrixConfiguration, ): OkHttpClient { return okHttpClient .newBuilder() @@ -239,6 +241,7 @@ internal abstract class SessionModule { addInterceptor(testInterceptor) } } + .applyMatrixConfiguration(matrixConfiguration) .build() } @@ -248,9 +251,11 @@ internal abstract class SessionModule { @UnauthenticatedWithCertificateWithProgress fun providesProgressOkHttpClient( @UnauthenticatedWithCertificate okHttpClient: OkHttpClient, - downloadProgressInterceptor: DownloadProgressInterceptor + downloadProgressInterceptor: DownloadProgressInterceptor, + matrixConfiguration: MatrixConfiguration, ): OkHttpClient { - return okHttpClient.newBuilder() + return okHttpClient + .newBuilder() .apply { // Remove the previous CurlLoggingInterceptor, to add it after the accessTokenInterceptor val existingCurlInterceptors = interceptors().filterIsInstance() @@ -262,7 +267,9 @@ internal abstract class SessionModule { existingCurlInterceptors.forEach { addInterceptor(it) } - }.build() + } + .applyMatrixConfiguration(matrixConfiguration) + .build() } @JvmStatic diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt index 464ae96e3a..33d8164895 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt @@ -21,6 +21,7 @@ import dagger.Module import dagger.Provides import io.realm.RealmConfiguration import okhttp3.OkHttpClient +import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.session.identity.IdentityService import org.matrix.android.sdk.internal.database.RealmKeysUtils import org.matrix.android.sdk.internal.di.AuthenticatedIdentity @@ -29,6 +30,7 @@ import org.matrix.android.sdk.internal.di.SessionFilesDirectory import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate import org.matrix.android.sdk.internal.di.UserMd5 import org.matrix.android.sdk.internal.network.httpclient.addAccessTokenInterceptor +import org.matrix.android.sdk.internal.network.httpclient.applyMatrixConfiguration import org.matrix.android.sdk.internal.network.token.AccessTokenProvider import org.matrix.android.sdk.internal.session.SessionModule import org.matrix.android.sdk.internal.session.SessionScope @@ -49,11 +51,13 @@ internal abstract class IdentityModule { @AuthenticatedIdentity fun providesOkHttpClient( @UnauthenticatedWithCertificate okHttpClient: OkHttpClient, - @AuthenticatedIdentity accessTokenProvider: AccessTokenProvider + @AuthenticatedIdentity accessTokenProvider: AccessTokenProvider, + matrixConfiguration: MatrixConfiguration, ): OkHttpClient { return okHttpClient .newBuilder() .addAccessTokenInterceptor(accessTokenProvider) + .applyMatrixConfiguration(matrixConfiguration) .build() } From 0abeb3306ecc4ae039f62da5272a4e8d9c5b7844 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 15 Jun 2022 10:37:17 +0200 Subject: [PATCH 4/4] Bad copy paste in comment --- .../org/matrix/android/sdk/internal/session/SessionModule.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt index 2cb9768231..950cb899f8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt @@ -257,7 +257,7 @@ internal abstract class SessionModule { return okHttpClient .newBuilder() .apply { - // Remove the previous CurlLoggingInterceptor, to add it after the accessTokenInterceptor + // Remove the previous CurlLoggingInterceptor, to add it after the downloadProgressInterceptor val existingCurlInterceptors = interceptors().filterIsInstance() interceptors().removeAll(existingCurlInterceptors)