Skip to content

Commit c9a4a3d

Browse files
mroberthemiswang
andauthored
Merged sessions-sharedrepo into main (#7039)
Merged `sessions-sharedrepo` into `main` This merge brings in the new sessions shared repo implementation, which facilitates the Perf+AQS integration. This also includes improvements that will benefit Crashlytics e.g. providing sessions for early crashes All individual commits on the `sessions-sharedrepo` branch were reviewed and approved in their respective pull requests --------- Co-authored-by: themiswang <[email protected]>
1 parent c09e9cc commit c9a4a3d

File tree

76 files changed

+2506
-2652
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+2506
-2652
lines changed

firebase-sessions/CHANGELOG.md

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,20 @@
11
# Unreleased
22
* [changed] Added internal api for Crashlytics to notify Sessions of crash events
3+
* [changed] Use multi-process DataStore instead of Preferences DataStore
4+
* [changed] Update the heuristic to detect cold app starts
35

46
# 2.1.1
57
* [unchanged] Updated to keep SDK versions aligned.
68

7-
8-
## Kotlin
9-
The Kotlin extensions library transitively includes the updated
10-
`firebase-sessions` library. The Kotlin extensions library has no additional
11-
updates.
12-
139
# 2.1.0
1410
* [changed] Add warning for known issue b/328687152
1511
* [changed] Use Dagger for dependency injection
1612
* [changed] Updated datastore dependency to v1.1.3 to
1713
fix [CVE-2024-7254](https://github.com/advisories/GHSA-735f-pc8j-v9w8).
1814

19-
20-
## Kotlin
21-
The Kotlin extensions library transitively includes the updated
22-
`firebase-sessions` library. The Kotlin extensions library has no additional
23-
updates.
24-
2515
# 2.0.9
2616
* [fixed] Make AQS resilient to background init in multi-process apps.
2717

28-
29-
## Kotlin
30-
The Kotlin extensions library transitively includes the updated
31-
`firebase-sessions` library. The Kotlin extensions library has no additional
32-
updates.
33-
3418
# 2.0.7
3519
* [fixed] Removed extraneous logs that risk leaking internal identifiers.
3620

firebase-sessions/benchmark/src/main/kotlin/com/google/firebase/benchmark/sessions/StartupBenchmark.kt

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import androidx.benchmark.macro.StartupMode
2020
import androidx.benchmark.macro.StartupTimingMetric
2121
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
2222
import androidx.test.ext.junit.runners.AndroidJUnit4
23+
import androidx.test.platform.app.InstrumentationRegistry
24+
import java.io.FileInputStream
2325
import org.junit.Rule
2426
import org.junit.Test
2527
import org.junit.runner.RunWith
@@ -31,12 +33,43 @@ class StartupBenchmark {
3133
@Test
3234
fun startup() =
3335
benchmarkRule.measureRepeated(
34-
packageName = "com.google.firebase.testing.sessions",
36+
packageName = PACKAGE_NAME,
3537
metrics = listOf(StartupTimingMetric()),
3638
iterations = 5,
3739
startupMode = StartupMode.COLD,
3840
) {
3941
pressHome()
4042
startActivityAndWait()
4143
}
44+
45+
@Test
46+
fun startup_clearAppData() =
47+
benchmarkRule.measureRepeated(
48+
packageName = PACKAGE_NAME,
49+
metrics = listOf(StartupTimingMetric()),
50+
iterations = 5,
51+
startupMode = StartupMode.COLD,
52+
setupBlock = { clearAppData(packageName) },
53+
) {
54+
pressHome()
55+
startActivityAndWait()
56+
}
57+
58+
private fun clearAppData(packageName: String) {
59+
val fileDescriptor =
60+
InstrumentationRegistry.getInstrumentation()
61+
.uiAutomation
62+
.executeShellCommand("pm clear $packageName")
63+
val fileInputStream = FileInputStream(fileDescriptor.fileDescriptor)
64+
// Read the output to ensure the app data was cleared successfully
65+
val result = fileInputStream.bufferedReader().use { it.readText().trim() }
66+
fileDescriptor.close()
67+
if (result != "Success") {
68+
throw IllegalStateException("Unable to clear app data for $packageName - $result")
69+
}
70+
}
71+
72+
private companion object {
73+
const val PACKAGE_NAME = "com.google.firebase.testing.sessions"
74+
}
4275
}

firebase-sessions/firebase-sessions.gradle.kts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,19 @@ plugins {
2121
id("firebase-vendor")
2222
id("kotlin-android")
2323
id("kotlin-kapt")
24+
id("kotlinx-serialization")
2425
}
2526

2627
firebaseLibrary {
2728
libraryGroup = "crashlytics"
2829

2930
testLab.enabled = true
3031
publishJavadoc = false
31-
releaseNotes { enabled.set(false) }
32+
33+
releaseNotes {
34+
enabled = false
35+
hasKTX = false
36+
}
3237
}
3338

3439
android {
@@ -76,7 +81,8 @@ dependencies {
7681
implementation("com.google.android.datatransport:transport-api:3.2.0")
7782
implementation(libs.javax.inject)
7883
implementation(libs.androidx.annotation)
79-
implementation(libs.androidx.datastore.preferences)
84+
implementation(libs.androidx.datastore)
85+
implementation(libs.kotlinx.serialization.json)
8086

8187
vendor(libs.dagger.dagger) { exclude(group = "javax.inject", module = "javax.inject") }
8288

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

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@ import androidx.test.core.app.ApplicationProvider
2020
import androidx.test.ext.junit.runners.AndroidJUnit4
2121
import com.google.common.truth.Truth.assertThat
2222
import com.google.firebase.Firebase
23-
import com.google.firebase.FirebaseApp
2423
import com.google.firebase.FirebaseOptions
2524
import com.google.firebase.initialize
2625
import com.google.firebase.sessions.settings.SessionsSettings
27-
import org.junit.After
28-
import org.junit.Before
26+
import org.junit.BeforeClass
2927
import org.junit.Test
3028
import org.junit.runner.RunWith
3129

@@ -36,23 +34,6 @@ import org.junit.runner.RunWith
3634
*/
3735
@RunWith(AndroidJUnit4::class)
3836
class FirebaseSessionsTests {
39-
@Before
40-
fun setUp() {
41-
Firebase.initialize(
42-
ApplicationProvider.getApplicationContext(),
43-
FirebaseOptions.Builder()
44-
.setApplicationId(APP_ID)
45-
.setApiKey(API_KEY)
46-
.setProjectId(PROJECT_ID)
47-
.build()
48-
)
49-
}
50-
51-
@After
52-
fun cleanUp() {
53-
FirebaseApp.clearInstancesForTest()
54-
}
55-
5637
@Test
5738
fun firebaseSessionsDoesInitialize() {
5839
assertThat(FirebaseSessions.instance).isNotNull()
@@ -61,13 +42,25 @@ class FirebaseSessionsTests {
6142
@Test
6243
fun firebaseSessionsDependenciesDoInitialize() {
6344
assertThat(SessionFirelogPublisher.instance).isNotNull()
64-
assertThat(SessionGenerator.instance).isNotNull()
6545
assertThat(SessionsSettings.instance).isNotNull()
6646
}
6747

6848
companion object {
6949
private const val APP_ID = "1:1:android:1a"
7050
private const val API_KEY = "API-KEY-API-KEY-API-KEY-API-KEY-API-KEY"
7151
private const val PROJECT_ID = "PROJECT-ID"
52+
53+
@BeforeClass
54+
@JvmStatic
55+
fun setUp() {
56+
Firebase.initialize(
57+
ApplicationProvider.getApplicationContext(),
58+
FirebaseOptions.Builder()
59+
.setApplicationId(APP_ID)
60+
.setApiKey(API_KEY)
61+
.setProjectId(PROJECT_ID)
62+
.build(),
63+
)
64+
}
7265
}
7366
}

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

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

firebase-sessions/src/main/AndroidManifest.xml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<!-- Copyright 2023 Google LLC -->
1+
<?xml version="1.0" encoding="utf-8"?><!-- Copyright 2023 Google LLC -->
32
<!-- -->
43
<!-- Licensed under the Apache License, Version 2.0 (the "License"); -->
54
<!-- you may not use this file except in compliance with the License. -->
@@ -19,11 +18,8 @@
1918

2019
<application>
2120
<service
22-
android:name="com.google.firebase.sessions.SessionLifecycleService"
23-
android:enabled="true"
24-
android:exported="false" />
25-
<service android:name="com.google.firebase.components.ComponentDiscoveryService"
26-
android:exported="false">
21+
android:exported="false"
22+
android:name="com.google.firebase.components.ComponentDiscoveryService">
2723
<meta-data
2824
android:name="com.google.firebase.components:com.google.firebase.sessions.FirebaseSessionsRegistrar"
2925
android:value="com.google.firebase.components.ComponentRegistrar" />

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.google.android.datatransport.Encoding
2121
import com.google.android.datatransport.Event
2222
import com.google.android.datatransport.TransportFactory
2323
import com.google.firebase.inject.Provider
24+
import com.google.firebase.sessions.FirebaseSessions.Companion.TAG
2425
import javax.inject.Inject
2526
import javax.inject.Singleton
2627

@@ -61,8 +62,6 @@ constructor(private val transportFactoryProvider: Provider<TransportFactory>) :
6162
}
6263

6364
companion object {
64-
private const val TAG = "EventGDTLogger"
65-
6665
private const val AQS_LOG_SOURCE = "FIREBASE_APPQUALITY_SESSION"
6766
}
6867
}

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

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ constructor(
3838
private val firebaseApp: FirebaseApp,
3939
private val settings: SessionsSettings,
4040
@Background backgroundDispatcher: CoroutineContext,
41-
lifecycleServiceBinder: SessionLifecycleServiceBinder,
41+
sessionsActivityLifecycleCallbacks: SessionsActivityLifecycleCallbacks,
4242
) {
4343

4444
init {
45-
Log.d(TAG, "Initializing Firebase Sessions SDK.")
45+
Log.d(TAG, "Initializing Firebase Sessions ${BuildConfig.VERSION_NAME}.")
4646
val appContext = firebaseApp.applicationContext.applicationContext
4747
if (appContext is Application) {
48-
appContext.registerActivityLifecycleCallbacks(SessionsActivityLifecycleCallbacks)
48+
appContext.registerActivityLifecycleCallbacks(sessionsActivityLifecycleCallbacks)
4949

5050
CoroutineScope(backgroundDispatcher).launch {
5151
val subscribers = FirebaseSessionsDependencies.getRegisteredSubscribers()
@@ -56,16 +56,12 @@ constructor(
5656
if (!settings.sessionsEnabled) {
5757
Log.d(TAG, "Sessions SDK disabled. Not listening to lifecycle events.")
5858
} else {
59-
val lifecycleClient = SessionLifecycleClient(backgroundDispatcher)
60-
lifecycleClient.bindToService(lifecycleServiceBinder)
61-
SessionsActivityLifecycleCallbacks.lifecycleClient = lifecycleClient
62-
6359
firebaseApp.addLifecycleEventListener { _, _ ->
6460
Log.w(
6561
TAG,
6662
"FirebaseApp instance deleted. Sessions library will stop collecting data.",
6763
)
68-
SessionsActivityLifecycleCallbacks.lifecycleClient = null
64+
sessionsActivityLifecycleCallbacks.onAppDelete()
6965
}
7066
}
7167
}
@@ -79,7 +75,7 @@ constructor(
7975
}
8076

8177
companion object {
82-
private const val TAG = "FirebaseSessions"
78+
internal const val TAG = "FirebaseSessions"
8379

8480
val instance: FirebaseSessions
8581
get() = Firebase.app[FirebaseSessions::class.java]

0 commit comments

Comments
 (0)