Skip to content

Commit 8042b4b

Browse files
Merge pull request #705 from snowplow/release/6.2.0
Release 6.2.0
2 parents 5cf2974 + 70ac3c5 commit 8042b4b

File tree

17 files changed

+278
-108
lines changed

17 files changed

+278
-108
lines changed

CHANGELOG

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
Version 6.2.0 (2025-02-10)
2+
--------------------------
3+
Add an option to continue previously persisted session when the app restarts rather than starting a new one (#340)
4+
15
Version 6.1.1 (2025-01-22)
26
--------------------------
37
Do not autotrack screen view events when app comes to foreground (#701)

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6.1.1
1+
6.2.0

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ plugins {
2222

2323
subprojects {
2424
group = 'com.snowplowanalytics'
25-
version = '6.1.1'
25+
version = '6.2.0'
2626
repositories {
2727
google()
2828
maven {

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ systemProp.org.gradle.internal.http.socketTimeout=120000
3131
SONATYPE_STAGING_PROFILE=comsnowplowanalytics
3232
GROUP=com.snowplowanalytics
3333
POM_ARTIFACT_ID=snowplow-android-tracker
34-
VERSION_NAME=6.1.1
34+
VERSION_NAME=6.2.0
3535

3636
POM_NAME=snowplow-android-tracker
3737
POM_PACKAGING=aar

snowplow-demo-kotlin/src/main/java/com/snowplowanalytics/snowplowdemokotlin/Demo.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,10 @@ class Demo : Activity(), LoggerDelegate {
279279
.installAutotracking(true)
280280
.diagnosticAutotracking(true)
281281
val sessionConfiguration = SessionConfiguration(
282-
TimeMeasure(6, TimeUnit.SECONDS),
283-
TimeMeasure(30, TimeUnit.SECONDS)
282+
TimeMeasure(30, TimeUnit.MINUTES),
283+
TimeMeasure(30, TimeUnit.MINUTES)
284284
)
285+
.continueSessionOnRestart(true)
285286
.onSessionUpdate { state: SessionState ->
286287
updateLogger(
287288
"""

snowplow-tracker/src/androidTest/java/com/snowplowanalytics/snowplow/internal/tracker/ConfigurationTest.kt

+3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class ConfigurationTest {
7373
Assert.assertEquals(protocol, scheme)
7474
Assert.assertEquals(trackerConfiguration.appId, tracker.appId)
7575
Assert.assertEquals("namespace", tracker.namespace)
76+
Assert.assertEquals(tracker.session!!.continueSessionOnRestart, false)
7677
}
7778

7879
@Test
@@ -83,12 +84,14 @@ class ConfigurationTest {
8384
val networkConfig = NetworkConfiguration("fake-url", HttpMethod.POST)
8485
val trackerConfig = TrackerConfiguration("appId")
8586
val sessionConfig = SessionConfiguration(expectedForeground, expectedBackground)
87+
sessionConfig.continueSessionOnRestart = true
8688
val tracker =
8789
createTracker(context, "namespace", networkConfig, trackerConfig, sessionConfig)
8890
val foreground = tracker.session!!.foregroundTimeout
8991
val background = tracker.session!!.backgroundTimeout
9092
Assert.assertEquals(expectedForeground, foreground)
9193
Assert.assertEquals(expectedBackground, background)
94+
Assert.assertEquals(tracker.session!!.continueSessionOnRestart, true)
9295
}
9396

9497
@Test

snowplow-tracker/src/androidTest/java/com/snowplowanalytics/snowplow/tracker/SessionTest.kt

+49-8
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,14 @@ class SessionTest {
5252
Assert.assertEquals(300000, session.backgroundTimeout)
5353
Assert.assertNull(sessionState)
5454
Assert.assertNotNull(session.userId)
55-
val sdj = session.getSessionContext("first-id-1", timestamp, false)
55+
val sdj = session.getAndUpdateSessionForEvent("first-id-1", timestamp, false)
5656
sessionState = session.state
5757

5858
Assert.assertNotNull(sdj)
5959
Assert.assertNotNull(sessionState)
6060
Assert.assertEquals("first-id-1", sessionState!!.firstEventId)
6161
Assert.assertEquals(timestampDateTime, sessionState.firstEventTimestamp)
62-
session.getSessionContext("second-id-2", timestamp + 10000, false)
62+
session.getAndUpdateSessionForEvent("second-id-2", timestamp + 10000, false)
6363
Assert.assertEquals("first-id-1", sessionState.firstEventId)
6464
Assert.assertEquals(timestampDateTime, sessionState.firstEventTimestamp)
6565
Assert.assertEquals(TrackerConstants.SESSION_SCHEMA, sdj!!.map["schema"])
@@ -342,21 +342,21 @@ class SessionTest {
342342
val tracker2 = Tracker(emitter, "tracker2", "app", context = context, builder = trackerBuilder)
343343
val session1 = tracker1.session
344344
val session2 = tracker2.session
345-
session1!!.getSessionContext("session1-fake-id1", timestamp, false)
346-
session2!!.getSessionContext("session2-fake-id1", timestamp, false)
345+
session1!!.getAndUpdateSessionForEvent("session1-fake-id1", timestamp, false)
346+
session2!!.getAndUpdateSessionForEvent("session2-fake-id1", timestamp, false)
347347
val initialValue1 = session1.sessionIndex?.toLong()
348348
val id1 = session1.state!!.sessionId
349349
val initialValue2 = session2.sessionIndex?.toLong()
350350

351351
// Retrigger session in tracker1
352352
// The timeout is 20s, this sleep is only 2s - it's still the same session
353353
Thread.sleep(2000)
354-
session1.getSessionContext("session1-fake-id2", timestamp, false)
354+
session1.getAndUpdateSessionForEvent("session1-fake-id2", timestamp, false)
355355

356356
// Retrigger timedout session in tracker2
357357
// 20s has then passed. Session must be updated, increasing the sessionIndex by 1
358358
Thread.sleep(18000)
359-
session2.getSessionContext("session2-fake-id2", timestamp, false)
359+
session2.getAndUpdateSessionForEvent("session2-fake-id2", timestamp, false)
360360

361361
// Check sessions have the correct state
362362
Assert.assertEquals(0, session1.sessionIndex!! - initialValue1!!)
@@ -365,7 +365,7 @@ class SessionTest {
365365

366366
// Recreate tracker2
367367
val tracker2b = Tracker(emitter, "tracker2", "app", context = context, builder = trackerBuilder)
368-
tracker2b.session!!.getSessionContext("session2b-fake-id3", timestamp, false)
368+
tracker2b.session!!.getAndUpdateSessionForEvent("session2b-fake-id3", timestamp, false)
369369
val initialValue2b = tracker2b.session!!.sessionIndex?.toLong()
370370
val previousId2b = tracker2b.session!!.state!!.previousSessionId
371371

@@ -388,6 +388,47 @@ class SessionTest {
388388
Assert.assertNull(context[Parameters.SESSION_PREVIOUS_ID])
389389
}
390390

391+
@Test
392+
fun testStartsNewSessionOnRestartByDefault() {
393+
val session1 = Session(foregroundTimeout = 3, backgroundTimeout = 3, namespace = "t1", timeUnit = TimeUnit.SECONDS, context = context)
394+
val firstSession = session1.getAndUpdateSessionForEvent("event_1", eventTimestamp = 1654496481345, userAnonymisation = false)
395+
396+
val session2 = Session(foregroundTimeout = 3, backgroundTimeout = 3, namespace = "t1", timeUnit = TimeUnit.SECONDS, context = context)
397+
val secondSession = session2.getAndUpdateSessionForEvent("event_2", eventTimestamp = 1654496481345, userAnonymisation = false)
398+
399+
Assert.assertNotNull(firstSession?.sessionId)
400+
Assert.assertNotEquals(firstSession?.sessionId, secondSession?.sessionId)
401+
Assert.assertEquals(firstSession?.sessionId, secondSession?.previousSessionId)
402+
}
403+
404+
@Test
405+
fun testResumesPreviouslyPersistedSessionIfEnabled() {
406+
val session1 = Session(foregroundTimeout = 3, backgroundTimeout = 3, namespace = "t1", continueSessionOnRestart = true, timeUnit = TimeUnit.SECONDS, context = context)
407+
session1.getAndUpdateSessionForEvent("event_1", eventTimestamp = 1654496481345, userAnonymisation = false)
408+
val firstSession = session1.getAndUpdateSessionForEvent("event_2", eventTimestamp = 1654496481346, userAnonymisation = false)
409+
410+
val session2 = Session(foregroundTimeout = 3, backgroundTimeout = 3, namespace = "t1", continueSessionOnRestart = true, timeUnit = TimeUnit.SECONDS, context = context)
411+
val secondSession = session2.getAndUpdateSessionForEvent("event_3", eventTimestamp = 1654496481347, userAnonymisation = false)
412+
413+
Assert.assertNotNull(firstSession?.sessionId)
414+
Assert.assertEquals(firstSession?.sessionId, secondSession?.sessionId)
415+
Assert.assertEquals(secondSession?.eventIndex, 3)
416+
}
417+
418+
@Test
419+
fun testStartsNewSessionOnRestartOnTimeout() {
420+
val session1 = Session(foregroundTimeout = 100, backgroundTimeout = 100, namespace = "t1", continueSessionOnRestart = true, timeUnit = TimeUnit.MILLISECONDS, context = context)
421+
val firstSession = session1.getAndUpdateSessionForEvent("event_1", eventTimestamp = 1654496481345, userAnonymisation = false)
422+
423+
Thread.sleep(500)
424+
425+
val session2 = Session(foregroundTimeout = 100, backgroundTimeout = 100, namespace = "t1", continueSessionOnRestart = true, timeUnit = TimeUnit.MILLISECONDS, context = context)
426+
val secondSession = session2.getAndUpdateSessionForEvent("event_2", eventTimestamp = 1654496481345, userAnonymisation = false)
427+
428+
Assert.assertNotEquals(firstSession?.sessionId, secondSession?.sessionId)
429+
Assert.assertEquals(firstSession?.sessionId, secondSession?.previousSessionId)
430+
}
431+
391432
// Private methods
392433
private fun getSession(foregroundTimeout: Long, backgroundTimeout: Long): Session {
393434
context.getSharedPreferences(TrackerConstants.SNOWPLOW_SESSION_VARS, Context.MODE_PRIVATE)
@@ -403,7 +444,7 @@ class SessionTest {
403444
eventTimestamp: Long,
404445
userAnonymisation: Boolean
405446
): Map<String, Any>? {
406-
return session!!.getSessionContext(
447+
return session!!.getAndUpdateSessionForEvent(
407448
eventId,
408449
eventTimestamp,
409450
userAnonymisation

snowplow-tracker/src/main/java/com/snowplowanalytics/core/constants/Parameters.kt

+1
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ object Parameters {
227227
const val SESSION_STORAGE = "storageMechanism"
228228
const val SESSION_FIRST_ID = "firstEventId"
229229
const val SESSION_FIRST_TIMESTAMP = "firstEventTimestamp"
230+
const val SESSION_LAST_UPDATE = "lastUpdate"
230231

231232
// Screen Context
232233
const val SCREEN_NAME = "name"

0 commit comments

Comments
 (0)