Skip to content

Commit 5473f98

Browse files
authored
Merge b3fe273 into 47dcc85
2 parents 47dcc85 + b3fe273 commit 5473f98

File tree

5 files changed

+155
-43
lines changed

5 files changed

+155
-43
lines changed

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import com.google.firebase.ktx.Firebase
2424
import com.google.firebase.ktx.app
2525

2626
class FirebaseSessions internal constructor(firebaseApp: FirebaseApp) {
27-
2827
private val sessionGenerator = SessionGenerator(collectEvents = true)
2928

3029
init {
@@ -41,10 +40,10 @@ class FirebaseSessions internal constructor(firebaseApp: FirebaseApp) {
4140
fun greeting(): String = "Matt says hi!"
4241

4342
private fun initiateSessionStart() {
44-
// TODO(mrober): Generate a session
45-
Log.i(TAG, "Initiate session start")
43+
val sessionState = sessionGenerator.generateNewSession()
44+
val sessionEvent = SessionEvent.sessionStart(sessionState)
4645

47-
sessionGenerator.generateNewSession()
46+
Log.i(TAG, "Initiate session start: $sessionEvent")
4847
}
4948

5049
companion object {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.sessions
18+
19+
/**
20+
* Contains the relevant information around a Firebase Session Event.
21+
*
22+
* See go/app-quality-unified-session-definition for more details. Keep in sync with
23+
* https://github.com/firebase/firebase-ios-sdk/blob/master/FirebaseSessions/ProtoSupport/Protos/sessions.proto
24+
*/
25+
// TODO(mrober): Add and populate all fields from sessions.proto
26+
internal data class SessionEvent(
27+
/** The type of event being reported. */
28+
val eventType: EventType,
29+
30+
/** Information about the session triggering the event. */
31+
val sessionData: SessionInfo,
32+
) {
33+
companion object {
34+
fun sessionStart(sessionDetails: SessionDetails) =
35+
SessionEvent(
36+
eventType = EventType.SESSION_START,
37+
sessionData =
38+
SessionInfo(
39+
sessionDetails.sessionId,
40+
sessionDetails.firstSessionId,
41+
sessionDetails.sessionIndex,
42+
),
43+
)
44+
}
45+
}
46+
47+
/** Enum denoting all possible session event types. */
48+
internal enum class EventType(val number: Int) {
49+
EVENT_TYPE_UNKNOWN(0),
50+
51+
/** This event type is fired as soon as a new session begins. */
52+
SESSION_START(1),
53+
}
54+
55+
/** Contains session-specific information relating to the event being uploaded. */
56+
internal data class SessionInfo(
57+
/** A globally unique identifier for the session. */
58+
val sessionId: String,
59+
60+
/**
61+
* Will point to the first Session for the run of the app.
62+
*
63+
* For the first session, this will be the same as session_id.
64+
*/
65+
val firstSessionId: String,
66+
67+
/** What order this Session came in this run of the app. For the first Session this will be 0. */
68+
val sessionIndex: Int,
69+
)

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

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ package com.google.firebase.sessions
1919
import java.util.UUID
2020

2121
/**
22-
* [SessionInfo] is a data class responsible for storing information about the current Session.
22+
* [SessionDetails] is a data class responsible for storing information about the current Session.
2323
*
2424
* @hide
2525
*/
26-
internal data class SessionInfo(
26+
internal data class SessionDetails(
2727
val sessionId: String,
2828
val firstSessionId: String,
2929
val collectEvents: Boolean,
@@ -32,43 +32,39 @@ internal data class SessionInfo(
3232

3333
/**
3434
* The [SessionGenerator] is responsible for generating the Session ID, and keeping the
35-
* [SessionInfo] up to date with the latest values.
35+
* [SessionDetails] up to date with the latest values.
3636
*
3737
* @hide
3838
*/
39-
internal class SessionGenerator(collectEvents: Boolean) {
39+
internal class SessionGenerator(private var collectEvents: Boolean) {
4040
private var firstSessionId = ""
4141
private var sessionIndex: Int = -1
42-
private var collectEvents = collectEvents
4342

44-
private var thisSession: SessionInfo =
45-
SessionInfo(
43+
private var thisSession: SessionDetails =
44+
SessionDetails(
4645
sessionId = "",
4746
firstSessionId = "",
48-
collectEvents = collectEvents,
49-
sessionIndex = sessionIndex
47+
collectEvents,
48+
sessionIndex,
5049
)
5150

5251
// Generates a new Session ID. If there was already a generated Session ID
5352
// from the last session during the app's lifecycle, it will also set the last Session ID
54-
fun generateNewSession() {
53+
fun generateNewSession(): SessionDetails {
5554
val newSessionId = UUID.randomUUID().toString().replace("-", "").lowercase()
5655

5756
// If firstSessionId is set, use it. Otherwise set it to the
5857
// first generated Session ID
59-
firstSessionId = if (firstSessionId.isEmpty()) newSessionId else firstSessionId
58+
firstSessionId = firstSessionId.ifEmpty { newSessionId }
6059

6160
sessionIndex += 1
6261

6362
thisSession =
64-
SessionInfo(
65-
sessionId = newSessionId,
66-
firstSessionId = firstSessionId,
67-
collectEvents = collectEvents,
68-
sessionIndex = sessionIndex
69-
)
63+
SessionDetails(sessionId = newSessionId, firstSessionId, collectEvents, sessionIndex)
64+
65+
return thisSession
7066
}
7167

72-
val currentSession: SessionInfo
68+
val currentSession: SessionDetails
7369
get() = thisSession
7470
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.sessions
18+
19+
import com.google.common.truth.Truth.assertThat
20+
import org.junit.Test
21+
22+
class SessionEventTest {
23+
@Test
24+
fun sessionStart_populatesSessionDetailsCorrectly() {
25+
val sessionDetails =
26+
SessionDetails(
27+
sessionId = "a1b2c3",
28+
firstSessionId = "a1a1a1",
29+
collectEvents = true,
30+
sessionIndex = 3,
31+
)
32+
33+
val sessionEvent = SessionEvent.sessionStart(sessionDetails)
34+
35+
assertThat(sessionEvent)
36+
.isEqualTo(
37+
SessionEvent(
38+
eventType = EventType.SESSION_START,
39+
sessionData =
40+
SessionInfo(
41+
sessionId = "a1b2c3",
42+
firstSessionId = "a1a1a1",
43+
sessionIndex = 3,
44+
)
45+
)
46+
)
47+
}
48+
}

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

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import com.google.common.truth.Truth.assertThat
2020
import org.junit.Test
2121

2222
class SessionGeneratorTest {
23-
fun isValidSessionId(sessionId: String): Boolean {
23+
private fun isValidSessionId(sessionId: String): Boolean {
2424
if (sessionId.length != 32) {
2525
return false
2626
}
@@ -42,21 +42,21 @@ class SessionGeneratorTest {
4242

4343
assertThat(sessionGenerator.currentSession.sessionId).isEqualTo("")
4444
assertThat(sessionGenerator.currentSession.firstSessionId).isEqualTo("")
45-
assertThat(sessionGenerator.currentSession.collectEvents).isEqualTo(false)
45+
assertThat(sessionGenerator.currentSession.collectEvents).isFalse()
4646
assertThat(sessionGenerator.currentSession.sessionIndex).isEqualTo(-1)
4747
}
4848

4949
@Test
50-
fun generateNewSessionID_generatesValidSessionInfo() {
50+
fun generateNewSessionID_generatesValidSessionDetails() {
5151
val sessionGenerator = SessionGenerator(collectEvents = true)
5252

5353
sessionGenerator.generateNewSession()
5454

55-
assertThat(isValidSessionId(sessionGenerator.currentSession.sessionId)).isEqualTo(true)
56-
assertThat(isValidSessionId(sessionGenerator.currentSession.firstSessionId)).isEqualTo(true)
55+
assertThat(isValidSessionId(sessionGenerator.currentSession.sessionId)).isTrue()
56+
assertThat(isValidSessionId(sessionGenerator.currentSession.firstSessionId)).isTrue()
5757
assertThat(sessionGenerator.currentSession.firstSessionId)
5858
.isEqualTo(sessionGenerator.currentSession.sessionId)
59-
assertThat(sessionGenerator.currentSession.collectEvents).isEqualTo(true)
59+
assertThat(sessionGenerator.currentSession.collectEvents).isTrue()
6060
assertThat(sessionGenerator.currentSession.sessionIndex).isEqualTo(0)
6161
}
6262

@@ -68,32 +68,32 @@ class SessionGeneratorTest {
6868

6969
sessionGenerator.generateNewSession()
7070

71-
val firstSessionInfo = sessionGenerator.currentSession
71+
val firstSessionDetails = sessionGenerator.currentSession
7272

73-
assertThat(isValidSessionId(firstSessionInfo.sessionId)).isEqualTo(true)
74-
assertThat(isValidSessionId(firstSessionInfo.firstSessionId)).isEqualTo(true)
75-
assertThat(firstSessionInfo.firstSessionId).isEqualTo(firstSessionInfo.sessionId)
76-
assertThat(firstSessionInfo.sessionIndex).isEqualTo(0)
73+
assertThat(isValidSessionId(firstSessionDetails.sessionId)).isTrue()
74+
assertThat(isValidSessionId(firstSessionDetails.firstSessionId)).isTrue()
75+
assertThat(firstSessionDetails.firstSessionId).isEqualTo(firstSessionDetails.sessionId)
76+
assertThat(firstSessionDetails.sessionIndex).isEqualTo(0)
7777

7878
sessionGenerator.generateNewSession()
79-
val secondSessionInfo = sessionGenerator.currentSession
79+
val secondSessionDetails = sessionGenerator.currentSession
8080

81-
assertThat(isValidSessionId(secondSessionInfo.sessionId)).isEqualTo(true)
82-
assertThat(isValidSessionId(secondSessionInfo.firstSessionId)).isEqualTo(true)
81+
assertThat(isValidSessionId(secondSessionDetails.sessionId)).isTrue()
82+
assertThat(isValidSessionId(secondSessionDetails.firstSessionId)).isTrue()
8383
// Ensure the new firstSessionId is equal to the first Session ID from earlier
84-
assertThat(secondSessionInfo.firstSessionId).isEqualTo(firstSessionInfo.sessionId)
84+
assertThat(secondSessionDetails.firstSessionId).isEqualTo(firstSessionDetails.sessionId)
8585
// Session Index should increase
86-
assertThat(secondSessionInfo.sessionIndex).isEqualTo(1)
86+
assertThat(secondSessionDetails.sessionIndex).isEqualTo(1)
8787

8888
// Do a third round just in case
8989
sessionGenerator.generateNewSession()
90-
val thirdSessionInfo = sessionGenerator.currentSession
90+
val thirdSessionDetails = sessionGenerator.currentSession
9191

92-
assertThat(isValidSessionId(thirdSessionInfo.sessionId)).isEqualTo(true)
93-
assertThat(isValidSessionId(thirdSessionInfo.firstSessionId)).isEqualTo(true)
92+
assertThat(isValidSessionId(thirdSessionDetails.sessionId)).isTrue()
93+
assertThat(isValidSessionId(thirdSessionDetails.firstSessionId)).isTrue()
9494
// Ensure the new firstSessionId is equal to the first Session ID from earlier
95-
assertThat(thirdSessionInfo.firstSessionId).isEqualTo(firstSessionInfo.sessionId)
95+
assertThat(thirdSessionDetails.firstSessionId).isEqualTo(firstSessionDetails.sessionId)
9696
// Session Index should increase
97-
assertThat(thirdSessionInfo.sessionIndex).isEqualTo(2)
97+
assertThat(thirdSessionDetails.sessionIndex).isEqualTo(2)
9898
}
9999
}

0 commit comments

Comments
 (0)