Skip to content

Commit

Permalink
Merge pull request #841 from embrace-io/update-lifecycle-owner
Browse files Browse the repository at this point in the history
Update lifecycle owner dependency
  • Loading branch information
fractalwrench committed May 14, 2024
2 parents 04ad926 + ca009cd commit 76ab112
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 36 deletions.
3 changes: 3 additions & 0 deletions buildSrc/src/main/kotlin/io/embrace/gradle/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,7 @@ object Versions {

@JvmField
val moshi = "1.12.0"

@JvmField
val lifecycle = "2.7.0"
}
4 changes: 2 additions & 2 deletions embrace-android-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ koverReport {
}

dependencies {
implementation "androidx.lifecycle:lifecycle-common-java8:2.5.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
implementation "androidx.lifecycle:lifecycle-common-java8:${Versions.lifecycle}"
implementation "androidx.lifecycle:lifecycle-process:${Versions.lifecycle}"

// json
implementation("com.squareup.moshi:moshi:${Versions.moshi}")
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.
Expand All @@ -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 {
Expand All @@ -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.")

Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
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

internal class FakeProcessStateService(
override var isInBackground: Boolean = false,
) : ProcessStateService {

override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
}

val listeners: MutableList<ProcessStateListener> = mutableListOf()
var config: Configuration? = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import android.content.res.Configuration
import android.content.res.Resources
import android.os.Bundle
import android.os.Looper
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeOrientationService
import io.embrace.android.embracesdk.fakes.system.mockApplication
Expand Down Expand Up @@ -38,27 +35,19 @@ internal class ActivityLifecycleTrackerTest {

companion object {
private lateinit var mockLooper: Looper
private lateinit var mockLifeCycleOwner: LifecycleOwner
private lateinit var mockLifecycle: Lifecycle
private lateinit var application: Application
private val fakeClock = FakeClock()

@BeforeClass
@JvmStatic
fun beforeClass() {
mockLooper = mockLooper()
mockLifeCycleOwner = mockk()
mockLifecycle = mockk(relaxed = true)
mockkStatic(Looper::class)
mockkStatic(ProcessLifecycleOwner::class)
application = mockApplication()

fakeClock.setCurrentTime(1234)
every { application.registerActivityLifecycleCallbacks(any()) } returns Unit
every { Looper.getMainLooper() } returns mockLooper
every { ProcessLifecycleOwner.get() } returns mockLifeCycleOwner
every { mockLifeCycleOwner.lifecycle } returns mockLifecycle
every { mockLifecycle.addObserver(any()) } returns Unit
}

@JvmStatic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package io.embrace.android.embracesdk.session
import android.app.Application
import android.os.Looper
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeEmbLogger
import io.embrace.android.embracesdk.fakes.FakeProcessStateListener
Expand Down Expand Up @@ -32,27 +30,19 @@ internal class EmbraceProcessStateServiceTest {

companion object {
private lateinit var looper: Looper
private lateinit var mockLifeCycleOwner: LifecycleOwner
private lateinit var mockLifecycle: Lifecycle
private lateinit var mockApplication: Application
private val fakeClock = FakeClock()

@BeforeClass
@JvmStatic
fun beforeClass() {
looper = mockLooper()
mockLifeCycleOwner = mockk()
mockLifecycle = mockk(relaxed = true)
mockkStatic(Looper::class)
mockkStatic(ProcessLifecycleOwner::class)
mockApplication = mockk(relaxed = true)

fakeClock.setCurrentTime(1234)
every { mockApplication.registerActivityLifecycleCallbacks(any()) } returns Unit
every { Looper.getMainLooper() } returns looper
every { ProcessLifecycleOwner.get() } returns mockLifeCycleOwner
every { mockLifeCycleOwner.lifecycle } returns mockLifecycle
every { mockLifecycle.addObserver(any()) } returns Unit
}

@JvmStatic
Expand Down Expand Up @@ -228,6 +218,34 @@ internal class EmbraceProcessStateServiceTest {
assertTrue(messages.isEmpty())
}

@Test
fun `launched in background`() {
stateService = EmbraceProcessStateService(
fakeClock,
fakeEmbLogger,
mockk {
every { lifecycle } returns mockk<Lifecycle> {
every { currentState } returns Lifecycle.State.INITIALIZED
}
}
)
assertTrue(stateService.isInBackground)
}

@Test
fun `launched in foreground`() {
stateService = EmbraceProcessStateService(
fakeClock,
fakeEmbLogger,
mockk {
every { lifecycle } returns mockk<Lifecycle> {
every { currentState } returns Lifecycle.State.STARTED
}
}
)
assertFalse(stateService.isInBackground)
}

private class DecoratedListener(
private val invocations: MutableList<String>
) : ProcessStateListener {
Expand Down

0 comments on commit 76ab112

Please sign in to comment.