Creates SessionLifecycleObserver

This commit is contained in:
ganfra 2020-06-23 15:12:25 +02:00
parent 6b13c00d56
commit 360666a758
10 changed files with 124 additions and 90 deletions

View file

@ -21,6 +21,7 @@ import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityF
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import im.vector.matrix.android.internal.task.TaskExecutor
@ -42,7 +43,7 @@ internal class ShieldTrustUpdater @Inject constructor(
private val taskExecutor: TaskExecutor,
@SessionDatabase private val sessionRealmConfiguration: RealmConfiguration,
private val roomSummaryUpdater: RoomSummaryUpdater
) {
): SessionLifecycleObserver {
companion object {
private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD")
@ -53,7 +54,7 @@ internal class ShieldTrustUpdater @Inject constructor(
private val isStarted = AtomicBoolean()
fun start() {
override fun onStart() {
if (isStarted.compareAndSet(false, true)) {
eventBus.register(this)
BACKGROUND_HANDLER.post {
@ -62,7 +63,7 @@ internal class ShieldTrustUpdater @Inject constructor(
}
}
fun stop() {
override fun onStop() {
if (isStarted.compareAndSet(true, false)) {
eventBus.unregister(this)
BACKGROUND_HANDLER.post {

View file

@ -17,6 +17,7 @@
package im.vector.matrix.android.internal.database
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.util.createBackgroundHandler
import io.realm.OrderedRealmCollectionChangeListener
import io.realm.Realm
@ -29,12 +30,7 @@ import kotlinx.coroutines.cancelChildren
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
internal interface LiveEntityObserver {
fun start()
fun dispose()
fun cancelProcess()
fun isStarted(): Boolean
}
internal interface LiveEntityObserver: SessionLifecycleObserver
internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val realmConfiguration: RealmConfiguration)
: LiveEntityObserver, OrderedRealmCollectionChangeListener<RealmResults<T>> {
@ -49,7 +45,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
private val backgroundRealm = AtomicReference<Realm>()
private lateinit var results: AtomicReference<RealmResults<T>>
override fun start() {
override fun onStart() {
if (isStarted.compareAndSet(false, true)) {
BACKGROUND_HANDLER.post {
val realm = Realm.getInstance(realmConfiguration)
@ -61,7 +57,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
}
}
override fun dispose() {
override fun onStop() {
if (isStarted.compareAndSet(true, false)) {
BACKGROUND_HANDLER.post {
results.getAndSet(null).removeAllChangeListeners()
@ -73,11 +69,7 @@ internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val r
}
}
override fun cancelProcess() {
override fun onClearCache() {
observerScope.coroutineContext.cancelChildren()
}
override fun isStarted(): Boolean {
return isStarted.get()
}
}

View file

@ -50,8 +50,6 @@ import im.vector.matrix.android.api.session.user.UserService
import im.vector.matrix.android.api.session.widgets.WidgetService
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.crypto.DefaultCryptoService
import im.vector.matrix.android.internal.crypto.crosssigning.ShieldTrustUpdater
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.di.WorkManagerProvider
import im.vector.matrix.android.internal.session.identity.DefaultIdentityService
@ -59,9 +57,9 @@ import im.vector.matrix.android.internal.session.room.timeline.TimelineEventDecr
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
import im.vector.matrix.android.internal.session.sync.job.SyncThread
import im.vector.matrix.android.internal.session.sync.job.SyncWorker
import im.vector.matrix.android.internal.session.widgets.WidgetDependenciesHolder
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import im.vector.matrix.android.internal.util.createUIHandler
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
@ -78,7 +76,7 @@ internal class DefaultSession @Inject constructor(
private val eventBus: EventBus,
@SessionId
override val sessionId: String,
private val liveEntityObservers: Set<@JvmSuppressWildcards LiveEntityObserver>,
private val lifecycleObservers: Set<@JvmSuppressWildcards SessionLifecycleObserver>,
private val sessionListeners: SessionListeners,
private val roomService: Lazy<RoomService>,
private val roomDirectoryService: Lazy<RoomDirectoryService>,
@ -110,9 +108,7 @@ internal class DefaultSession @Inject constructor(
private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val defaultIdentityService: DefaultIdentityService,
private val integrationManagerService: IntegrationManagerService,
private val taskExecutor: TaskExecutor,
private val widgetDependenciesHolder: WidgetDependenciesHolder,
private val shieldTrustUpdater: ShieldTrustUpdater)
private val taskExecutor: TaskExecutor)
: Session,
RoomService by roomService.get(),
RoomDirectoryService by roomDirectoryService.get(),
@ -138,6 +134,8 @@ internal class DefaultSession @Inject constructor(
private var syncThread: SyncThread? = null
private val uiHandler = createUIHandler()
override val isOpenable: Boolean
get() = sessionParamsStore.get(sessionId)?.isTokenValid ?: false
@ -145,12 +143,11 @@ internal class DefaultSession @Inject constructor(
override fun open() {
assert(!isOpen)
isOpen = true
liveEntityObservers.forEach { it.start() }
uiHandler.post {
lifecycleObservers.forEach { it.onStart() }
}
eventBus.register(this)
timelineEventDecryptor.start()
shieldTrustUpdater.start()
defaultIdentityService.start()
widgetDependenciesHolder.start()
}
override fun requireBackgroundSync() {
@ -188,16 +185,12 @@ internal class DefaultSession @Inject constructor(
assert(isOpen)
stopSync()
timelineEventDecryptor.destroy()
liveEntityObservers.forEach { it.dispose() }
uiHandler.post {
lifecycleObservers.forEach { it.onStop() }
}
cryptoService.get().close()
isOpen = false
eventBus.unregister(this)
shieldTrustUpdater.stop()
taskExecutor.executorScope.launch(coroutineDispatchers.main) {
// This has to be done on main thread
defaultIdentityService.stop()
widgetDependenciesHolder.stop()
}
}
override fun getSyncStateLive(): LiveData<SyncState> {
@ -217,7 +210,9 @@ internal class DefaultSession @Inject constructor(
override fun clearCache(callback: MatrixCallback<Unit>) {
stopSync()
stopAnyBackgroundSync()
liveEntityObservers.forEach { it.cancelProcess() }
uiHandler.post {
lifecycleObservers.forEach { it.onClearCache() }
}
cacheService.get().clearCache(callback)
workManagerProvider.cancelAllWorks()
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.internal.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 {
/*
Called when the session is opened
*/
@MainThread
fun onStart(){
//noop
}
/*
Called when the session is cleared
*/
@MainThread
fun onClearCache(){
//noop
}
/*
Called when the session is closed
*/
@MainThread
fun onStop() {
//noop
}
}

View file

@ -37,6 +37,8 @@ import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesSer
import im.vector.matrix.android.api.session.securestorage.SecureStorageService
import im.vector.matrix.android.api.session.securestorage.SharedSecretStorageService
import im.vector.matrix.android.api.session.typing.TypingUsersTracker
import im.vector.matrix.android.api.session.widgets.WidgetURLFormatter
import im.vector.matrix.android.internal.crypto.crosssigning.ShieldTrustUpdater
import im.vector.matrix.android.internal.crypto.secrets.DefaultSharedSecretStorageService
import im.vector.matrix.android.internal.crypto.verification.VerificationMessageLiveObserver
import im.vector.matrix.android.internal.database.LiveEntityObserver
@ -63,6 +65,8 @@ import im.vector.matrix.android.internal.network.token.AccessTokenProvider
import im.vector.matrix.android.internal.network.token.HomeserverAccessTokenProvider
import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater
import im.vector.matrix.android.internal.session.homeserver.DefaultHomeServerCapabilitiesService
import im.vector.matrix.android.internal.session.identity.DefaultIdentityService
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager
import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater
import im.vector.matrix.android.internal.session.room.create.RoomCreateEventLiveObserver
import im.vector.matrix.android.internal.session.room.prune.EventsPruner
@ -70,6 +74,8 @@ import im.vector.matrix.android.internal.session.room.tombstone.RoomTombstoneEve
import im.vector.matrix.android.internal.session.securestorage.DefaultSecureStorageService
import im.vector.matrix.android.internal.session.typing.DefaultTypingUsersTracker
import im.vector.matrix.android.internal.session.user.accountdata.DefaultAccountDataService
import im.vector.matrix.android.internal.session.widgets.DefaultWidgetURLFormatter
import im.vector.matrix.android.internal.session.widgets.WidgetManager
import im.vector.matrix.android.internal.util.md5
import io.realm.RealmConfiguration
import okhttp3.OkHttpClient
@ -236,27 +242,48 @@ internal abstract class SessionModule {
@Binds
@IntoSet
abstract fun bindGroupSummaryUpdater(updater: GroupSummaryUpdater): LiveEntityObserver
abstract fun bindGroupSummaryUpdater(updater: GroupSummaryUpdater): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindEventsPruner(pruner: EventsPruner): LiveEntityObserver
abstract fun bindEventsPruner(pruner: EventsPruner): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindEventRelationsAggregationUpdater(updater: EventRelationsAggregationUpdater): LiveEntityObserver
abstract fun bindEventRelationsAggregationUpdater(updater: EventRelationsAggregationUpdater): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindRoomTombstoneEventLiveObserver(observer: RoomTombstoneEventLiveObserver): LiveEntityObserver
abstract fun bindRoomTombstoneEventLiveObserver(observer: RoomTombstoneEventLiveObserver): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindRoomCreateEventLiveObserver(observer: RoomCreateEventLiveObserver): LiveEntityObserver
abstract fun bindRoomCreateEventLiveObserver(observer: RoomCreateEventLiveObserver): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindVerificationMessageLiveObserver(observer: VerificationMessageLiveObserver): LiveEntityObserver
abstract fun bindVerificationMessageLiveObserver(observer: VerificationMessageLiveObserver): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindWidgetManager(observer: WidgetManager): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindIntegrationManager(observer: IntegrationManager): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindWidgetUrlFormatter(observer: DefaultWidgetURLFormatter): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindShieldTrustUpdated(observer: ShieldTrustUpdater): SessionLifecycleObserver
@Binds
@IntoSet
abstract fun bindIdentityService(observer: DefaultIdentityService): SessionLifecycleObserver
@Binds
abstract fun bindInitialSyncProgressService(service: DefaultInitialSyncProgressService): InitialSyncProgressService

View file

@ -39,6 +39,7 @@ import im.vector.matrix.android.internal.di.AuthenticatedIdentity
import im.vector.matrix.android.internal.di.Unauthenticated
import im.vector.matrix.android.internal.extensions.observeNotNull
import im.vector.matrix.android.internal.network.RetrofitFactory
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.identity.data.IdentityStore
import im.vector.matrix.android.internal.session.openid.GetOpenIdTokenTask
@ -82,14 +83,14 @@ internal class DefaultIdentityService @Inject constructor(
private val homeServerCapabilitiesService: HomeServerCapabilitiesService,
private val sessionParams: SessionParams,
private val taskExecutor: TaskExecutor
) : IdentityService {
) : IdentityService, SessionLifecycleObserver {
private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry }
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner)
private val listeners = mutableSetOf<IdentityServiceListener>()
fun start() {
override fun onStart() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED
// Observe the account data change
accountDataDataSource
@ -114,7 +115,7 @@ internal class DefaultIdentityService @Inject constructor(
}
}
fun stop() {
override fun onStop() {
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
}

View file

@ -32,6 +32,7 @@ import im.vector.matrix.android.api.util.NoOpCancellable
import im.vector.matrix.android.internal.database.model.WellknownIntegrationManagerConfigEntity
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.extensions.observeNotNull
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
@ -62,7 +63,8 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
@SessionDatabase private val monarchy: Monarchy,
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
private val accountDataDataSource: AccountDataDataSource,
private val widgetFactory: WidgetFactory) {
private val widgetFactory: WidgetFactory)
: SessionLifecycleObserver {
private val currentConfigs = ArrayList<IntegrationManagerConfig>()
private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry }
@ -81,7 +83,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
currentConfigs.add(defaultConfig)
}
fun start() {
override fun onStart() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED
observeWellknownConfig()
accountDataDataSource
@ -109,7 +111,7 @@ internal class IntegrationManager @Inject constructor(matrixConfiguration: Matri
}
}
fun stop() {
override fun onStop() {
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
}

View file

@ -20,6 +20,7 @@ import im.vector.matrix.android.api.MatrixConfiguration
import im.vector.matrix.android.api.session.integrationmanager.IntegrationManagerConfig
import im.vector.matrix.android.api.session.integrationmanager.IntegrationManagerService
import im.vector.matrix.android.api.session.widgets.WidgetURLFormatter
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager
import im.vector.matrix.android.internal.session.widgets.token.GetScalarTokenTask
@ -30,17 +31,17 @@ import javax.inject.Inject
internal class DefaultWidgetURLFormatter @Inject constructor(private val integrationManager: IntegrationManager,
private val getScalarTokenTask: GetScalarTokenTask,
private val matrixConfiguration: MatrixConfiguration
) : IntegrationManagerService.Listener, WidgetURLFormatter {
) : IntegrationManagerService.Listener, WidgetURLFormatter, SessionLifecycleObserver {
private lateinit var currentConfig: IntegrationManagerConfig
private var whiteListedUrls: List<String> = emptyList()
fun start() {
override fun onStart() {
setupWithConfiguration()
integrationManager.addListener(this)
}
fun stop() {
override fun onStop() {
integrationManager.removeListener(this)
}

View file

@ -1,37 +0,0 @@
/*
* Copyright (c) 2020 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.matrix.android.internal.session.widgets
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager
import javax.inject.Inject
internal class WidgetDependenciesHolder @Inject constructor(private val integrationManager: IntegrationManager,
private val widgetManager: WidgetManager,
private val widgetURLFormatter: DefaultWidgetURLFormatter) {
fun start() {
integrationManager.start()
widgetManager.start()
widgetURLFormatter.start()
}
fun stop() {
widgetURLFormatter.stop()
widgetManager.stop()
integrationManager.stop()
}
}

View file

@ -34,6 +34,7 @@ import im.vector.matrix.android.api.session.widgets.WidgetManagementFailure
import im.vector.matrix.android.api.session.widgets.model.Widget
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.SessionLifecycleObserver
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.integrationmanager.IntegrationManager
import im.vector.matrix.android.internal.session.room.state.StateEventDataSource
@ -54,17 +55,19 @@ internal class WidgetManager @Inject constructor(private val integrationManager:
private val taskExecutor: TaskExecutor,
private val createWidgetTask: CreateWidgetTask,
private val widgetFactory: WidgetFactory,
@UserId private val userId: String) : IntegrationManagerService.Listener {
@UserId private val userId: String)
: IntegrationManagerService.Listener, SessionLifecycleObserver {
private val lifecycleOwner: LifecycleOwner = LifecycleOwner { lifecycleRegistry }
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(lifecycleOwner)
fun start() {
override fun onStart() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED
integrationManager.addListener(this)
}
fun stop() {
override fun onStop() {
integrationManager.removeListener(this)
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
}