Skip to content

Commit d8fdd9e

Browse files
authored
Merge dd9ed1b into 97675ee
2 parents 97675ee + dd9ed1b commit d8fdd9e

File tree

10 files changed

+100
-82
lines changed

10 files changed

+100
-82
lines changed

firebase-sessions/api.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package com.google.firebase.sessions {
44
public final class FirebaseSessions {
55
method @NonNull public static com.google.firebase.sessions.FirebaseSessions getInstance();
66
method @NonNull public static com.google.firebase.sessions.FirebaseSessions getInstance(@NonNull com.google.firebase.FirebaseApp app);
7-
method @Discouraged(message="This will be replaced with a real API.") @NonNull public String greeting();
7+
method public void register(@NonNull com.google.firebase.sessions.api.SessionSubscriber subscriber);
88
property @NonNull public static final com.google.firebase.sessions.FirebaseSessions instance;
99
field @NonNull public static final com.google.firebase.sessions.FirebaseSessions.Companion Companion;
1010
}
@@ -16,4 +16,3 @@ package com.google.firebase.sessions {
1616
}
1717

1818
}
19-

firebase-sessions/src/androidTest/kotlin/com/google/firebase/sessions/FirebaseSessionsTests.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,8 @@ class FirebaseSessionsTests {
5353
}
5454

