Skip to content
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