Skip to content

background time nullable #6886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ import kotlinx.serialization.json.Json

/** Session data to be persisted. */
@Serializable
internal data class SessionData(val sessionDetails: SessionDetails, val backgroundTime: Time)
internal data class SessionData(
val sessionDetails: SessionDetails,
val backgroundTime: Time? = null
)

/** DataStore json [Serializer] for [SessionData]. */
@Singleton
Expand All @@ -38,11 +41,7 @@ constructor(
private val timeProvider: TimeProvider,
) : Serializer<SessionData> {
override val defaultValue: SessionData
get() =
SessionData(
sessionDetails = sessionGenerator.generateNewSession(currentSession = null),
backgroundTime = timeProvider.currentTime(),
)
get() = SessionData(sessionGenerator.generateNewSession(currentSession = null))

override suspend fun readFrom(input: InputStream): SessionData =
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,13 @@ constructor(
internal var previousNotificationType: NotificationType = NotificationType.GENERAL

init {
println("session repo init")
CoroutineScope(backgroundDispatcher).launch {
sessionDataStore.data
.catch {
val newSession =
SessionData(
sessionDetails = sessionGenerator.generateNewSession(null),
backgroundTime = timeProvider.currentTime()
backgroundTime = null
)
Log.d(
TAG,
Expand Down Expand Up @@ -123,15 +122,16 @@ constructor(
val newSessionDetails =
sessionGenerator.generateNewSession(sessionData.sessionDetails)
sessionFirelogPublisher.mayLogSession(sessionDetails = newSessionDetails)
currentSessionData.copy(sessionDetails = newSessionDetails)
currentSessionData.copy(sessionDetails = newSessionDetails, backgroundTime = null)
} else {
currentSessionData
}
}
} catch (ex: Exception) {
Log.d(TAG, "App appForegrounded, failed to update data. Message: ${ex.message}")
val newSessionDetails = sessionGenerator.generateNewSession(sessionData.sessionDetails)
localSessionData = localSessionData.copy(sessionDetails = newSessionDetails)
localSessionData =
localSessionData.copy(sessionDetails = newSessionDetails, backgroundTime = null)
sessionFirelogPublisher.mayLogSession(sessionDetails = newSessionDetails)

val sessionId = newSessionDetails.sessionId
Expand Down Expand Up @@ -159,8 +159,12 @@ constructor(
}

private fun shouldInitiateNewSession(sessionData: SessionData): Boolean {
val interval = timeProvider.currentTime() - sessionData.backgroundTime
return interval > sessionsSettings.sessionRestartTimeout
sessionData.backgroundTime?.let {
val interval = timeProvider.currentTime() - it
return interval > sessionsSettings.sessionRestartTimeout
}
Log.d(TAG, "No process has backgrounded yet, should not change the session.")
return false
}

private companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import com.google.firebase.sessions.testing.FakeUuidGenerator
import kotlin.time.Duration.Companion.hours
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.After
Expand Down Expand Up @@ -135,7 +134,7 @@ class SharedSessionRepositoryTest {
}

@Test
fun appForegroundSharedSessionRepo_updateSuccess() = runTest {
fun appForegroundGenerateNewSession_updateSuccess() = runTest {
val sessionFirelogPublisher =
SessionFirelogPublisherImpl(
fakeFirebaseApp.firebaseApp,
Expand Down Expand Up @@ -166,20 +165,22 @@ class SharedSessionRepositoryTest {
backgroundDispatcher =
TestOnlyExecutors.background().asCoroutineDispatcher() + coroutineContext
)
backgroundScope.launch {
fakeTimeProvider.addInterval(20.hours)
sharedSessionRepository.appForeground()
}
runCurrent()

fakeTimeProvider.addInterval(20.hours)
sharedSessionRepository.appForeground()
runCurrent()

assertThat(sharedSessionRepository.localSessionData.sessionDetails.sessionId)
.isEqualTo(SESSION_ID_1)
assertThat(sharedSessionRepository.localSessionData.backgroundTime).isNull()
assertThat(sharedSessionRepository.previousNotificationType)
.isEqualTo(SharedSessionRepositoryImpl.NotificationType.GENERAL)
fakeDataStore.close()
}

@Test
fun appForegroundSharedSessionRepo_updateFail() = runTest {
fun appForegroundGenerateNewSession_updateFail() = runTest {
val sessionFirelogPublisher =
SessionFirelogPublisherImpl(
fakeFirebaseApp.firebaseApp,
Expand All @@ -201,7 +202,6 @@ class SharedSessionRepositoryTest {
),
IllegalArgumentException("Datastore init failed")
)
fakeDataStore.throwOnNextUpdateData(IllegalArgumentException("Datastore update failed"))
val sharedSessionRepository =
SharedSessionRepositoryImpl(
sessionsSettings,
Expand All @@ -212,15 +212,23 @@ class SharedSessionRepositoryTest {
backgroundDispatcher =
TestOnlyExecutors.background().asCoroutineDispatcher() + coroutineContext
)
runCurrent()

backgroundScope.launch {
fakeTimeProvider.addInterval(20.hours)
sharedSessionRepository.appForeground()
}
// set background time first
fakeDataStore.throwOnNextUpdateData(IllegalArgumentException("Datastore update failed"))
sharedSessionRepository.appBackground()
runCurrent()

// foreground update session
fakeTimeProvider.addInterval(20.hours)
fakeDataStore.throwOnNextUpdateData(IllegalArgumentException("Datastore update failed"))
sharedSessionRepository.appForeground()
runCurrent()

// session_2 here because session_1 is failed when try to init datastore
assertThat(sharedSessionRepository.localSessionData.sessionDetails.sessionId)
.isEqualTo(SESSION_ID_2)
assertThat(sharedSessionRepository.localSessionData.backgroundTime).isNull()
assertThat(sharedSessionRepository.previousNotificationType)
.isEqualTo(SharedSessionRepositoryImpl.NotificationType.FALLBACK)
fakeDataStore.close()
Expand Down
Loading