@@ -19,7 +19,6 @@ package com.google.firebase.sessions
1919import android.util.Log
2020import androidx.datastore.core.DataStore
2121import com.google.firebase.annotations.concurrent.Background
22- import com.google.firebase.sessions.ProcessDetailsProvider.getProcessName
2322import com.google.firebase.sessions.api.FirebaseSessionsDependencies
2423import com.google.firebase.sessions.api.SessionSubscriber
2524import com.google.firebase.sessions.settings.SessionsSettings
@@ -92,7 +91,7 @@ constructor(
9291 return
9392 }
9493 val sessionData = localSessionData
95- Log .d(TAG , " App backgrounded on ${getProcessName() } - $sessionData " )
94+ Log .d(TAG , " App backgrounded on ${processDataManager.myProcessName } - $sessionData " )
9695
9796 CoroutineScope (backgroundDispatcher).launch {
9897 try {
@@ -113,32 +112,57 @@ constructor(
113112 return
114113 }
115114 val sessionData = localSessionData
116- Log .d(TAG , " App foregrounded on ${getProcessName() } - $sessionData " )
115+ Log .d(TAG , " App foregrounded on ${processDataManager.myProcessName } - $sessionData " )
117116
118- if (shouldInitiateNewSession(sessionData)) {
117+ // Check if maybe the session data needs to be updated
118+ if (isSessionExpired(sessionData) || isMyProcessStale(sessionData)) {
119119 CoroutineScope (backgroundDispatcher).launch {
120120 try {
121121 sessionDataStore.updateData { currentSessionData ->
122- // Double-check pattern
123- if (shouldInitiateNewSession(currentSessionData)) {
122+ val isSessionExpired = isSessionExpired(currentSessionData)
123+ val isColdStart = isColdStart(currentSessionData)
124+ val isMyProcessStale = isMyProcessStale(currentSessionData)
125+
126+ val newProcessDataMap =
127+ if (isColdStart) {
128+ // Generate a new process data map for cold app start
129+ processDataManager.generateProcessDataMap()
130+ } else if (isMyProcessStale) {
131+ // Update the data map with this process if stale
132+ processDataManager.updateProcessDataMap(currentSessionData.processDataMap)
133+ } else {
134+ // No change
135+ currentSessionData.processDataMap
136+ }
137+
138+ // This is an expression, and returns the updated session data
139+ if (isSessionExpired || isColdStart) {
124140 val newSessionDetails =
125- sessionGenerator.generateNewSession(sessionData .sessionDetails)
141+ sessionGenerator.generateNewSession(currentSessionData .sessionDetails)
126142 sessionFirelogPublisher.mayLogSession(sessionDetails = newSessionDetails)
127143 processDataManager.onSessionGenerated()
128- currentSessionData.copy(sessionDetails = newSessionDetails, backgroundTime = null )
144+ currentSessionData.copy(
145+ sessionDetails = newSessionDetails,
146+ backgroundTime = null ,
147+ processDataMap = newProcessDataMap,
148+ )
149+ } else if (isMyProcessStale) {
150+ currentSessionData.copy(
151+ processDataMap = processDataManager.updateProcessDataMap(newProcessDataMap)
152+ )
129153 } else {
130154 currentSessionData
131155 }
132156 }
133157 } catch (ex: Exception ) {
134158 Log .d(TAG , " App appForegrounded, failed to update data. Message: ${ex.message} " )
135- val newSessionDetails = sessionGenerator.generateNewSession( sessionData.sessionDetails)
136- localSessionData =
137- localSessionData.copy(sessionDetails = newSessionDetails, backgroundTime = null )
138- sessionFirelogPublisher.mayLogSession (sessionDetails = newSessionDetails)
139-
140- val sessionId = newSessionDetails.sessionId
141- notifySubscribers(sessionId, NotificationType . FALLBACK )
159+ if (isSessionExpired( sessionData)) {
160+ val newSessionDetails = sessionGenerator.generateNewSession(sessionData.sessionDetails)
161+ localSessionData =
162+ sessionData.copy (sessionDetails = newSessionDetails, backgroundTime = null )
163+ sessionFirelogPublisher.mayLogSession(sessionDetails = newSessionDetails)
164+ notifySubscribers( newSessionDetails.sessionId, NotificationType . FALLBACK )
165+ }
142166 }
143167 }
144168 }
@@ -161,22 +185,47 @@ constructor(
161185 }
162186 }
163187
164- private fun shouldInitiateNewSession (sessionData : SessionData ): Boolean {
188+ /* * Checks if the session has expired. If no background time, consider it not expired. */
189+ private fun isSessionExpired (sessionData : SessionData ): Boolean {
165190 sessionData.backgroundTime?.let { backgroundTime ->
166191 val interval = timeProvider.currentTime() - backgroundTime
167- if (interval > sessionsSettings.sessionRestartTimeout) {
168- Log .d( TAG , " Passed session restart timeout, so initiate a new session " )
169- return true
192+ val sessionExpired = (interval > sessionsSettings.sessionRestartTimeout)
193+ if (sessionExpired) {
194+ Log .d( TAG , " Session ${sessionData.sessionDetails.sessionId} is expired " )
170195 }
196+ return sessionExpired
171197 }
172198
199+ Log .d(TAG , " Session ${sessionData.sessionDetails.sessionId} has not backgrounded yet" )
200+ return false
201+ }
202+
203+ /* * Checks for cold app start. If no process data map, consider it a cold start. */
204+ private fun isColdStart (sessionData : SessionData ): Boolean {
173205 sessionData.processDataMap?.let { processDataMap ->
174- Log .d(TAG , " Has not passed session restart timeout, so check for cold app start" )
175- return processDataManager.isColdStart(processDataMap)
206+ val coldStart = processDataManager.isColdStart(processDataMap)
207+ if (coldStart) {
208+ Log .d(TAG , " Cold app start detected" )
209+ }
210+ return coldStart
176211 }
177212
178- Log .d(TAG , " No process has backgrounded yet and no process data, should not change the session" )
179- return false
213+ Log .d(TAG , " No process data map" )
214+ return true
215+ }
216+
217+ /* * Checks if this process is stale. If no process data map, consider the process stale. */
218+ private fun isMyProcessStale (sessionData : SessionData ): Boolean {
219+ sessionData.processDataMap?.let { processDataMap ->
220+ val myProcessStale = processDataManager.isMyProcessStale(processDataMap)
221+ if (myProcessStale) {
222+ Log .d(TAG , " Process ${processDataManager.myProcessName} is stale" )
223+ }
224+ return myProcessStale
225+ }
226+
227+ Log .d(TAG , " No process data for ${processDataManager.myProcessName} " )
228+ return true
180229 }
181230
182231 private companion object {
0 commit comments