From 0a9845af306979c6f4c4305d56461aeb72a99e33 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 9 Nov 2021 16:56:51 +0100 Subject: [PATCH] @OnLifecycleEvent is deprecated, use DefaultLifecycleObserver instead --- .../util/BackgroundDetectionObserver.kt | 16 ++--- vector/build.gradle | 3 + .../java/im/vector/app/AppStateHandler.kt | 13 ++-- .../java/im/vector/app/VectorApplication.kt | 18 ++--- .../app/core/platform/LifecycleAwareLazy.kt | 70 +++++++++---------- .../call/conference/ConferenceEvent.kt | 15 ++-- .../features/call/webrtc/WebRtcCallManager.kt | 14 ++-- .../im/vector/app/features/pin/PinLocker.kt | 13 ++-- 8 files changed, 72 insertions(+), 90 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt index a12587ac56..3e977b31fb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt @@ -16,9 +16,8 @@ package org.matrix.android.sdk.internal.util -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleObserver -import androidx.lifecycle.OnLifecycleEvent +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner import org.matrix.android.sdk.internal.di.MatrixScope import timber.log.Timber import javax.inject.Inject @@ -27,13 +26,12 @@ import javax.inject.Inject * To be attached to ProcessLifecycleOwner lifecycle */ @MatrixScope -internal class BackgroundDetectionObserver @Inject constructor() : LifecycleObserver { +internal class BackgroundDetectionObserver @Inject constructor() : DefaultLifecycleObserver { var isInBackground: Boolean = true private set - private - val listeners = LinkedHashSet() + private val listeners = LinkedHashSet() fun register(listener: Listener) { listeners.add(listener) @@ -43,15 +41,13 @@ internal class BackgroundDetectionObserver @Inject constructor() : LifecycleObse listeners.remove(listener) } - @OnLifecycleEvent(Lifecycle.Event.ON_START) - fun onMoveToForeground() { + override fun onStart(owner: LifecycleOwner) { Timber.v("App returning to foreground…") isInBackground = false listeners.forEach { it.onMoveToForeground() } } - @OnLifecycleEvent(Lifecycle.Event.ON_STOP) - fun onMoveToBackground() { + override fun onStop(owner: LifecycleOwner) { Timber.v("App going to background…") isInBackground = true listeners.forEach { it.onMoveToBackground() } diff --git a/vector/build.gradle b/vector/build.gradle index 86d245a0a5..5d7cb27fec 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -356,7 +356,10 @@ dependencies { implementation libs.squareup.moshi kapt libs.squareup.moshiKotlin + + // Lifecycle implementation libs.androidx.lifecycleLivedata + implementation libs.androidx.lifecycleProcess implementation libs.androidx.datastore implementation libs.androidx.datastorepreferences diff --git a/vector/src/main/java/im/vector/app/AppStateHandler.kt b/vector/src/main/java/im/vector/app/AppStateHandler.kt index b6d41ce35d..9ed9dd5b23 100644 --- a/vector/src/main/java/im/vector/app/AppStateHandler.kt +++ b/vector/src/main/java/im/vector/app/AppStateHandler.kt @@ -16,9 +16,8 @@ package im.vector.app -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleObserver -import androidx.lifecycle.OnLifecycleEvent +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner import arrow.core.Option import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.utils.BehaviorDataSource @@ -57,7 +56,7 @@ class AppStateHandler @Inject constructor( private val sessionDataSource: ActiveSessionDataSource, private val uiStateRepository: UiStateRepository, private val activeSessionHolder: ActiveSessionHolder -) : LifecycleObserver { +) : DefaultLifecycleObserver { private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) private val selectedSpaceDataSource = BehaviorDataSource>(Option.empty()) @@ -133,13 +132,11 @@ class AppStateHandler @Inject constructor( return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary?.groupId } - @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) - fun entersForeground() { + override fun onResume(owner: LifecycleOwner) { observeActiveSession() } - @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) - fun entersBackground() { + override fun onPause(owner: LifecycleOwner) { coroutineScope.coroutineContext.cancelChildren() val session = activeSessionHolder.getSafeActiveSession() ?: return when (val currentMethod = selectedSpaceDataSource.currentValue?.orNull() ?: RoomGroupingMethod.BySpace(null)) { diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt index 80b397231b..c1d9eef125 100644 --- a/vector/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector/src/main/java/im/vector/app/VectorApplication.kt @@ -27,9 +27,8 @@ import android.os.HandlerThread import android.os.StrictMode import androidx.core.provider.FontRequest import androidx.core.provider.FontsContractCompat -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleObserver -import androidx.lifecycle.OnLifecycleEvent +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner import androidx.multidex.MultiDex import com.airbnb.epoxy.EpoxyAsyncUtil @@ -166,9 +165,8 @@ class VectorApplication : ProcessLifecycleOwner.get().lifecycle.addObserver(startSyncOnFirstStart) - ProcessLifecycleOwner.get().lifecycle.addObserver(object : LifecycleObserver { - @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) - fun entersForeground() { + ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver { + override fun onResume(owner: LifecycleOwner) { Timber.i("App entered foreground") FcmHelper.onEnterForeground(appContext, activeSessionHolder) activeSessionHolder.getSafeActiveSession()?.also { @@ -176,8 +174,7 @@ class VectorApplication : } } - @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) - fun entersBackground() { + override fun onPause(owner: LifecycleOwner) { Timber.i("App entered background") // call persistInfo notificationDrawerManager.persistInfo() FcmHelper.onEnterBackground(appContext, vectorPreferences, activeSessionHolder) @@ -198,9 +195,8 @@ class VectorApplication : EmojiManager.install(GoogleEmojiProvider()) } - private val startSyncOnFirstStart = object : LifecycleObserver { - @OnLifecycleEvent(Lifecycle.Event.ON_START) - fun onStart() { + private val startSyncOnFirstStart = object : DefaultLifecycleObserver { + override fun onStart(owner: LifecycleOwner) { Timber.i("App process started") authenticationService.getLastAuthenticatedSession()?.startSyncing(appContext) ProcessLifecycleOwner.get().lifecycle.removeObserver(this) diff --git a/vector/src/main/java/im/vector/app/core/platform/LifecycleAwareLazy.kt b/vector/src/main/java/im/vector/app/core/platform/LifecycleAwareLazy.kt index 283106232e..54add00459 100644 --- a/vector/src/main/java/im/vector/app/core/platform/LifecycleAwareLazy.kt +++ b/vector/src/main/java/im/vector/app/core/platform/LifecycleAwareLazy.kt @@ -18,58 +18,56 @@ package im.vector.app.core.platform import androidx.annotation.MainThread import androidx.fragment.app.Fragment +import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.OnLifecycleEvent fun LifecycleOwner.lifecycleAwareLazy(initializer: () -> T): Lazy = LifecycleAwareLazy(this, initializer) private object UninitializedValue class LifecycleAwareLazy( - private val owner: LifecycleOwner, - initializer: () -> T -) : Lazy, LifecycleObserver { + private val owner: LifecycleOwner, + initializer: () -> T +) : Lazy, DefaultLifecycleObserver { - private var initializer: (() -> T)? = initializer + private var initializer: (() -> T)? = initializer - private var _value: Any? = UninitializedValue + private var _value: Any? = UninitializedValue - @Suppress("UNCHECKED_CAST") - override val value: T - @MainThread - get() { - if (_value === UninitializedValue) { - _value = initializer!!() - attachToLifecycle() - } - return _value as T + @Suppress("UNCHECKED_CAST") + override val value: T + @MainThread + get() { + if (_value === UninitializedValue) { + _value = initializer!!() + attachToLifecycle() + } + return _value as T + } + + override fun onDestroy(owner: LifecycleOwner) { + _value = UninitializedValue + detachFromLifecycle() } - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) - fun resetValue() { - _value = UninitializedValue - detachFromLifecycle() - } - - private fun attachToLifecycle() { - if (getLifecycleOwner().lifecycle.currentState == Lifecycle.State.DESTROYED) { - throw IllegalStateException("Initialization failed because lifecycle has been destroyed!") + private fun attachToLifecycle() { + if (getLifecycleOwner().lifecycle.currentState == Lifecycle.State.DESTROYED) { + throw IllegalStateException("Initialization failed because lifecycle has been destroyed!") + } + getLifecycleOwner().lifecycle.addObserver(this) } - getLifecycleOwner().lifecycle.addObserver(this) - } - private fun detachFromLifecycle() { - getLifecycleOwner().lifecycle.removeObserver(this) - } + private fun detachFromLifecycle() { + getLifecycleOwner().lifecycle.removeObserver(this) + } - private fun getLifecycleOwner() = when (owner) { - is Fragment -> owner.viewLifecycleOwner - else -> owner - } + private fun getLifecycleOwner() = when (owner) { + is Fragment -> owner.viewLifecycleOwner + else -> owner + } - override fun isInitialized(): Boolean = _value !== UninitializedValue + override fun isInitialized(): Boolean = _value !== UninitializedValue - override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet." + override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet." } diff --git a/vector/src/main/java/im/vector/app/features/call/conference/ConferenceEvent.kt b/vector/src/main/java/im/vector/app/features/call/conference/ConferenceEvent.kt index 0a63ad6907..0d8e538eca 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/ConferenceEvent.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/ConferenceEvent.kt @@ -20,9 +20,8 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleObserver -import androidx.lifecycle.OnLifecycleEvent +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner import androidx.localbroadcastmanager.content.LocalBroadcastManager import com.facebook.react.bridge.JavaOnlyMap import org.jitsi.meet.sdk.BroadcastEmitter @@ -42,7 +41,7 @@ sealed class ConferenceEvent(open val data: Map) { } } -class ConferenceEventEmitter(private val context: Context) { +class ConferenceEventEmitter(private val context: Context) { fun emitConferenceEnded() { val broadcastEventData = JavaOnlyMap.of(CONFERENCE_URL_DATA_KEY, JitsiMeet.getCurrentConference()) @@ -52,7 +51,7 @@ class ConferenceEventEmitter(private val context: Context) { class ConferenceEventObserver(private val context: Context, private val onBroadcastEvent: (ConferenceEvent) -> Unit) : - LifecycleObserver { + DefaultLifecycleObserver { // See https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-android-sdk#listening-for-broadcasted-events private val broadcastReceiver = object : BroadcastReceiver() { @@ -61,8 +60,7 @@ class ConferenceEventObserver(private val context: Context, } } - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) - fun unregisterForBroadcastMessages() { + override fun onDestroy(owner: LifecycleOwner) { try { LocalBroadcastManager.getInstance(context).unregisterReceiver(broadcastReceiver) } catch (throwable: Throwable) { @@ -70,8 +68,7 @@ class ConferenceEventObserver(private val context: Context, } } - @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) - fun registerForBroadcastMessages() { + override fun onCreate(owner: LifecycleOwner) { val intentFilter = IntentFilter() for (type in BroadcastEvent.Type.values()) { intentFilter.addAction(type.action) diff --git a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt index 9e620174f3..80390a7dfb 100644 --- a/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt +++ b/vector/src/main/java/im/vector/app/features/call/webrtc/WebRtcCallManager.kt @@ -17,9 +17,8 @@ package im.vector.app.features.call.webrtc import android.content.Context -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleObserver -import androidx.lifecycle.OnLifecycleEvent +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner import im.vector.app.ActiveSessionDataSource import im.vector.app.BuildConfig import im.vector.app.core.services.CallService @@ -70,7 +69,8 @@ private val loggerTag = LoggerTag("WebRtcCallManager", LoggerTag.VOIP) class WebRtcCallManager @Inject constructor( private val context: Context, private val activeSessionDataSource: ActiveSessionDataSource -) : CallListener, LifecycleObserver { +) : CallListener, + DefaultLifecycleObserver { private val currentSession: Session? get() = activeSessionDataSource.currentValue?.orNull() @@ -133,13 +133,11 @@ class WebRtcCallManager @Inject constructor( private var isInBackground: Boolean = true - @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) - fun entersForeground() { + override fun onResume(owner: LifecycleOwner) { isInBackground = false } - @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) - fun entersBackground() { + override fun onPause(owner: LifecycleOwner) { isInBackground = true } diff --git a/vector/src/main/java/im/vector/app/features/pin/PinLocker.kt b/vector/src/main/java/im/vector/app/features/pin/PinLocker.kt index 9c55b88805..f848a3174e 100644 --- a/vector/src/main/java/im/vector/app/features/pin/PinLocker.kt +++ b/vector/src/main/java/im/vector/app/features/pin/PinLocker.kt @@ -17,11 +17,10 @@ package im.vector.app.features.pin import android.os.SystemClock -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.OnLifecycleEvent import im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -41,7 +40,7 @@ private const val PERIOD_OF_GRACE_IN_MS = 2 * 60 * 1000L class PinLocker @Inject constructor( private val pinCodeStore: PinCodeStore, private val vectorPreferences: VectorPreferences -) : LifecycleObserver { +) : DefaultLifecycleObserver { enum class State { // App is locked, can be unlock @@ -87,16 +86,14 @@ class PinLocker @Inject constructor( computeState() } - @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) - fun entersForeground() { + override fun onResume(owner: LifecycleOwner) { val timeElapsedSinceBackground = SystemClock.elapsedRealtime() - entersBackgroundTs shouldBeLocked = shouldBeLocked || timeElapsedSinceBackground >= getGracePeriod() Timber.v("App enters foreground after $timeElapsedSinceBackground ms spent in background shouldBeLocked: $shouldBeLocked") computeState() } - @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) - fun entersBackground() { + override fun onPause(owner: LifecycleOwner) { Timber.v("App enters background") entersBackgroundTs = SystemClock.elapsedRealtime() }