diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt index f1e387beb3..16457ba95e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/ShieldTrustUpdater.kt @@ -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 { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt index 0312e6d4f0..c3ace55e1c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/RealmLiveEntityObserver.kt @@ -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(protected val realmConfiguration: RealmConfiguration) : LiveEntityObserver, OrderedRealmCollectionChangeListener> { @@ -49,7 +45,7 @@ internal abstract class RealmLiveEntityObserver(protected val r private val backgroundRealm = AtomicReference() private lateinit var results: AtomicReference> - 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(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(protected val r } } - override fun cancelProcess() { + override fun onClearCache() { observerScope.coroutineContext.cancelChildren() } - - override fun isStarted(): Boolean { - return isStarted.get() - } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt index c95be9c000..da59e01907 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt @@ -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, private val roomDirectoryService: Lazy, @@ -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 { @@ -217,7 +210,9 @@ internal class DefaultSession @Inject constructor( override fun clearCache(callback: MatrixCallback) { stopSync() stopAnyBackgroundSync() - liveEntityObservers.forEach { it.cancelProcess() } + uiHandler.post { + lifecycleObservers.forEach { it.onClearCache() } + } cacheService.get().clearCache(callback) workManagerProvider.cancelAllWorks() } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionLifecycleObserver.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionLifecycleObserver.kt new file mode 100644 index 0000000000..92af3c1fe1 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionLifecycleObserver.kt @@ -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 + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index ee52934ff3..e911d720aa 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -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 diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt index 00c4c48a6d..4afd045d0f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/identity/DefaultIdentityService.kt @@ -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() - 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 } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/integrationmanager/IntegrationManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/integrationmanager/IntegrationManager.kt index f1351c1a7c..ac50f2118a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/integrationmanager/IntegrationManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/integrationmanager/IntegrationManager.kt @@ -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() 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 } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/DefaultWidgetURLFormatter.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/DefaultWidgetURLFormatter.kt index 0cf99b6021..ffdc05203a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/DefaultWidgetURLFormatter.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/DefaultWidgetURLFormatter.kt @@ -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 = emptyList() - fun start() { + override fun onStart() { setupWithConfiguration() integrationManager.addListener(this) } - fun stop() { + override fun onStop() { integrationManager.removeListener(this) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetDependenciesHolder.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetDependenciesHolder.kt deleted file mode 100644 index 42a8b7e8d2..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetDependenciesHolder.kt +++ /dev/null @@ -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() - } -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt index 8d13f53190..e4f7796d31 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/widgets/WidgetManager.kt @@ -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 }