diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/session/lifecycle/EmbraceProcessStateService.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/session/lifecycle/EmbraceProcessStateService.kt index 03d0102193..04b7d7a625 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/session/lifecycle/EmbraceProcessStateService.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/session/lifecycle/EmbraceProcessStateService.kt @@ -1,9 +1,8 @@ -@file:Suppress("DEPRECATION") - package io.embrace.android.embracesdk.session.lifecycle import androidx.lifecycle.Lifecycle -import androidx.lifecycle.OnLifecycleEvent +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner import io.embrace.android.embracesdk.internal.clock.Clock import io.embrace.android.embracesdk.logging.EmbLogger @@ -19,8 +18,9 @@ import java.util.concurrent.CopyOnWriteArrayList */ internal class EmbraceProcessStateService( private val clock: Clock, - private val logger: EmbLogger -) : ProcessStateService { + private val logger: EmbLogger, + private val lifecycleOwner: LifecycleOwner = ProcessLifecycleOwner.get() +) : ProcessStateService, LifecycleEventObserver { /** * List of listeners that subscribe to process lifecycle events. @@ -39,8 +39,7 @@ internal class EmbraceProcessStateService( * Returns if the app's in background or not. */ @Volatile - // TODO: future: investigate setting via ProcessLifecycleOwner initial state - override var isInBackground = true + override var isInBackground = !lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) private set init { @@ -49,17 +48,25 @@ internal class EmbraceProcessStateService( ThreadUtils.runOnMainThread( logger, Runnable { - ProcessLifecycleOwner.get().lifecycle - .addObserver(this@EmbraceProcessStateService) + lifecycleOwner.lifecycle.addObserver(this) } ) } + override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) { + when (event) { + Lifecycle.Event.ON_START -> onForeground() + Lifecycle.Event.ON_STOP -> onBackground() + else -> { + // no-op + } + } + } + /** * This method will be called by the ProcessLifecycleOwner when the main app process calls * ON START. */ - @OnLifecycleEvent(Lifecycle.Event.ON_START) override fun onForeground() { logger.logDebug("AppState: App entered foreground.") @@ -84,7 +91,6 @@ internal class EmbraceProcessStateService( * This method will be called by the ProcessLifecycleOwner when the main app process calls * ON STOP. */ - @OnLifecycleEvent(Lifecycle.Event.ON_STOP) override fun onBackground() { logger.logDebug("AppState: App entered background") isInBackground = true diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/session/lifecycle/ProcessStateService.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/session/lifecycle/ProcessStateService.kt index 5c6b5c98c3..6e813d8191 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/session/lifecycle/ProcessStateService.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/session/lifecycle/ProcessStateService.kt @@ -1,12 +1,12 @@ package io.embrace.android.embracesdk.session.lifecycle -import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.LifecycleEventObserver import java.io.Closeable /** * Service which handles Android process lifecycle callbacks. */ -internal interface ProcessStateService : LifecycleObserver, Closeable { +internal interface ProcessStateService : LifecycleEventObserver, Closeable { /** * Whether the application is in the background. diff --git a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/fakes/FakeProcessStateService.kt b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/fakes/FakeProcessStateService.kt index ebd4d24660..4d24019ba8 100644 --- a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/fakes/FakeProcessStateService.kt +++ b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/fakes/FakeProcessStateService.kt @@ -1,6 +1,8 @@ package io.embrace.android.embracesdk.fakes import android.content.res.Configuration +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner import io.embrace.android.embracesdk.session.lifecycle.ProcessStateListener import io.embrace.android.embracesdk.session.lifecycle.ProcessStateService @@ -8,6 +10,9 @@ internal class FakeProcessStateService( override var isInBackground: Boolean = false, ) : ProcessStateService { + override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) { + } + val listeners: MutableList = mutableListOf() var config: Configuration? = null diff --git a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/session/EmbraceProcessStateServiceTest.kt b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/session/EmbraceProcessStateServiceTest.kt index c4d7872b22..3be82e81a6 100644 --- a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/session/EmbraceProcessStateServiceTest.kt +++ b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/session/EmbraceProcessStateServiceTest.kt @@ -2,6 +2,7 @@ package io.embrace.android.embracesdk.session import android.app.Application import android.os.Looper +import androidx.lifecycle.Lifecycle import io.embrace.android.embracesdk.fakes.FakeClock import io.embrace.android.embracesdk.fakes.FakeEmbLogger import io.embrace.android.embracesdk.fakes.FakeProcessStateListener @@ -217,6 +218,34 @@ internal class EmbraceProcessStateServiceTest { assertTrue(messages.isEmpty()) } + @Test + fun `launched in background`() { + stateService = EmbraceProcessStateService( + fakeClock, + fakeEmbLogger, + mockk { + every { lifecycle } returns mockk { + every { currentState } returns Lifecycle.State.INITIALIZED + } + } + ) + assertTrue(stateService.isInBackground) + } + + @Test + fun `launched in foreground`() { + stateService = EmbraceProcessStateService( + fakeClock, + fakeEmbLogger, + mockk { + every { lifecycle } returns mockk { + every { currentState } returns Lifecycle.State.STARTED + } + } + ) + assertFalse(stateService.isInBackground) + } + private class DecoratedListener( private val invocations: MutableList ) : ProcessStateListener {