mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Merge pull request #3197 from vector-im/feature/bma/crashfix
WIP - introduce sessionScope
This commit is contained in:
commit
98177da6b1
@ -255,13 +255,13 @@ interface Session :
|
||||
/**
|
||||
* A global session listener to get notified for some events.
|
||||
*/
|
||||
interface Listener {
|
||||
interface Listener : SessionLifecycleObserver {
|
||||
/**
|
||||
* Possible cases:
|
||||
* - The access token is not valid anymore,
|
||||
* - a M_CONSENT_NOT_GIVEN error has been received from the homeserver
|
||||
*/
|
||||
fun onGlobalError(globalError: GlobalError)
|
||||
fun onGlobalError(session: Session, globalError: GlobalError)
|
||||
}
|
||||
|
||||
val sharedSecretStorageService: SharedSecretStorageService
|
||||
|
@ -14,20 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.session
|
||||
package org.matrix.android.sdk.api.session
|
||||
|
||||
import androidx.annotation.MainThread
|
||||
|
||||
/**
|
||||
* This defines methods associated with some lifecycle events of a session.
|
||||
* A list of SessionLifecycle will be injected into [DefaultSession]
|
||||
*/
|
||||
internal interface SessionLifecycleObserver {
|
||||
interface SessionLifecycleObserver {
|
||||
/*
|
||||
Called when the session is opened
|
||||
*/
|
||||
@MainThread
|
||||
fun onSessionStarted() {
|
||||
fun onSessionStarted(session: Session) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@ -35,7 +34,7 @@ internal interface SessionLifecycleObserver {
|
||||
Called when the session is cleared
|
||||
*/
|
||||
@MainThread
|
||||
fun onClearCache() {
|
||||
fun onClearCache(session: Session) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@ -43,7 +42,7 @@ internal interface SessionLifecycleObserver {
|
||||
Called when the session is closed
|
||||
*/
|
||||
@MainThread
|
||||
fun onSessionStopped() {
|
||||
fun onSessionStopped(session: Session) {
|
||||
// noop
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.internal.database.helper.nextDisplayIndex
|
||||
import org.matrix.android.sdk.internal.database.model.ChunkEntity
|
||||
import org.matrix.android.sdk.internal.database.model.ChunkEntityFields
|
||||
@ -29,7 +30,7 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.deleteOnCascade
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
|
||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||
import timber.log.Timber
|
||||
@ -47,7 +48,7 @@ private const val MIN_NUMBER_OF_EVENTS_BY_CHUNK = 300
|
||||
internal class DatabaseCleaner @Inject constructor(@SessionDatabase private val realmConfiguration: RealmConfiguration,
|
||||
private val taskExecutor: TaskExecutor) : SessionLifecycleObserver {
|
||||
|
||||
override fun onSessionStarted() {
|
||||
override fun onSessionStarted(session: Session) {
|
||||
taskExecutor.executorScope.launch(Dispatchers.Default) {
|
||||
awaitTransaction(realmConfiguration) { realm ->
|
||||
val allRooms = realm.where(RoomEntity::class.java).findAll()
|
||||
|
@ -17,7 +17,7 @@
|
||||
package org.matrix.android.sdk.internal.database
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.internal.util.createBackgroundHandler
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmChangeListener
|
||||
@ -28,6 +28,7 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.android.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
@ -46,7 +47,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
|
||||
private val backgroundRealm = AtomicReference<Realm>()
|
||||
private lateinit var results: AtomicReference<RealmResults<T>>
|
||||
|
||||
override fun onSessionStarted() {
|
||||
override fun onSessionStarted(session: Session) {
|
||||
if (isStarted.compareAndSet(false, true)) {
|
||||
BACKGROUND_HANDLER.post {
|
||||
val realm = Realm.getInstance(realmConfiguration)
|
||||
@ -58,7 +59,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSessionStopped() {
|
||||
override fun onSessionStopped(session: Session) {
|
||||
if (isStarted.compareAndSet(true, false)) {
|
||||
BACKGROUND_HANDLER.post {
|
||||
results.getAndSet(null).removeAllChangeListeners()
|
||||
@ -70,7 +71,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClearCache() {
|
||||
override fun onClearCache(session: Session) {
|
||||
observerScope.coroutineContext.cancelChildren()
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,9 @@ import android.os.Looper
|
||||
import androidx.annotation.MainThread
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.Realm
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import javax.inject.Inject
|
||||
import kotlin.concurrent.getOrSet
|
||||
@ -44,14 +45,14 @@ internal class RealmSessionProvider @Inject constructor(@SessionDatabase private
|
||||
}
|
||||
|
||||
@MainThread
|
||||
override fun onSessionStarted() {
|
||||
override fun onSessionStarted(session: Session) {
|
||||
realmThreadLocal.getOrSet {
|
||||
Realm.getInstance(monarchy.realmConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
@MainThread
|
||||
override fun onSessionStopped() {
|
||||
override fun onSessionStopped(session: Session) {
|
||||
realmThreadLocal.get()?.close()
|
||||
realmThreadLocal.remove()
|
||||
}
|
||||
|
@ -19,13 +19,15 @@ package org.matrix.android.sdk.internal.session
|
||||
import androidx.annotation.MainThread
|
||||
import dagger.Lazy
|
||||
import io.realm.RealmConfiguration
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.OkHttpClient
|
||||
import org.matrix.android.sdk.api.auth.data.SessionParams
|
||||
import org.matrix.android.sdk.api.failure.GlobalError
|
||||
import org.matrix.android.sdk.api.federation.FederationService
|
||||
import org.matrix.android.sdk.api.pushrules.PushRuleService
|
||||
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.api.session.account.AccountService
|
||||
import org.matrix.android.sdk.api.session.accountdata.AccountDataService
|
||||
import org.matrix.android.sdk.api.session.cache.CacheService
|
||||
@ -38,6 +40,7 @@ import org.matrix.android.sdk.api.session.file.ContentDownloadStateTracker
|
||||
import org.matrix.android.sdk.api.session.file.FileService
|
||||
import org.matrix.android.sdk.api.session.group.GroupService
|
||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
||||
import org.matrix.android.sdk.api.session.initsync.InitialSyncProgressService
|
||||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
|
||||
import org.matrix.android.sdk.api.session.media.MediaService
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
||||
@ -161,7 +164,12 @@ internal class DefaultSession @Inject constructor(
|
||||
isOpen = true
|
||||
cryptoService.get().ensureDevice()
|
||||
uiHandler.post {
|
||||
lifecycleObservers.forEach { it.onSessionStarted() }
|
||||
lifecycleObservers.forEach {
|
||||
it.onSessionStarted(this)
|
||||
}
|
||||
sessionListeners.dispatch {
|
||||
it.onSessionStarted(this)
|
||||
}
|
||||
}
|
||||
globalErrorHandler.listener = this
|
||||
}
|
||||
@ -202,7 +210,10 @@ internal class DefaultSession @Inject constructor(
|
||||
stopSync()
|
||||
// timelineEventDecryptor.destroy()
|
||||
uiHandler.post {
|
||||
lifecycleObservers.forEach { it.onSessionStopped() }
|
||||
lifecycleObservers.forEach { it.onSessionStopped(this) }
|
||||
sessionListeners.dispatch {
|
||||
it.onSessionStopped(this)
|
||||
}
|
||||
}
|
||||
cryptoService.get().close()
|
||||
isOpen = false
|
||||
@ -227,14 +238,23 @@ internal class DefaultSession @Inject constructor(
|
||||
stopSync()
|
||||
stopAnyBackgroundSync()
|
||||
uiHandler.post {
|
||||
lifecycleObservers.forEach { it.onClearCache() }
|
||||
lifecycleObservers.forEach {
|
||||
it.onClearCache(this)
|
||||
}
|
||||
sessionListeners.dispatch {
|
||||
it.onClearCache(this)
|
||||
}
|
||||
}
|
||||
withContext(NonCancellable) {
|
||||
cacheService.get().clearCache()
|
||||
}
|
||||
cacheService.get().clearCache()
|
||||
workManagerProvider.cancelAllWorks()
|
||||
}
|
||||
|
||||
override fun onGlobalError(globalError: GlobalError) {
|
||||
sessionListeners.dispatchGlobalError(globalError)
|
||||
sessionListeners.dispatch {
|
||||
it.onGlobalError(this, globalError)
|
||||
}
|
||||
}
|
||||
|
||||
override fun contentUrlResolver() = contentUrlResolver
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.session
|
||||
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import javax.inject.Inject
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
|
||||
@SessionScope
|
||||
internal class SessionCoroutineScopeHolder @Inject constructor(): SessionLifecycleObserver {
|
||||
|
||||
val scope: CoroutineScope = CoroutineScope(SupervisorJob())
|
||||
|
||||
override fun onSessionStopped(session: Session) {
|
||||
scope.cancelChildren()
|
||||
}
|
||||
|
||||
override fun onClearCache(session: Session) {
|
||||
scope.cancelChildren()
|
||||
}
|
||||
|
||||
private fun CoroutineScope.cancelChildren() {
|
||||
coroutineContext.cancelChildren(CancellationException("Closing session"))
|
||||
}
|
||||
}
|
@ -16,7 +16,6 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session
|
||||
|
||||
import org.matrix.android.sdk.api.failure.GlobalError
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -36,10 +35,10 @@ internal class SessionListeners @Inject constructor() {
|
||||
}
|
||||
}
|
||||
|
||||
fun dispatchGlobalError(globalError: GlobalError) {
|
||||
fun dispatch(block: (Session.Listener) -> Unit) {
|
||||
synchronized(listeners) {
|
||||
listeners.forEach {
|
||||
it.onGlobalError(globalError)
|
||||
block(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.auth.data.SessionParams
|
||||
import org.matrix.android.sdk.api.auth.data.sessionId
|
||||
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.api.session.accountdata.AccountDataService
|
||||
import org.matrix.android.sdk.api.session.events.EventService
|
||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
||||
@ -343,6 +344,10 @@ internal abstract class SessionModule {
|
||||
@IntoSet
|
||||
abstract fun bindRealmSessionProvider(provider: RealmSessionProvider): SessionLifecycleObserver
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
abstract fun bindSessionCoroutineScopeHolder(holder: SessionCoroutineScopeHolder): SessionLifecycleObserver
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
abstract fun bindEventSenderProcessorAsSessionLifecycleObserver(processor: EventSenderProcessorCoroutine): SessionLifecycleObserver
|
||||
|
@ -36,7 +36,7 @@ import org.matrix.android.sdk.internal.di.AuthenticatedIdentity
|
||||
import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate
|
||||
import org.matrix.android.sdk.internal.extensions.observeNotNull
|
||||
import org.matrix.android.sdk.internal.network.RetrofitFactory
|
||||
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import org.matrix.android.sdk.internal.session.identity.data.IdentityStore
|
||||
import org.matrix.android.sdk.internal.session.openid.GetOpenIdTokenTask
|
||||
@ -51,6 +51,7 @@ import org.matrix.android.sdk.internal.util.ensureProtocol
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.OkHttpClient
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
@ -86,7 +87,7 @@ internal class DefaultIdentityService @Inject constructor(
|
||||
|
||||
private val listeners = mutableSetOf<IdentityServiceListener>()
|
||||
|
||||
override fun onSessionStarted() {
|
||||
override fun onSessionStarted(session: Session) {
|
||||
lifecycleRegistry.currentState = Lifecycle.State.STARTED
|
||||
// Observe the account data change
|
||||
accountDataDataSource
|
||||
@ -111,7 +112,7 @@ internal class DefaultIdentityService @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSessionStopped() {
|
||||
override fun onSessionStopped(session: Session) {
|
||||
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LifecycleRegistry
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import org.matrix.android.sdk.api.MatrixConfiguration
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerConfig
|
||||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
|
||||
@ -29,7 +30,7 @@ import org.matrix.android.sdk.api.session.widgets.model.WidgetType
|
||||
import org.matrix.android.sdk.internal.database.model.WellknownIntegrationManagerConfigEntity
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.extensions.observeNotNull
|
||||
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
|
||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
|
||||
@ -77,7 +78,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
|
||||
currentConfigs.add(defaultConfig)
|
||||
}
|
||||
|
||||
override fun onSessionStarted() {
|
||||
override fun onSessionStarted(session: Session) {
|
||||
lifecycleRegistry.currentState = Lifecycle.State.STARTED
|
||||
observeWellknownConfig()
|
||||
accountDataDataSource
|
||||
@ -105,7 +106,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSessionStopped() {
|
||||
override fun onSessionStopped(session: Session) {
|
||||
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.session.room.send.queue
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.util.Cancelable
|
||||
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
|
||||
internal interface EventSenderProcessor: SessionLifecycleObserver {
|
||||
|
||||
|
@ -25,6 +25,7 @@ import org.matrix.android.sdk.api.auth.data.SessionParams
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.failure.MatrixError
|
||||
import org.matrix.android.sdk.api.failure.getRetryDelay
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.util.Cancelable
|
||||
@ -72,7 +73,7 @@ internal class EventSenderProcessorCoroutine @Inject constructor(
|
||||
*/
|
||||
private val cancelableBag = ConcurrentHashMap<String, Cancelable>()
|
||||
|
||||
override fun onSessionStarted() {
|
||||
override fun onSessionStarted(session: Session) {
|
||||
// We should check for sending events not handled because app was killed
|
||||
// But we should be careful of only took those that was submitted to us, because if it's
|
||||
// for example it's a media event it is handled by some worker and he will handle it
|
||||
|
@ -25,6 +25,7 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.failure.MatrixError
|
||||
import org.matrix.android.sdk.api.failure.isTokenError
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.sync.SyncState
|
||||
@ -64,11 +65,11 @@ internal class EventSenderProcessorThread @Inject constructor(
|
||||
memento.unTrack(task)
|
||||
}
|
||||
|
||||
override fun onSessionStarted() {
|
||||
override fun onSessionStarted(session: Session) {
|
||||
start()
|
||||
}
|
||||
|
||||
override fun onSessionStopped() {
|
||||
override fun onSessionStopped(session: Session) {
|
||||
interrupt()
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,13 @@
|
||||
package org.matrix.android.sdk.internal.session.widgets
|
||||
|
||||
import org.matrix.android.sdk.api.MatrixConfiguration
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerConfig
|
||||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
|
||||
import org.matrix.android.sdk.api.session.widgets.WidgetURLFormatter
|
||||
import org.matrix.android.sdk.api.util.appendParamToUrl
|
||||
import org.matrix.android.sdk.api.util.appendParamsToUrl
|
||||
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
|
||||
import org.matrix.android.sdk.internal.session.widgets.token.GetScalarTokenTask
|
||||
@ -37,12 +38,12 @@ internal class DefaultWidgetURLFormatter @Inject constructor(private val integra
|
||||
private lateinit var currentConfig: IntegrationManagerConfig
|
||||
private var whiteListedUrls: List<String> = emptyList()
|
||||
|
||||
override fun onSessionStarted() {
|
||||
override fun onSessionStarted(session: Session) {
|
||||
setupWithConfiguration()
|
||||
integrationManager.addListener(this)
|
||||
}
|
||||
|
||||
override fun onSessionStopped() {
|
||||
override fun onSessionStopped(session: Session) {
|
||||
integrationManager.removeListener(this)
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import androidx.lifecycle.LifecycleRegistry
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
|
||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
|
||||
import org.matrix.android.sdk.api.session.events.model.Content
|
||||
@ -34,7 +35,7 @@ import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import org.matrix.android.sdk.api.session.widgets.WidgetManagementFailure
|
||||
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.api.session.SessionLifecycleObserver
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationManager
|
||||
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
|
||||
@ -57,12 +58,12 @@ internal class WidgetManager @Inject constructor(private val integrationManager:
|
||||
private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry }
|
||||
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner)
|
||||
|
||||
override fun onSessionStarted() {
|
||||
override fun onSessionStarted(session: Session) {
|
||||
lifecycleRegistry.currentState = Lifecycle.State.STARTED
|
||||
integrationManager.addListener(this)
|
||||
}
|
||||
|
||||
override fun onSessionStopped() {
|
||||
override fun onSessionStopped(session: Session) {
|
||||
integrationManager.removeListener(this)
|
||||
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ import com.bumptech.glide.signature.ObjectKey
|
||||
import im.vector.app.core.extensions.vectorComponent
|
||||
import im.vector.app.core.files.LocalFilesHelper
|
||||
import im.vector.app.features.media.ImageContentRenderer
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.OkHttpClient
|
||||
@ -115,7 +115,7 @@ class VectorGlideDataFetcher(context: Context,
|
||||
callback.onLoadFailed(IllegalArgumentException("No File service"))
|
||||
}
|
||||
// Use the file vector service, will avoid flickering and redownload after upload
|
||||
GlobalScope.launch {
|
||||
activeSessionHolder.getSafeActiveSession()?.coroutineScope?.launch {
|
||||
val result = runCatching {
|
||||
fileService.downloadFile(
|
||||
fileName = data.filename,
|
||||
|
@ -78,7 +78,6 @@ class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallContro
|
||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,6 @@ class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMee
|
||||
private val jitsiViewModel: JitsiCallViewModel by viewModel()
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,6 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>(),
|
||||
override fun getCoordinatorLayout() = views.vectorCoordinatorLayout
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,6 @@ class RoomDetailActivity :
|
||||
}
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
|
@ -161,6 +161,7 @@ import im.vector.app.features.permalink.NavigationInterceptor
|
||||
import im.vector.app.features.permalink.PermalinkHandler
|
||||
import im.vector.app.features.reactions.EmojiReactionPickerActivity
|
||||
import im.vector.app.features.roomprofile.RoomProfileActivity
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.features.settings.VectorSettingsActivity
|
||||
import im.vector.app.features.share.SharedData
|
||||
@ -1749,7 +1750,7 @@ class RoomDetailFragment @Inject constructor(
|
||||
sharedActionViewModel.pendingAction = action
|
||||
return
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
session.coroutineScope.launch {
|
||||
val result = runCatching { session.fileService().downloadFile(messageContent = action.messageContent) }
|
||||
if (!isAdded) return@launch
|
||||
result.fold(
|
||||
|
@ -53,13 +53,13 @@ import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
|
||||
import im.vector.app.features.home.room.typing.TypingHelper
|
||||
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
|
||||
import im.vector.app.features.raw.wellknown.getElementWellknown
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import im.vector.app.features.settings.VectorLocale
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.commonmark.parser.Parser
|
||||
@ -188,10 +188,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||
}
|
||||
// Inform the SDK that the room is displayed
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
session.onRoomDisplayed(initialState.roomId)
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
tryOrNull { session.onRoomDisplayed(initialState.roomId) }
|
||||
}
|
||||
callManager.addPstnSupportListener(this)
|
||||
callManager.checkForPSTNSupportIfNeeded()
|
||||
@ -574,7 +571,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||
* Convert a send mode to a draft and save the draft
|
||||
*/
|
||||
private fun handleSaveDraft(action: RoomDetailAction.SaveDraft) = withState {
|
||||
viewModelScope.launch(NonCancellable) {
|
||||
session.coroutineScope.launch {
|
||||
when {
|
||||
it.sendMode is SendMode.REGULAR && !it.sendMode.fromSharing -> {
|
||||
setState { copy(sendMode = it.sendMode.copy(action.draft)) }
|
||||
@ -1162,19 +1159,13 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||
|
||||
private fun handleRejectInvite() {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
room.leave(null)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
tryOrNull { room.leave(null) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleAcceptInvite() {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
room.join()
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
tryOrNull { room.join() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1327,7 +1318,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||
}
|
||||
}
|
||||
bufferedMostRecentDisplayedEvent.root.eventId?.let { eventId ->
|
||||
viewModelScope.launch {
|
||||
session.coroutineScope.launch {
|
||||
tryOrNull { room.setReadReceipt(eventId) }
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ class SearchActivity : VectorBaseActivity<ActivitySearchBinding>() {
|
||||
override fun getCoordinatorLayout() = views.coordinatorLayout
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ import androidx.core.app.RemoteInput
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.extensions.vectorComponent
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
@ -78,7 +78,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
||||
activeSessionHolder.getSafeActiveSession()?.let { session ->
|
||||
val room = session.getRoom(roomId)
|
||||
if (room != null) {
|
||||
GlobalScope.launch {
|
||||
session.coroutineScope.launch {
|
||||
tryOrNull { room.join() }
|
||||
}
|
||||
}
|
||||
@ -89,7 +89,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
||||
activeSessionHolder.getSafeActiveSession()?.let { session ->
|
||||
val room = session.getRoom(roomId)
|
||||
if (room != null) {
|
||||
GlobalScope.launch {
|
||||
session.coroutineScope.launch {
|
||||
tryOrNull { room.leave() }
|
||||
}
|
||||
}
|
||||
@ -100,7 +100,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
||||
activeSessionHolder.getActiveSession().let { session ->
|
||||
val room = session.getRoom(roomId)
|
||||
if (room != null) {
|
||||
GlobalScope.launch {
|
||||
session.coroutineScope.launch {
|
||||
tryOrNull { room.markAsRead(ReadService.MarkAsReadParams.READ_RECEIPT) }
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ class RoomMemberProfileActivity :
|
||||
}
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,6 @@ class RoomProfileActivity :
|
||||
}
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.session
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
|
||||
private val sessionCoroutineScopes = HashMap<String, CoroutineScope>(1)
|
||||
|
||||
val Session.coroutineScope: CoroutineScope
|
||||
get() {
|
||||
return synchronized(sessionCoroutineScopes) {
|
||||
sessionCoroutineScopes.getOrPut(sessionId) {
|
||||
CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import im.vector.app.core.extensions.postLiveEvent
|
||||
import im.vector.app.core.utils.LiveEvent
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import org.matrix.android.sdk.api.failure.GlobalError
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import javax.inject.Inject
|
||||
@ -32,7 +33,15 @@ class SessionListener @Inject constructor() : Session.Listener {
|
||||
val globalErrorLiveData: LiveData<LiveEvent<GlobalError>>
|
||||
get() = _globalErrorLiveData
|
||||
|
||||
override fun onGlobalError(globalError: GlobalError) {
|
||||
override fun onGlobalError(session: Session, globalError: GlobalError) {
|
||||
_globalErrorLiveData.postLiveEvent(globalError)
|
||||
}
|
||||
|
||||
override fun onSessionStopped(session: Session) {
|
||||
session.coroutineScope.coroutineContext.cancelChildren()
|
||||
}
|
||||
|
||||
override fun onClearCache(session: Session) {
|
||||
session.coroutineScope.coroutineContext.cancelChildren()
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,8 @@ import androidx.activity.result.ActivityResultLauncher
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
@ -52,7 +52,7 @@ class TestAccountSettings @Inject constructor(private val stringProvider: String
|
||||
override fun doFix() {
|
||||
if (manager?.diagStatus == TestStatus.RUNNING) return // wait before all is finished
|
||||
|
||||
GlobalScope.launch {
|
||||
session.coroutineScope.launch {
|
||||
tryOrNull {
|
||||
session.updatePushRuleEnableStatus(RuleKind.OVERRIDE, defaultRule, !defaultRule.enabled)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user