mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Merge pull request #6884 from vector-im/feature/bma/sync_thread_investigation
Ensure sync thread is started
This commit is contained in:
commit
e86058b299
1
changelog.d/6884.bugfix
Normal file
1
changelog.d/6884.bugfix
Normal file
@ -0,0 +1 @@
|
||||
Ensure SyncThread is started when the app is launched after a Push has been received.
|
1
changelog.d/6884.sdk
Normal file
1
changelog.d/6884.sdk
Normal file
@ -0,0 +1 @@
|
||||
Rename `DebugService.logDbUsageInfo` (resp. `Session.logDbUsageInfo`) to `DebugService.getDbUsageInfo` (resp. `Session.getDbUsageInfo`) and return a String instead of logging. The caller may want to log the String.
|
@ -28,7 +28,7 @@ interface DebugService {
|
||||
fun getAllRealmConfigurations(): List<RealmConfiguration>
|
||||
|
||||
/**
|
||||
* Prints out info on DB size to logcat.
|
||||
* Get info on DB size.
|
||||
*/
|
||||
fun logDbUsageInfo()
|
||||
fun getDbUsageInfo(): String
|
||||
}
|
||||
|
@ -323,9 +323,9 @@ interface Session {
|
||||
fun getUiaSsoFallbackUrl(authenticationSessionId: String): String
|
||||
|
||||
/**
|
||||
* Debug API, will print out info on DB size to logcat.
|
||||
* Debug API, will return info about the DB.
|
||||
*/
|
||||
fun logDbUsageInfo()
|
||||
fun getDbUsageInfo(): String
|
||||
|
||||
/**
|
||||
* Debug API, return the list of all RealmConfiguration used by this session.
|
||||
|
@ -53,6 +53,11 @@ interface SyncService {
|
||||
*/
|
||||
fun getSyncState(): SyncState
|
||||
|
||||
/**
|
||||
* This method returns true if the sync thread is alive, i.e. started.
|
||||
*/
|
||||
fun isSyncThreadAlive(): Boolean
|
||||
|
||||
/**
|
||||
* This method allows to listen the sync state.
|
||||
* @return a [LiveData] of [SyncState].
|
||||
|
@ -38,7 +38,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
|
||||
LiveEntityObserver, RealmChangeListener<RealmResults<T>> {
|
||||
|
||||
private companion object {
|
||||
val BACKGROUND_HANDLER = createBackgroundHandler("LIVE_ENTITY_BACKGROUND")
|
||||
val BACKGROUND_HANDLER = createBackgroundHandler("Matrix-LIVE_ENTITY_BACKGROUND")
|
||||
}
|
||||
|
||||
protected val observerScope = CoroutineScope(SupervisorJob() + BACKGROUND_HANDLER.asCoroutineDispatcher())
|
||||
|
@ -19,16 +19,15 @@ package org.matrix.android.sdk.internal.database.tools
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import org.matrix.android.sdk.BuildConfig
|
||||
import timber.log.Timber
|
||||
|
||||
internal class RealmDebugTools(
|
||||
private val realmConfiguration: RealmConfiguration
|
||||
) {
|
||||
/**
|
||||
* Log info about the DB.
|
||||
* Get info about the DB.
|
||||
*/
|
||||
fun logInfo(baseName: String) {
|
||||
buildString {
|
||||
fun getInfo(baseName: String): String {
|
||||
return buildString {
|
||||
append("\n$baseName Realm located at : ${realmConfiguration.realmDirectory}/${realmConfiguration.realmFileName}")
|
||||
|
||||
if (BuildConfig.LOG_PRIVATE_DATA) {
|
||||
@ -54,7 +53,6 @@ internal class RealmDebugTools(
|
||||
separator()
|
||||
}
|
||||
}
|
||||
.let { Timber.i(it) }
|
||||
}
|
||||
|
||||
private fun StringBuilder.separator() = append("\n==============================================")
|
||||
|
@ -36,9 +36,9 @@ internal class DefaultDebugService @Inject constructor(
|
||||
realmConfigurationGlobal
|
||||
}
|
||||
|
||||
override fun logDbUsageInfo() {
|
||||
RealmDebugTools(realmConfigurationAuth).logInfo("Auth")
|
||||
RealmDebugTools(realmConfigurationGlobal).logInfo("Global")
|
||||
sessionManager.getLastSession()?.logDbUsageInfo()
|
||||
override fun getDbUsageInfo() = buildString {
|
||||
append(RealmDebugTools(realmConfigurationAuth).getInfo("Auth"))
|
||||
append(RealmDebugTools(realmConfigurationGlobal).getInfo("Global"))
|
||||
append(sessionManager.getLastSession()?.getDbUsageInfo())
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ internal object MatrixModule {
|
||||
io = Dispatchers.IO,
|
||||
computation = Dispatchers.Default,
|
||||
main = Dispatchers.Main,
|
||||
crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher(),
|
||||
crypto = createBackgroundHandler("Matrix-Crypto_Thread").asCoroutineDispatcher(),
|
||||
dmVerif = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
)
|
||||
}
|
||||
|
@ -263,11 +263,11 @@ 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 getDbUsageInfo() = buildString {
|
||||
append(RealmDebugTools(realmConfiguration).getInfo("Session"))
|
||||
append(RealmDebugTools(realmConfigurationCrypto).getInfo("Crypto"))
|
||||
append(RealmDebugTools(realmConfigurationIdentity).getInfo("Identity"))
|
||||
append(RealmDebugTools(realmConfigurationContentScanner).getInfo("ContentScanner"))
|
||||
}
|
||||
|
||||
override fun getRealmConfigurations(): List<RealmConfiguration> {
|
||||
|
@ -55,7 +55,7 @@ internal class EventSenderProcessorThread @Inject constructor(
|
||||
private val queuedTaskFactory: QueuedTaskFactory,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val memento: QueueMemento
|
||||
) : Thread("SENDER_THREAD_SID_${sessionParams.credentials.sessionId()}"), EventSenderProcessor {
|
||||
) : Thread("Matrix-SENDER_THREAD_SID_${sessionParams.credentials.sessionId()}"), EventSenderProcessor {
|
||||
|
||||
private fun markAsManaged(task: QueuedTask) {
|
||||
memento.track(task)
|
||||
|
@ -76,7 +76,7 @@ internal class DefaultTimeline(
|
||||
) : Timeline {
|
||||
|
||||
companion object {
|
||||
val BACKGROUND_HANDLER = createBackgroundHandler("DefaultTimeline_Thread")
|
||||
val BACKGROUND_HANDLER = createBackgroundHandler("Matrix-DefaultTimeline_Thread")
|
||||
}
|
||||
|
||||
override val timelineID = UUID.randomUUID().toString()
|
||||
|
@ -73,6 +73,8 @@ internal class DefaultSyncService @Inject constructor(
|
||||
|
||||
override fun getSyncState() = getSyncThread().currentState()
|
||||
|
||||
override fun isSyncThreadAlive() = getSyncThread().isAlive
|
||||
|
||||
override fun getSyncRequestStateFlow() = syncRequestStateTracker.syncRequestState
|
||||
|
||||
override fun hasAlreadySynced(): Boolean {
|
||||
|
@ -62,7 +62,7 @@ internal class SyncThread @Inject constructor(
|
||||
private val backgroundDetectionObserver: BackgroundDetectionObserver,
|
||||
private val activeCallHandler: ActiveCallHandler,
|
||||
private val lightweightSettingsStorage: DefaultLightweightSettingsStorage
|
||||
) : Thread("SyncThread"), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener {
|
||||
) : Thread("Matrix-SyncThread"), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener {
|
||||
|
||||
private var state: SyncState = SyncState.Idle
|
||||
private var liveState = MutableLiveData(state)
|
||||
|
@ -49,13 +49,13 @@ internal class DefaultBackgroundDetectionObserver : BackgroundDetectionObserver
|
||||
}
|
||||
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
Timber.v("App returning to foreground…")
|
||||
Timber.d("App returning to foreground…")
|
||||
isInBackground = false
|
||||
listeners.forEach { it.onMoveToForeground() }
|
||||
}
|
||||
|
||||
override fun onStop(owner: LifecycleOwner) {
|
||||
Timber.v("App going to background…")
|
||||
Timber.d("App going to background…")
|
||||
isInBackground = true
|
||||
listeners.forEach { it.onMoveToBackground() }
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ class VectorApplication :
|
||||
}
|
||||
|
||||
private fun createFontThreadHandler(): Handler {
|
||||
val handlerThread = HandlerThread("fonts")
|
||||
val handlerThread = HandlerThread("Vector-fonts")
|
||||
handlerThread.start()
|
||||
return Handler(handlerThread.looper)
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import android.content.Context
|
||||
import arrow.core.Option
|
||||
import im.vector.app.ActiveSessionDataSource
|
||||
import im.vector.app.core.extensions.configureAndStart
|
||||
import im.vector.app.core.extensions.startSyncing
|
||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
||||
import im.vector.app.core.services.GuardServiceStarter
|
||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||
@ -100,7 +101,13 @@ class ActiveSessionHolder @Inject constructor(
|
||||
}
|
||||
|
||||
suspend fun getOrInitializeSession(startSync: Boolean): Session? {
|
||||
return activeSessionReference.get() ?: sessionInitializer.tryInitialize(readCurrentSession = { activeSessionReference.get() }) { session ->
|
||||
return activeSessionReference.get()
|
||||
?.also {
|
||||
if (startSync && !it.syncService().isSyncThreadAlive()) {
|
||||
it.startSyncing(applicationContext)
|
||||
}
|
||||
}
|
||||
?: sessionInitializer.tryInitialize(readCurrentSession = { activeSessionReference.get() }) { session ->
|
||||
setActiveSession(session)
|
||||
session.configureAndStart(applicationContext, startSyncing = startSync)
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import org.matrix.android.sdk.api.session.sync.FilterService
|
||||
import timber.log.Timber
|
||||
|
||||
fun Session.configureAndStart(context: Context, startSyncing: Boolean = true) {
|
||||
Timber.i("Configure and start session for $myUserId")
|
||||
Timber.i("Configure and start session for $myUserId. startSyncing: $startSyncing")
|
||||
open()
|
||||
filterService().setFilter(FilterService.FilterPreset.ElementFilter)
|
||||
if (startSyncing) {
|
||||
|
@ -19,7 +19,7 @@ package im.vector.app.features.home.room.detail.timeline.helper
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
|
||||
private const val THREAD_NAME = "Timeline_Building_Thread"
|
||||
private const val THREAD_NAME = "Vector-Timeline_Building_Thread"
|
||||
|
||||
object TimelineAsyncHelper {
|
||||
|
||||
|
@ -78,6 +78,7 @@ class BugReporter @Inject constructor(
|
||||
private val systemLocaleProvider: SystemLocaleProvider,
|
||||
private val matrix: Matrix,
|
||||
private val buildMeta: BuildMeta,
|
||||
private val processInfo: ProcessInfo,
|
||||
private val sdkIntProvider: BuildVersionSdkIntProvider,
|
||||
) {
|
||||
var inMultiWindowMode = false
|
||||
@ -499,10 +500,26 @@ class BugReporter @Inject constructor(
|
||||
*/
|
||||
fun openBugReportScreen(activity: FragmentActivity, reportType: ReportType = ReportType.BUG_REPORT) {
|
||||
screenshot = takeScreenshot(activity)
|
||||
matrix.debugService().logDbUsageInfo()
|
||||
logDbInfo()
|
||||
logProcessInfo()
|
||||
logOtherInfo()
|
||||
activity.startActivity(BugReportActivity.intent(activity, reportType))
|
||||
}
|
||||
|
||||
private fun logOtherInfo() {
|
||||
Timber.i("SyncThread state: " + activeSessionHolder.getSafeActiveSession()?.syncService()?.getSyncState())
|
||||
}
|
||||
|
||||
private fun logDbInfo() {
|
||||
val dbInfo = matrix.debugService().getDbUsageInfo()
|
||||
Timber.i(dbInfo)
|
||||
}
|
||||
|
||||
private fun logProcessInfo() {
|
||||
val pInfo = processInfo.getInfo()
|
||||
Timber.i(pInfo)
|
||||
}
|
||||
|
||||
private fun rageShakeAppNameForReport(reportType: ReportType): String {
|
||||
// As per https://github.com/matrix-org/rageshake
|
||||
// app: Identifier for the application (eg 'riot-web').
|
||||
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.features.rageshake
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.os.Build
|
||||
import android.os.Process
|
||||
import java.lang.reflect.Method
|
||||
import javax.inject.Inject
|
||||
|
||||
class ProcessInfo @Inject constructor() {
|
||||
fun getInfo() = buildString {
|
||||
append("===========================================\n")
|
||||
append("* PROCESS INFO *\n")
|
||||
append("===========================================\n")
|
||||
val processId = Process.myPid()
|
||||
append("ProcessId: $processId\n")
|
||||
append("ProcessName: ${getProcessName()}\n")
|
||||
append(getThreadInfo())
|
||||
append("===========================================\n")
|
||||
}
|
||||
|
||||
@SuppressLint("PrivateApi")
|
||||
private fun getProcessName(): String? {
|
||||
return if (Build.VERSION.SDK_INT >= 28) {
|
||||
Application.getProcessName()
|
||||
} else {
|
||||
try {
|
||||
val activityThread = Class.forName("android.app.ActivityThread")
|
||||
val getProcessName: Method = activityThread.getDeclaredMethod("currentProcessName")
|
||||
getProcessName.invoke(null) as? String
|
||||
} catch (t: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getThreadInfo() = buildString {
|
||||
append("Thread activeCount: ${Thread.activeCount()}\n")
|
||||
Thread.getAllStackTraces().keys
|
||||
.sortedBy { it.name }
|
||||
.forEach { thread -> append(thread.getInfo()) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun Thread.getInfo() = buildString {
|
||||
append("Thread '$name':")
|
||||
append(" id: $id")
|
||||
append(" priority: $priority")
|
||||
append(" group name: ${threadGroup?.name ?: "null"}")
|
||||
append(" state: $state")
|
||||
append(" isAlive: $isAlive")
|
||||
append(" isDaemon: $isDaemon")
|
||||
append(" isInterrupted: $isInterrupted")
|
||||
append("\n")
|
||||
}
|
Loading…
Reference in New Issue
Block a user