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>
|
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
|
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.
|
* Debug API, return the list of all RealmConfiguration used by this session.
|
||||||
|
@ -53,6 +53,11 @@ interface SyncService {
|
|||||||
*/
|
*/
|
||||||
fun getSyncState(): SyncState
|
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.
|
* This method allows to listen the sync state.
|
||||||
* @return a [LiveData] of [SyncState].
|
* @return a [LiveData] of [SyncState].
|
||||||
|
@ -38,7 +38,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
|
|||||||
LiveEntityObserver, RealmChangeListener<RealmResults<T>> {
|
LiveEntityObserver, RealmChangeListener<RealmResults<T>> {
|
||||||
|
|
||||||
private companion object {
|
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())
|
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.Realm
|
||||||
import io.realm.RealmConfiguration
|
import io.realm.RealmConfiguration
|
||||||
import org.matrix.android.sdk.BuildConfig
|
import org.matrix.android.sdk.BuildConfig
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
internal class RealmDebugTools(
|
internal class RealmDebugTools(
|
||||||
private val realmConfiguration: RealmConfiguration
|
private val realmConfiguration: RealmConfiguration
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* Log info about the DB.
|
* Get info about the DB.
|
||||||
*/
|
*/
|
||||||
fun logInfo(baseName: String) {
|
fun getInfo(baseName: String): String {
|
||||||
buildString {
|
return buildString {
|
||||||
append("\n$baseName Realm located at : ${realmConfiguration.realmDirectory}/${realmConfiguration.realmFileName}")
|
append("\n$baseName Realm located at : ${realmConfiguration.realmDirectory}/${realmConfiguration.realmFileName}")
|
||||||
|
|
||||||
if (BuildConfig.LOG_PRIVATE_DATA) {
|
if (BuildConfig.LOG_PRIVATE_DATA) {
|
||||||
@ -54,7 +53,6 @@ internal class RealmDebugTools(
|
|||||||
separator()
|
separator()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.let { Timber.i(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun StringBuilder.separator() = append("\n==============================================")
|
private fun StringBuilder.separator() = append("\n==============================================")
|
||||||
|
@ -36,9 +36,9 @@ internal class DefaultDebugService @Inject constructor(
|
|||||||
realmConfigurationGlobal
|
realmConfigurationGlobal
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logDbUsageInfo() {
|
override fun getDbUsageInfo() = buildString {
|
||||||
RealmDebugTools(realmConfigurationAuth).logInfo("Auth")
|
append(RealmDebugTools(realmConfigurationAuth).getInfo("Auth"))
|
||||||
RealmDebugTools(realmConfigurationGlobal).logInfo("Global")
|
append(RealmDebugTools(realmConfigurationGlobal).getInfo("Global"))
|
||||||
sessionManager.getLastSession()?.logDbUsageInfo()
|
append(sessionManager.getLastSession()?.getDbUsageInfo())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ internal object MatrixModule {
|
|||||||
io = Dispatchers.IO,
|
io = Dispatchers.IO,
|
||||||
computation = Dispatchers.Default,
|
computation = Dispatchers.Default,
|
||||||
main = Dispatchers.Main,
|
main = Dispatchers.Main,
|
||||||
crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher(),
|
crypto = createBackgroundHandler("Matrix-Crypto_Thread").asCoroutineDispatcher(),
|
||||||
dmVerif = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
dmVerif = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -263,11 +263,11 @@ internal class DefaultSession @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logDbUsageInfo() {
|
override fun getDbUsageInfo() = buildString {
|
||||||
RealmDebugTools(realmConfiguration).logInfo("Session")
|
append(RealmDebugTools(realmConfiguration).getInfo("Session"))
|
||||||
RealmDebugTools(realmConfigurationCrypto).logInfo("Crypto")
|
append(RealmDebugTools(realmConfigurationCrypto).getInfo("Crypto"))
|
||||||
RealmDebugTools(realmConfigurationIdentity).logInfo("Identity")
|
append(RealmDebugTools(realmConfigurationIdentity).getInfo("Identity"))
|
||||||
RealmDebugTools(realmConfigurationContentScanner).logInfo("ContentScanner")
|
append(RealmDebugTools(realmConfigurationContentScanner).getInfo("ContentScanner"))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRealmConfigurations(): List<RealmConfiguration> {
|
override fun getRealmConfigurations(): List<RealmConfiguration> {
|
||||||
|
@ -55,7 +55,7 @@ internal class EventSenderProcessorThread @Inject constructor(
|
|||||||
private val queuedTaskFactory: QueuedTaskFactory,
|
private val queuedTaskFactory: QueuedTaskFactory,
|
||||||
private val taskExecutor: TaskExecutor,
|
private val taskExecutor: TaskExecutor,
|
||||||
private val memento: QueueMemento
|
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) {
|
private fun markAsManaged(task: QueuedTask) {
|
||||||
memento.track(task)
|
memento.track(task)
|
||||||
|
@ -76,7 +76,7 @@ internal class DefaultTimeline(
|
|||||||
) : Timeline {
|
) : Timeline {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val BACKGROUND_HANDLER = createBackgroundHandler("DefaultTimeline_Thread")
|
val BACKGROUND_HANDLER = createBackgroundHandler("Matrix-DefaultTimeline_Thread")
|
||||||
}
|
}
|
||||||
|
|
||||||
override val timelineID = UUID.randomUUID().toString()
|
override val timelineID = UUID.randomUUID().toString()
|
||||||
|
@ -73,6 +73,8 @@ internal class DefaultSyncService @Inject constructor(
|
|||||||
|
|
||||||
override fun getSyncState() = getSyncThread().currentState()
|
override fun getSyncState() = getSyncThread().currentState()
|
||||||
|
|
||||||
|
override fun isSyncThreadAlive() = getSyncThread().isAlive
|
||||||
|
|
||||||
override fun getSyncRequestStateFlow() = syncRequestStateTracker.syncRequestState
|
override fun getSyncRequestStateFlow() = syncRequestStateTracker.syncRequestState
|
||||||
|
|
||||||
override fun hasAlreadySynced(): Boolean {
|
override fun hasAlreadySynced(): Boolean {
|
||||||
|
@ -62,7 +62,7 @@ internal class SyncThread @Inject constructor(
|
|||||||
private val backgroundDetectionObserver: BackgroundDetectionObserver,
|
private val backgroundDetectionObserver: BackgroundDetectionObserver,
|
||||||
private val activeCallHandler: ActiveCallHandler,
|
private val activeCallHandler: ActiveCallHandler,
|
||||||
private val lightweightSettingsStorage: DefaultLightweightSettingsStorage
|
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 state: SyncState = SyncState.Idle
|
||||||
private var liveState = MutableLiveData(state)
|
private var liveState = MutableLiveData(state)
|
||||||
|
@ -49,13 +49,13 @@ internal class DefaultBackgroundDetectionObserver : BackgroundDetectionObserver
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart(owner: LifecycleOwner) {
|
override fun onStart(owner: LifecycleOwner) {
|
||||||
Timber.v("App returning to foreground…")
|
Timber.d("App returning to foreground…")
|
||||||
isInBackground = false
|
isInBackground = false
|
||||||
listeners.forEach { it.onMoveToForeground() }
|
listeners.forEach { it.onMoveToForeground() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop(owner: LifecycleOwner) {
|
override fun onStop(owner: LifecycleOwner) {
|
||||||
Timber.v("App going to background…")
|
Timber.d("App going to background…")
|
||||||
isInBackground = true
|
isInBackground = true
|
||||||
listeners.forEach { it.onMoveToBackground() }
|
listeners.forEach { it.onMoveToBackground() }
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ class VectorApplication :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createFontThreadHandler(): Handler {
|
private fun createFontThreadHandler(): Handler {
|
||||||
val handlerThread = HandlerThread("fonts")
|
val handlerThread = HandlerThread("Vector-fonts")
|
||||||
handlerThread.start()
|
handlerThread.start()
|
||||||
return Handler(handlerThread.looper)
|
return Handler(handlerThread.looper)
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import android.content.Context
|
|||||||
import arrow.core.Option
|
import arrow.core.Option
|
||||||
import im.vector.app.ActiveSessionDataSource
|
import im.vector.app.ActiveSessionDataSource
|
||||||
import im.vector.app.core.extensions.configureAndStart
|
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.pushers.UnifiedPushHelper
|
||||||
import im.vector.app.core.services.GuardServiceStarter
|
import im.vector.app.core.services.GuardServiceStarter
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||||
@ -100,7 +101,13 @@ class ActiveSessionHolder @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getOrInitializeSession(startSync: Boolean): Session? {
|
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)
|
setActiveSession(session)
|
||||||
session.configureAndStart(applicationContext, startSyncing = startSync)
|
session.configureAndStart(applicationContext, startSyncing = startSync)
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ import org.matrix.android.sdk.api.session.sync.FilterService
|
|||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
fun Session.configureAndStart(context: Context, startSyncing: Boolean = true) {
|
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()
|
open()
|
||||||
filterService().setFilter(FilterService.FilterPreset.ElementFilter)
|
filterService().setFilter(FilterService.FilterPreset.ElementFilter)
|
||||||
if (startSyncing) {
|
if (startSyncing) {
|
||||||
|
@ -19,7 +19,7 @@ package im.vector.app.features.home.room.detail.timeline.helper
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.HandlerThread
|
import android.os.HandlerThread
|
||||||
|
|
||||||
private const val THREAD_NAME = "Timeline_Building_Thread"
|
private const val THREAD_NAME = "Vector-Timeline_Building_Thread"
|
||||||
|
|
||||||
object TimelineAsyncHelper {
|
object TimelineAsyncHelper {
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ class BugReporter @Inject constructor(
|
|||||||
private val systemLocaleProvider: SystemLocaleProvider,
|
private val systemLocaleProvider: SystemLocaleProvider,
|
||||||
private val matrix: Matrix,
|
private val matrix: Matrix,
|
||||||
private val buildMeta: BuildMeta,
|
private val buildMeta: BuildMeta,
|
||||||
|
private val processInfo: ProcessInfo,
|
||||||
private val sdkIntProvider: BuildVersionSdkIntProvider,
|
private val sdkIntProvider: BuildVersionSdkIntProvider,
|
||||||
) {
|
) {
|
||||||
var inMultiWindowMode = false
|
var inMultiWindowMode = false
|
||||||
@ -499,10 +500,26 @@ class BugReporter @Inject constructor(
|
|||||||
*/
|
*/
|
||||||
fun openBugReportScreen(activity: FragmentActivity, reportType: ReportType = ReportType.BUG_REPORT) {
|
fun openBugReportScreen(activity: FragmentActivity, reportType: ReportType = ReportType.BUG_REPORT) {
|
||||||
screenshot = takeScreenshot(activity)
|
screenshot = takeScreenshot(activity)
|
||||||
matrix.debugService().logDbUsageInfo()
|
logDbInfo()
|
||||||
|
logProcessInfo()
|
||||||
|
logOtherInfo()
|
||||||
activity.startActivity(BugReportActivity.intent(activity, reportType))
|
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 {
|
private fun rageShakeAppNameForReport(reportType: ReportType): String {
|
||||||
// As per https://github.com/matrix-org/rageshake
|
// As per https://github.com/matrix-org/rageshake
|
||||||
// app: Identifier for the application (eg 'riot-web').
|
// 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