5555
@Test
56-
fun mattDoesDayHi() {
57-
// This will be replaced with real tests.
58-
assertThat(FirebaseSessions.instance.greeting()).isEqualTo("Matt says hi!")
56+
fun firebaseSessionsDoesInitialize() {
57+
assertThat(FirebaseSessions.instance).isNotNull()
5958
}
6059

6160
companion object {

firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessions.kt

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@ package com.google.firebase.sessions
1818

1919
import android.app.Application
2020
import android.util.Log
21-
import androidx.annotation.Discouraged
2221
import com.google.android.datatransport.TransportFactory
2322
import com.google.firebase.FirebaseApp
2423
import com.google.firebase.inject.Provider
2524
import com.google.firebase.installations.FirebaseInstallationsApi
2625
import com.google.firebase.ktx.Firebase
2726
import com.google.firebase.ktx.app
27+
import com.google.firebase.sessions.api.FirebaseSessionsDependencies
28+
import com.google.firebase.sessions.api.SessionSubscriber
2829
import com.google.firebase.sessions.settings.SessionsSettings
2930
import kotlinx.coroutines.CoroutineDispatcher
31+
import kotlinx.coroutines.CoroutineScope
32+
import kotlinx.coroutines.launch
3033

3134
class FirebaseSessions
3235
internal constructor(
@@ -47,9 +50,9 @@ internal constructor(
4750
)
4851
private val sessionGenerator = SessionGenerator(collectEvents = shouldCollectEvents())
4952
private val eventGDTLogger = EventGDTLogger(transportFactoryProvider)
50-
private val sessionCoordinator =
51-
SessionCoordinator(firebaseInstallations, backgroundDispatcher, eventGDTLogger)
53+
private val sessionCoordinator = SessionCoordinator(firebaseInstallations, eventGDTLogger)
5254
private val timeProvider: TimeProvider = Time()
55+
private val sessionStartScope = CoroutineScope(backgroundDispatcher)
5356

5457
init {
5558
sessionSettings.updateSettings()
@@ -66,20 +69,53 @@ internal constructor(
6669
}
6770
}
6871

69-
@Discouraged(message = "This will be replaced with a real API.")
70-
fun greeting(): String = "Matt says hi!"
72+
/** Register the [subscriber]. This must be called for every dependency. */
73+
fun register(subscriber: SessionSubscriber) {
74+
FirebaseSessionsDependencies.register(subscriber)
75+
76+
Log.d(
77+
TAG,
78+
"Registering Sessions SDK subscriber with name: ${subscriber.sessionSubscriberName}, " +
79+
"data collection enabled: ${subscriber.isDataCollectionEnabled}"
80+
)
81+
}
7182

7283
private fun initiateSessionStart() {
7384
val sessionDetails = sessionGenerator.generateNewSession()
7485

75-
if (!sessionGenerator.collectEvents) {
76-
Log.d(TAG, "Sessions SDK has sampled this session")
77-
return
78-
}
86+
sessionStartScope.launch {
87+
val subscribers = FirebaseSessionsDependencies.getRegisteredSubscribers()
7988

80-
sessionCoordinator.attemptLoggingSessionEvent(
81-
SessionEvents.startSession(firebaseApp, sessionDetails, sessionSettings, timeProvider)
82-
)
89+
if (subscribers.isEmpty()) {
90+
Log.d(
91+
TAG,
92+
"Sessions SDK did not have any dependent SDKs register as dependencies. Events will not be sent."
93+
)
94+
return@launch
95+
}
96+
97+
if (subscribers.values.none { it.isDataCollectionEnabled }) {
98+
Log.d(TAG, "Data Collection is disabled for all subscribers. Skipping this Session Event")
99+
return@launch
100+
}
101+
102+
Log.d(TAG, "Data Collection is enabled for at least one Subscriber")
103+
104+
subscribers.values.forEach { subscriber ->
105+
if (subscriber.isDataCollectionEnabled) {
106+
subscriber.onSessionChanged(SessionSubscriber.SessionDetails(sessionDetails.sessionId))
107+
}
108+
}
109+
110+
if (!sessionGenerator.collectEvents) {
111+
Log.d(TAG, "Sessions SDK has sampled this session")
112+
return@launch
113+
}
114+
115+
sessionCoordinator.attemptLoggingSessionEvent(
116+
SessionEvents.startSession(firebaseApp, sessionDetails, sessionSettings, timeProvider)
117+
)
118+
}
83119
}
84120

85121
/** Calculate whether we should sample events using [sessionSettings] data. */

firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessionsEarly.kt

Lines changed: 0 additions & 26 deletions
This file was deleted.

firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessionsRegistrar.kt

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ import com.google.android.datatransport.TransportFactory
1919
import com.google.firebase.FirebaseApp
2020
import com.google.firebase.annotations.concurrent.Background
2121
import com.google.firebase.annotations.concurrent.Blocking
22-
import com.google.firebase.components.*
22+
import com.google.firebase.components.Component
23+
import com.google.firebase.components.ComponentRegistrar
24+
import com.google.firebase.components.Dependency
2325
import com.google.firebase.components.Qualified.qualified
2426
import com.google.firebase.components.Qualified.unqualified
2527
import com.google.firebase.installations.FirebaseInstallationsApi
@@ -35,22 +37,14 @@ import kotlinx.coroutines.CoroutineDispatcher
3537
internal class FirebaseSessionsRegistrar : ComponentRegistrar {
3638
override fun getComponents() =
3739
listOf(
38-
Component.builder(firebaseSessionsEarly)
39-
.name(EARLY_LIBRARY_NAME)
40-
.factory { _ -> FirebaseSessionsEarly() }
41-
.eagerInDefaultApp()
42-
.build(),
4340
Component.builder(FirebaseSessions::class.java)
4441
.name(LIBRARY_NAME)
45-
.add(Dependency.required(firebaseSessionsEarly))
4642
.add(Dependency.required(firebaseApp))
4743
.add(Dependency.required(firebaseInstallationsApi))
4844
.add(Dependency.required(backgroundDispatcher))
4945
.add(Dependency.required(blockingDispatcher))
5046
.add(Dependency.requiredProvider(transportFactory))
5147
.factory { container ->
52-
// Make sure FirebaseSessionsEarly has started up
53-
container.get(firebaseSessionsEarly)
5448
FirebaseSessions(
5549
container.get(firebaseApp),
5650
container.get(firebaseInstallationsApi),
@@ -65,9 +59,7 @@ internal class FirebaseSessionsRegistrar : ComponentRegistrar {
6559

6660
companion object {
6761
private const val LIBRARY_NAME = "fire-sessions"
68-
private const val EARLY_LIBRARY_NAME = "fire-sessions-early"
6962

70-
private val firebaseSessionsEarly = unqualified(FirebaseSessionsEarly::class.java)
7163
private val firebaseApp = unqualified(FirebaseApp::class.java)
7264
private val firebaseInstallationsApi = unqualified(FirebaseInstallationsApi::class.java)
7365
private val backgroundDispatcher =

firebase-sessions/src/main/kotlin/com/google/firebase/sessions/SessionCoordinator.kt

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ package com.google.firebase.sessions
1818

1919
import android.util.Log
2020
import com.google.firebase.installations.FirebaseInstallationsApi
21-
import kotlin.coroutines.CoroutineContext
22-
import kotlinx.coroutines.CoroutineScope
23-
import kotlinx.coroutines.launch
2421
import kotlinx.coroutines.tasks.await
2522

2623
/**
@@ -31,30 +28,26 @@ import kotlinx.coroutines.tasks.await
3128
*/
3229
internal class SessionCoordinator(
3330
private val firebaseInstallations: FirebaseInstallationsApi,
34-
context: CoroutineContext,
3531
private val eventGDTLogger: EventGDTLoggerInterface,
3632
) {
37-
private val scope = CoroutineScope(context)
38-
39-
fun attemptLoggingSessionEvent(sessionEvent: SessionEvent) =
40-
scope.launch {
41-
sessionEvent.sessionData.firebaseInstallationId =
42-
try {
43-
firebaseInstallations.id.await()
44-
} catch (ex: Exception) {
45-
Log.e(TAG, "Error getting Firebase Installation ID: ${ex}. Using an empty ID")
46-
// Use an empty fid if there is any failure.
47-
""
48-
}
49-
33+
suspend fun attemptLoggingSessionEvent(sessionEvent: SessionEvent) {
34+
sessionEvent.sessionData.firebaseInstallationId =
5035
try {
51-
eventGDTLogger.log(sessionEvent)
52-
53-
Log.i(TAG, "Successfully logged Session Start event: ${sessionEvent.sessionData.sessionId}")
54-
} catch (e: RuntimeException) {
55-
Log.e(TAG, "Error logging Session Start event to DataTransport: ", e)
36+
firebaseInstallations.id.await()
37+
} catch (ex: Exception) {
38+
Log.e(TAG, "Error getting Firebase Installation ID: ${ex}. Using an empty ID")
39+
// Use an empty fid if there is any failure.
40+
""
5641
}
42+
43+
try {
44+
eventGDTLogger.log(sessionEvent)
45+
46+
Log.i(TAG, "Successfully logged Session Start event: ${sessionEvent.sessionData.sessionId}")
47+
} catch (ex: RuntimeException) {
48+
Log.e(TAG, "Error logging Session Start event to DataTransport: ", ex)
5749
}
50+
}
5851

5952
companion object {
6053
private const val TAG = "SessionCoordinator"

firebase-sessions/src/main/kotlin/com/google/firebase/sessions/api/SessionSubscriber.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@
1616

1717
package com.google.firebase.sessions.api
1818

19+
import androidx.annotation.Discouraged
20+
1921
/** [SessionSubscriber] is an interface that dependent SDKs must implement. */
2022
interface SessionSubscriber {
2123
/** [SessionSubscriber.Name]s are used for identifying subscribers. */
2224
enum class Name {
2325
CRASHLYTICS,
2426
PERFORMANCE,
27+
@Discouraged(message = "This is for testing purposes only.") MATT_SAYS_HI,
2528
}
2629

2730
/** [SessionDetails] contains session data passed to subscribers whenever the session changes */

firebase-sessions/src/test/kotlin/com/google/firebase/sessions/SessionCoordinatorTest.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ class SessionCoordinatorTest {
4444
val sessionCoordinator =
4545
SessionCoordinator(
4646
firebaseInstallations,
47-
context = TestOnlyExecutors.background().asCoroutineDispatcher() + coroutineContext,
4847
eventGDTLogger = fakeEventGDTLogger,
4948
)
5049

firebase-sessions/test-app/src/androidTest/kotlin/com/google/firebase/testing/sessions/FirebaseSessionsTest.kt

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import com.google.firebase.FirebaseApp
2323
import com.google.firebase.ktx.Firebase
2424
import com.google.firebase.ktx.initialize
2525
import com.google.firebase.sessions.FirebaseSessions
26+
import com.google.firebase.sessions.api.FirebaseSessionsDependencies
27+
import com.google.firebase.sessions.api.SessionSubscriber
2628
import org.junit.After
2729
import org.junit.Before
2830
import org.junit.Test
@@ -41,16 +43,38 @@ class FirebaseSessionsTest {
4143
}
4244

4345
@Test
44-
fun initializeSession() {
46+
fun initializeSessions_generatesSessionEvent() {
4547
// Force the Firebase Sessions SDK to initialize.
46-
assertThat(FirebaseSessions.instance.greeting()).isEqualTo("Matt says hi!")
48+
assertThat(FirebaseSessions.instance).isNotNull()
49+
50+
// Add a fake dependency and register it, otherwise sessions will never send.
51+
val fakeSessionSubscriber = FakeSessionSubscriber()
52+
FirebaseSessions.instance.register(fakeSessionSubscriber)
4753

4854
// Wait for the session start event to send.
49-
// TODO(mrober): Setup logger we can access from tests.
5055
Thread.sleep(TIME_TO_LOG_SESSION)
56+
57+
// Assert that some session was generated and sent to the subscriber.
58+
assertThat(fakeSessionSubscriber.sessionDetails).isNotNull()
5159
}
5260

5361
companion object {
5462
private const val TIME_TO_LOG_SESSION = 60_000L
63+
64+
init {
65+
FirebaseSessionsDependencies.addDependency(SessionSubscriber.Name.MATT_SAYS_HI)
66+
}
67+
}
68+
69+
private class FakeSessionSubscriber(
70+
override val isDataCollectionEnabled: Boolean = true,
71+
override val sessionSubscriberName: SessionSubscriber.Name = SessionSubscriber.Name.MATT_SAYS_HI
72+
) : SessionSubscriber {
73+
var sessionDetails: SessionSubscriber.SessionDetails? = null
74+
private set
75+
76+
override fun onSessionChanged(sessionDetails: SessionSubscriber.SessionDetails) {
77+
this.sessionDetails = sessionDetails
78+
}
5579
}
5680
}

firebase-sessions/test-app/src/main/kotlin/com/google/firebase/testing/sessions/MainActivity.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@ package com.google.firebase.testing.sessions
1919
import android.os.Bundle
2020
import android.widget.TextView
2121
import androidx.appcompat.app.AppCompatActivity
22-
import com.google.firebase.sessions.FirebaseSessions
2322

2423
class MainActivity : AppCompatActivity() {
2524
override fun onCreate(savedInstanceState: Bundle?) {
2625
super.onCreate(savedInstanceState)
2726
setContentView(R.layout.activity_main)
2827

29-
findViewById<TextView>(R.id.greeting_text).text = FirebaseSessions.instance.greeting()
28+
findViewById<TextView>(R.id.greeting_text).text = getText(R.string.firebase_greetings)
3029
}
3130
}

0 commit comments

Comments
 (0)