Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use AQS for Firebase Performance sessions. #6665

Draft
wants to merge 145 commits into
base: fireperf-aqs
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
145 commits
Select commit Hold shift + click to select a range
3e15e86
Upload a prototype of lazy AQS mapping
tejasd Feb 3, 2025
ad7217a
Improve logging
tejasd Feb 3, 2025
aa0da1f
Better logging
tejasd Feb 3, 2025
9a91b1b
Switch the proto value to the AQS session
tejasd Feb 3, 2025
ed9f56c
Remove TODO in AppStartTrace
tejasd Feb 3, 2025
ed765f5
style
tejasd Feb 3, 2025
4ea928d
Merge branch 'main' into td/fireperf-aqs
tejasd Feb 3, 2025
d355af2
remove cold start gauge name
tejasd Feb 3, 2025
4096b0a
More changes
tejasd Feb 3, 2025
ff75fd9
Update comments
tejasd Feb 3, 2025
6bdf12c
Style
tejasd Feb 4, 2025
4e75c31
Change sessions dependency to HEAD
tejasd Feb 4, 2025
407df2a
Switch to a singleton Fireperf session subscriber
tejasd Feb 4, 2025
eb341c0
Revert session manager test
tejasd Feb 4, 2025
042ee43
Update SessionManagerTest
tejasd Feb 4, 2025
bacc81f
Update SessionManagerTest
tejasd Feb 4, 2025
f2b30fe
Remove calling defaultInstance as it's already called in FirebasePerf…
tejasd Feb 4, 2025
db14ff5
More test changes
tejasd Feb 5, 2025
0b1be56
style
tejasd Feb 5, 2025
dfbc521
Change the location of registering subscriber
tejasd Feb 5, 2025
21d4778
Update subscriber
tejasd Feb 5, 2025
9731146
Revert internal perf session id
tejasd Feb 5, 2025
b942120
Attempt to simplify AQS session usage
tejasd Feb 5, 2025
6899fde
Update tests
tejasd Feb 5, 2025
5676892
Update prefix
tejasd Feb 5, 2025
e4b7114
Update prefix
tejasd Feb 5, 2025
79aac4c
Improve logging and adda TODO
tejasd Feb 6, 2025
5093a85
Additional TODO
tejasd Feb 6, 2025
8a8e8ed
Remove the logging of GaugeMetadata based on AppStart
tejasd Feb 6, 2025
c606723
Remove file based memory reading test
tejasd Feb 6, 2025
148b068
Add TODO to re-introduce metadata logging
tejasd Feb 6, 2025
3e03785
Merge branch 'td/fireperf-gauge-metadata' into td/fireperf-aqs
tejasd Feb 6, 2025
4c637aa
Re-introduce gauge metadata collection
tejasd Feb 6, 2025
705ceea
Delete gaugeMetadata tests that correctly fail
tejasd Feb 6, 2025
c2e355e
Fix unit test
tejasd Feb 6, 2025
a9e8354
Remove LinkedHashMap TODO.
tejasd Feb 6, 2025
d803be6
Remove LinkedHashMap TODO.
tejasd Feb 6, 2025
4dd97ac
Additional changes
tejasd Feb 7, 2025
c726a1a
Fix ModuleVersion bumping (#6679)
daymxn Feb 6, 2025
7a13c36
m159 mergeback (#6680)
google-oss-bot Feb 7, 2025
0c02c4c
dataconnect: DataConnectExecutableVersions.json updated with versions…
dconeybe Feb 7, 2025
d1cba61
dataconnect.yaml: improve readability of the output of the "tool vers…
dconeybe Feb 7, 2025
944cdca
dataconnect: fix cache key conflict on nighty integration tests runs …
dconeybe Feb 7, 2025
582107a
Add support for token-based usage metrics (#6658)
rlazo Feb 8, 2025
5716006
Add support for new FinishReason and BlockReason values (#6685)
davidmotson Feb 10, 2025
363a863
Fix deprecated message in KeyValueBuilder to render properly (#6691)
mrober Feb 10, 2025
d6551c3
Add functions changelog (#6694)
emilypgoogle Feb 11, 2025
809b794
Make token count details fields non-nullable (#6695)
rlazo Feb 11, 2025
a889148
dataconnect: fix generation of invalid timestamp values in internal t…
dconeybe Feb 12, 2025
c6a138d
dataconnect: improve cache restoration in github actions workflow (#6…
dconeybe Feb 12, 2025
7befca5
Make AQS resilient to background init in multi-process apps (#6699)
mrober Feb 13, 2025
4fd7c2d
Followup to #6699 (#6701)
mrober Feb 13, 2025
d9f4fdb
docs: update ImagePart refdocs (#6681)
thatfiredev Feb 17, 2025
f14ef94
Initial implementation to API spec (#6607)
davidmotson Feb 19, 2025
65ff901
add new recipe entries to BoM generator (#6702)
davidmotson Feb 21, 2025
465a729
Improve imagen Java API (#6712)
rlazo Feb 24, 2025
7f2271d
Remove test code left by mistake (#6717)
rlazo Feb 24, 2025
c600ab1
Add missing optIn declarations to reduce compilation noise (#6713)
rlazo Feb 24, 2025
ad9f6e2
Support custom tabs in more browsers (#6705)
Fry-kun Feb 24, 2025
feeeed6
Update CHANGELOG for Crashlytics and NDK (#6719)
mrober Feb 24, 2025
dcb3cb0
Bump well known types (#6716)
daymxn Feb 24, 2025
befade7
Update CHANGELOG.md (#6718)
lfkellogg Feb 24, 2025
7ea169a
Add custom signal limits link and fix Javadoc List Formatting (#6722)
tusharkhandelwal8 Feb 26, 2025
4228d93
Fix documentation for ImagenGenerationResponse (#6728)
davidmotson Feb 26, 2025
c372b1d
Add copyApiTxtFile task (#6724)
emilypgoogle Feb 26, 2025
1e9c290
dataconnect: minor cosmetic changes to the github actions workflow (#…
dconeybe Feb 26, 2025
d7b14a0
Bump truth from 1.4.2 to 1.4.4 (#6723)
dependabot[bot] Feb 27, 2025
d2365b2
Bump semver from 7.5.0 to 7.5.4 in /smoke-tests/src/androidTest/backe…
dependabot[bot] Feb 27, 2025
0209463
build(deps): bump com.fasterxml.jackson.core:jackson-databind from 2.…
dependabot[bot] Feb 27, 2025
f4195ae
dataconnect: DataConnectExecutableVersions.json updated with versions…
dconeybe Feb 27, 2025
190d096
dataconnect: change grpc api version from "v1beta" to "v1" (#6729)
dconeybe Feb 27, 2025
2ad9b2c
Add Metalava SemVer Task (#6725)
emilypgoogle Feb 28, 2025
53f3238
Use lazy encoding in utf-8 encoded string comparison (#6706)
milaGGL Mar 3, 2025
3df1a40
Avoid Process.myProcessName() on Android 13 (#6720)
mrober Mar 3, 2025
a0fee48
Fix bug that let responsePayloadBytes get set to -1 (#6721)
mrober Mar 3, 2025
df70f99
Update datastore dependency to 1.1.3 (#6688)
mrober Mar 4, 2025
948e98c
build(deps): bump org.eclipse.jgit:org.eclipse.jgit from 6.3.0.202209…
dependabot[bot] Mar 4, 2025
636e474
build(deps): bump kotestAssertionsCore from 5.5.5 to 5.8.1 (#6736)
rlazo Mar 5, 2025
be00f2c
Remove unnecessary steps in CI Testing for vertex (#6743)
rlazo Mar 7, 2025
d5801dc
Update functions changelog (#6751)
rlazo Mar 10, 2025
d32c474
[VertexAI] Add initial support to export covered API (#6749)
rlazo Mar 10, 2025
606a4bb
Remove code style from deprecated message (#6753)
mrober Mar 10, 2025
3440cc1
Store registered context for sync task unregistrations (#6752)
welishr Mar 10, 2025
1c59236
Extend Firebase SDK with new APIs to consume streaming callable funct…
MustafaJadid2025 Mar 10, 2025
c0fba25
[Functions] Send the placeholder appcheck token in case of error (#6750)
rlazo Mar 10, 2025
04b1e21
Read version control info from Android resource (#6754)
mrober Mar 11, 2025
c1ffa6f
Use Dagger for dependency injection in Sessions (#6745)
mrober Mar 11, 2025
a59649e
Add warning for known issue b/328687152 (#6755)
mrober Mar 11, 2025
6e7b7a1
m160 mergeback (#6757)
google-oss-bot Mar 11, 2025
3c839f3
[Vertex AI] Remove `golden-files` directory (#6740)
andrewheard Mar 11, 2025
7fa9a5c
build(deps): bump app.cash.turbine:turbine from 1.0.0 to 1.2.0 (#6738)
dependabot[bot] Mar 11, 2025
575616e
Update changelogs and versions for Crashlytics, Perf, and AQS (#6758)
mrober Mar 11, 2025
ee7bb8e
build(deps): bump com.google.firebase:firebase-appdistribution-gradle…
dependabot[bot] Mar 12, 2025
107a8bd
Adjust Create Release (#6761)
emilypgoogle Mar 12, 2025
d1c42a7
Add GenerationConfig to CountTokenRequest's (#6768)
rlazo Mar 13, 2025
bea2cbe
[VertexAI] Remove redundant tests (#6762)
rlazo Mar 13, 2025
d0a7226
Add m161 changelog for functions (#6769)
emilypgoogle Mar 13, 2025
8eb67a8
dataconnect: demo: upgrade versions in build.gradle.kts (#6776)
dconeybe Mar 14, 2025
06ce410
chore(functions): export reactive-streams as a transitive dependency …
thatfiredev Mar 14, 2025
2078c9b
fix(functions): use notifyError() instead of throwing (#6773)
thatfiredev Mar 14, 2025
be7561f
fix for new version of golden files (#6771)
davidmotson Mar 17, 2025
581d082
build(deps): bump androidx.core:core from 1.2.0 to 1.15.0 (#6764)
dependabot[bot] Mar 18, 2025
556fec2
Simplify settings package and a few more classes using DI (#6778)
mrober Mar 19, 2025
fbbf1fe
Setup kotlinx.serialization plugin (#6783)
mrober Mar 19, 2025
68f8a35
Swap external action to verify changed files for inline code (#6779)
rlazo Mar 19, 2025
48d5fc6
[github actions] Pin actions to hash commits (#6784)
rlazo Mar 19, 2025
41bc680
Add transform action to remove package prefix in toc files (#6787)
daymxn Mar 20, 2025
6fabfee
include the full googleid module in GenerateTutorialBundleTask.kt (#6…
thatfiredev Mar 21, 2025
338d24e
ci: add missing permissions to .github/workflows/plugins-check.yml (#…
thatfiredev Mar 21, 2025
613f362
dataconnect: remove "beta" version marker and graduate the data conne…
dconeybe Mar 21, 2025
0d9b060
m161 mergeback (#6793)
google-oss-bot Mar 21, 2025
4979a97
[Functions] Several functions improvements (#6796)
rlazo Mar 24, 2025
b17a495
[DataConnect] Update release configuration (#6798)
rlazo Mar 24, 2025
269a571
[DataConnect] Add changelog entry back (#6799)
rlazo Mar 24, 2025
3018f69
dataconnect: DataConnectExecutableVersions.json updated with versions…
dconeybe Mar 24, 2025
e02250a
dataconnect: generateApiTxtFile.sh added (#6802)
dconeybe Mar 24, 2025
8dee61d
feat: dataconnect: DataConnectOperationException added to support par…
dconeybe Mar 24, 2025
c7fb101
Add fix for API info task (#6808)
emilypgoogle Mar 25, 2025
a7cbb02
[VertexAI] Bump timeout for error test (#6807)
rlazo Mar 25, 2025
307ef13
[Vertex AI] Return `ImagenInlineImage.data` as binary (#6800)
andrewheard Mar 25, 2025
a4727f0
Add ML monitoring info to GenAI requests (#6804)
davidmotson Mar 25, 2025
fbab9fc
[VertexAI] Log warning for unsupported model names (#6805)
rlazo Mar 25, 2025
e3e6119
Updated internal Crashpad version (#6797)
mrober Mar 26, 2025
cc89daa
Add basic Vertex Java compilation tests (#6810)
emilypgoogle Mar 26, 2025
0cb7a77
Upgrade to Android ndk r27c and update Crashpad to latest commit (#6814)
mrober Mar 27, 2025
2748033
Fix startup check failures (#6820)
daymxn Mar 28, 2025
afa1197
[Functions] Bump all test timeouts to 10 seconds (#6821)
rlazo Mar 28, 2025
e26be15
Bidirectional Streaming Android (#6759)
VinayGuthal Mar 28, 2025
2299b50
Changes in the Session Test App to verify behaviour with Fireperf #no…
tejasd Mar 31, 2025
b14a2f4
Remove the logging of GaugeMetadata to allow using AQS (#6678)
tejasd Feb 7, 2025
c1a097b
Implement a SessionSubscriber for Firebase Performance (#6683)
tejasd Feb 11, 2025
1fcbed6
Use multi-process DataStore instead of Preferences DataStore (#6781)
mrober Mar 20, 2025
4d7bff9
Share settings cache between running processes (#6788)
mrober Mar 24, 2025
cd9387b
Upload a prototype of lazy AQS mapping
tejasd Feb 3, 2025
8acc84b
Better logging
tejasd Feb 3, 2025
66a8afc
style
tejasd Feb 3, 2025
a5249ac
Change sessions dependency to HEAD
tejasd Feb 4, 2025
6855a97
Update subscriber
tejasd Feb 5, 2025
bc01620
Attempt to simplify AQS session usage
tejasd Feb 5, 2025
99243ed
Remove the logging of GaugeMetadata based on AppStart
tejasd Feb 6, 2025
d6efa32
Remove file based memory reading test
tejasd Feb 6, 2025
9e15726
Add TODO to re-introduce metadata logging
tejasd Feb 6, 2025
c87b3dd
Re-introduce gauge metadata collection
tejasd Feb 6, 2025
b94bd77
Delete gaugeMetadata tests that correctly fail
tejasd Feb 6, 2025
8738761
Merge branch 'fireperf-aqs' into td/fireperf-aqs
tejasd Apr 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.google.firebase.StartupTime;
import com.google.firebase.perf.application.AppStateMonitor;
import com.google.firebase.perf.config.ConfigResolver;
import com.google.firebase.perf.logging.AndroidLogger;
import com.google.firebase.perf.metrics.AppStartTrace;
import com.google.firebase.perf.session.SessionManager;
import java.util.concurrent.Executor;
Expand Down Expand Up @@ -51,12 +52,11 @@ public FirebasePerfEarly(
uiExecutor.execute(new AppStartTrace.StartFromBackgroundRunnable(appStartTrace));
}

// TODO: Bring back Firebase Sessions dependency to watch for updates to sessions.

// In the case of cold start, we create a session and start collecting gauges as early as
// possible.
// There is code in SessionManager that prevents us from resetting the session twice in case
// of app cold start.
AndroidLogger.getInstance().debug("Initializing Gauge Collection");
SessionManager.getInstance().initializeGaugeCollection();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ public class FirebasePerfRegistrar implements ComponentRegistrar {
private static final String EARLY_LIBRARY_NAME = "fire-perf-early";

static {
// Add Firebase Performance as a dependency of Sessions when this class is loaded into memory.
FirebaseSessionsDependencies.addDependency(SessionSubscriber.Name.PERFORMANCE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ public static FirebasePerformance getInstance() {
return;
}

// Prioritize registering the FirebaseSession dependency to have the session
// `setApplicationContext`.
FirebaseSessionsDependencies.register(
FirebasePerformanceSessionSubscriber.Companion.getInstance());
TransportManager.getInstance()
.initialize(firebaseApp, firebaseInstallationsApi, transportFactoryProvider);

Expand All @@ -193,6 +197,9 @@ public static FirebasePerformance getInstance() {
ConsoleUrlGenerator.generateDashboardUrl(
firebaseApp.getOptions().getProjectId(), appContext.getPackageName())));
}

SessionManagerKt sessionSubscriber = new SessionManagerKt(isPerformanceCollectionEnabled());
FirebaseSessionsDependencies.register(sessionSubscriber);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public void setMetadataBundle(ImmutableBundle bundle) {
/** Default API to call for whether performance monitoring is currently silent. */
public boolean isPerformanceMonitoringEnabled() {
Boolean isPerformanceCollectionEnabled = getIsPerformanceCollectionEnabled();
return (isPerformanceCollectionEnabled == null || isPerformanceCollectionEnabled == true)
return (isPerformanceCollectionEnabled == null || isPerformanceCollectionEnabled)
&& getIsServiceCollectionEnabled();
}

Expand All @@ -131,7 +131,7 @@ public Boolean getIsPerformanceCollectionEnabled() {
// return developer config.
// 4. Else, return null. Because Firebase Performance will read highlevel Firebase flag in this
// case.
if (getIsPerformanceCollectionDeactivated()) {
if (Boolean.TRUE.equals(getIsPerformanceCollectionDeactivated())) {
// 1. If developer has deactivated Firebase Performance in Manifest, return false.
return false;
}
Expand Down Expand Up @@ -186,7 +186,7 @@ public void setIsPerformanceCollectionEnabled(Boolean isEnabled) {
// 2. Otherwise, save this configuration in device cache.

// If collection is deactivated, skip the action to save user configuration.
if (getIsPerformanceCollectionDeactivated()) {
if (Boolean.TRUE.equals(getIsPerformanceCollectionDeactivated())) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,58 @@
/*
* Copyright 2025 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.firebase.perf.session

import com.google.firebase.perf.config.ConfigResolver
import com.google.firebase.perf.logging.AndroidLogger
import com.google.firebase.perf.session.gauges.GaugeManager
import com.google.firebase.perf.v1.ApplicationProcessState
import com.google.firebase.sessions.api.SessionSubscriber
import java.util.UUID

class FirebasePerformanceSessionSubscriber(override val isDataCollectionEnabled: Boolean) :
class FirebasePerformanceSessionSubscriber(private val dataCollectionEnabled: Boolean) :
SessionSubscriber {
private val perfSessionToAqs: MutableMap<String, SessionSubscriber.SessionDetails?> =
mutableMapOf()

override val isDataCollectionEnabled: Boolean
get() = dataCollectionEnabled

override val sessionSubscriberName: SessionSubscriber.Name = SessionSubscriber.Name.PERFORMANCE
override val sessionSubscriberName: SessionSubscriber.Name
get() = SessionSubscriber.Name.PERFORMANCE

override fun onSessionChanged(sessionDetails: SessionSubscriber.SessionDetails) {
val currentPerfSession = SessionManager.getInstance().perfSession()

// A [PerfSession] was created before a session was started.
if (currentPerfSession.aqsSessionId() == null) {
currentPerfSession.setAQSId(sessionDetails)
GaugeManager.getInstance()
.logGaugeMetadata(currentPerfSession.aqsSessionId(), ApplicationProcessState.FOREGROUND)
return
AndroidLogger.getInstance().debug("AQS Session Changed: $sessionDetails")
val currentInternalSessionId = SessionManager.getInstance().perfSession().internalSessionId

// There can be situations where a new [PerfSession] was created, but an AQS wasn't
// available (during cold start).
if (perfSessionToAqs[currentInternalSessionId] == null) {
perfSessionToAqs[currentInternalSessionId] = sessionDetails
} else {
val newSession = PerfSession.createNewSession()
SessionManager.getInstance().updatePerfSession(newSession)
perfSessionToAqs[newSession.internalSessionId] = sessionDetails
}

val updatedSession = PerfSession.createWithId(UUID.randomUUID().toString())
updatedSession.setAQSId(sessionDetails)
SessionManager.getInstance().updatePerfSession(updatedSession)
GaugeManager.getInstance()
.logGaugeMetadata(updatedSession.aqsSessionId(), ApplicationProcessState.FOREGROUND)
// Always log GaugeMetadata when a session changes.
GaugeManager.getInstance().logGaugeMetadata(sessionDetails.sessionId)
}

fun reportPerfSession(perfSessionId: String) {
perfSessionToAqs[perfSessionId] = null
}

fun getAqsMappedToPerfSession(perfSessionId: String): String {
AndroidLogger.getInstance()
.debug("AQS for perf session $perfSessionId is ${perfSessionToAqs[perfSessionId]?.sessionId}")
return perfSessionToAqs[perfSessionId]?.sessionId ?: perfSessionId
}

fun clearSessionForTest() {
perfSessionToAqs.clear()
}

companion object {
val instance: FirebasePerformanceSessionSubscriber by lazy {
FirebasePerformanceSessionSubscriber(
ConfigResolver.getInstance().isPerformanceMonitoringEnabled
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
import com.google.firebase.perf.v1.SessionVerbosity;
import com.google.firebase.sessions.api.SessionSubscriber;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/** Details of a session including a unique Id and related information. */
public class PerfSession implements Parcelable {

private static final String SESSION_ID_PREFIX = "fireperf-session";
private final String sessionId;
private final Timer creationTime;
@Nullable private String aqsSessionId;
Expand All @@ -39,11 +41,10 @@ public class PerfSession implements Parcelable {
/*
* Creates a PerfSession object and decides what metrics to collect.
*/
public static PerfSession createWithId(@NonNull String sessionId) {
String prunedSessionId = sessionId.replace("-", "");
public static PerfSession createNewSession() {
String prunedSessionId = SESSION_ID_PREFIX + UUID.randomUUID().toString().replace("-", "");
PerfSession session = new PerfSession(prunedSessionId, new Clock());
session.setGaugeAndEventCollectionEnabled(shouldCollectGaugesAndEvents());

return session;
}

Expand All @@ -52,6 +53,11 @@ public static PerfSession createWithId(@NonNull String sessionId) {
public PerfSession(String sessionId, Clock clock) {
this.sessionId = sessionId;
creationTime = clock.getTime();
// Every time a PerfSession is created, it sets the AQS to null. Once an AQS is received,
// SessionManagerKt verifies if this is an active session, and sets the AQS session ID.
// The assumption is that new PerfSessions *should* be limited to either App Start, or through
// AQS.
FirebasePerformanceSessionSubscriber.Companion.getInstance().reportPerfSession(sessionId);
}

private PerfSession(@NonNull Parcel in) {
Expand All @@ -63,7 +69,12 @@ private PerfSession(@NonNull Parcel in) {

/** Returns the sessionId of the session. */
public String sessionId() {
return sessionId;
return this.sessionId;
}

private String aqsSessionId() {
return FirebasePerformanceSessionSubscriber.Companion.getInstance()
.getAqsMappedToPerfSession(this.sessionId);
}

/** Returns the AQS sessionId for the given session. */
Expand Down Expand Up @@ -130,7 +141,7 @@ public boolean isSessionRunningTooLong() {
public com.google.firebase.perf.v1.PerfSession build() {
// TODO(b/394127311): Switch to using AQS.
com.google.firebase.perf.v1.PerfSession.Builder sessionMetric =
com.google.firebase.perf.v1.PerfSession.newBuilder().setSessionId(sessionId);
com.google.firebase.perf.v1.PerfSession.newBuilder().setSessionId(aqsSessionId());

// If gauge collection is enabled, enable gauge collection verbosity.
if (isGaugeAndEventCollectionEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import androidx.annotation.Keep;
import androidx.annotation.VisibleForTesting;
import com.google.firebase.perf.application.AppStateMonitor;
import com.google.firebase.perf.logging.AndroidLogger;
import com.google.firebase.perf.session.gauges.GaugeManager;
import com.google.firebase.perf.v1.ApplicationProcessState;
import com.google.firebase.perf.v1.GaugeMetadata;
Expand All @@ -28,7 +29,7 @@
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Future;

/** Session manager to generate sessionIDs and broadcast to the application. */
@Keep // Needed because of b/117526359.
Expand All @@ -42,6 +43,7 @@ public class SessionManager {
private final Set<WeakReference<SessionAwareObject>> clients = new HashSet<>();

private PerfSession perfSession;
private Future syncInitFuture;

/** Returns the singleton instance of SessionManager. */
public static SessionManager getInstance() {
Expand All @@ -55,10 +57,7 @@ public final PerfSession perfSession() {

private SessionManager() {
// Generate a new sessionID for every cold start.
this(
GaugeManager.getInstance(),
PerfSession.createWithId(UUID.randomUUID().toString()),
AppStateMonitor.getInstance());
this(GaugeManager.getInstance(), PerfSession.createNewSession(), AppStateMonitor.getInstance());
}

@VisibleForTesting
Expand All @@ -74,7 +73,7 @@ public SessionManager(
* (currently that is before onResume finishes) to ensure gauge collection starts on time.
*/
public void setApplicationContext(final Context appContext) {
gaugeManager.initializeGaugeMetadataManager(appContext);
gaugeManager.initializeGaugeMetadataManager(appContext, ApplicationProcessState.FOREGROUND);
}

/**
Expand Down Expand Up @@ -102,6 +101,8 @@ public void updatePerfSession(PerfSession perfSession) {
return;
}

AndroidLogger.getInstance().debug("Perf Session Changed: " + perfSession);

this.perfSession = perfSession;

synchronized (clients) {
Expand Down Expand Up @@ -167,4 +168,9 @@ private void startOrStopCollectingGauges(ApplicationProcessState appState) {
public void setPerfSession(PerfSession perfSession) {
this.perfSession = perfSession;
}

@VisibleForTesting
public Future getSyncInitFuture() {
return this.syncInitFuture;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.google.firebase.components.Lazy;
import com.google.firebase.perf.config.ConfigResolver;
import com.google.firebase.perf.logging.AndroidLogger;
import com.google.firebase.perf.session.FirebasePerformanceSessionSubscriber;
import com.google.firebase.perf.session.PerfSession;
import com.google.firebase.perf.transport.TransportManager;
import com.google.firebase.perf.util.Timer;
Expand Down Expand Up @@ -59,7 +60,7 @@ public class GaugeManager {
private final TransportManager transportManager;

@Nullable private GaugeMetadataManager gaugeMetadataManager;
@Nullable private ScheduledFuture gaugeManagerDataCollectionJob = null;
@Nullable private ScheduledFuture<?> gaugeManagerDataCollectionJob = null;
@Nullable private String sessionId = null;
private ApplicationProcessState applicationProcessState =
ApplicationProcessState.APPLICATION_PROCESS_STATE_UNKNOWN;
Expand Down Expand Up @@ -94,8 +95,10 @@ private GaugeManager() {
}

/** Initializes GaugeMetadataManager which requires application context. */
public void initializeGaugeMetadataManager(Context appContext) {
public void initializeGaugeMetadataManager(
Context appContext, ApplicationProcessState applicationProcessState) {
this.gaugeMetadataManager = new GaugeMetadataManager(appContext);
this.applicationProcessState = applicationProcessState;
}

/** Returns the singleton instance of this class. */
Expand Down Expand Up @@ -136,7 +139,6 @@ public void startCollectingGauges(
final String sessionIdForScheduledTask = sessionId;
final ApplicationProcessState applicationProcessStateForScheduledTask = applicationProcessState;

// TODO(b/394127311): Switch to using AQS.
try {
gaugeManagerDataCollectionJob =
gaugeManagerExecutor
Expand Down Expand Up @@ -205,10 +207,9 @@ public void stopCollectingGauges() {
gaugeManagerDataCollectionJob.cancel(false);
}

// TODO(b/394127311): Switch to using AQS.
// Flush any data that was collected for this session one last time.
@SuppressWarnings("FutureReturnValueIgnored")
ScheduledFuture unusedFuture =
ScheduledFuture<?> unusedFuture =
gaugeManagerExecutor
.get()
.schedule(
Expand Down Expand Up @@ -244,31 +245,32 @@ private void syncFlush(String sessionId, ApplicationProcessState appState) {
}

// Adding Session ID info.
// TODO(b/394127311): Switch to using AQS.
gaugeMetricBuilder.setSessionId(sessionId);
String aqsSessionId =
FirebasePerformanceSessionSubscriber.Companion.getInstance()
.getAqsMappedToPerfSession(sessionId);
gaugeMetricBuilder.setSessionId(aqsSessionId);
AndroidLogger.getInstance().debug("CFPR syncFlush: " + sessionId + " AQS: " + aqsSessionId);

transportManager.log(gaugeMetricBuilder.build(), appState);
}

/**
* Log the Gauge Metadata information to the transport.
*
* @param aqsSessionId The {@link PerfSession#aqsSessionId()} ()} to which the collected Gauge Metrics
* @param aqsSessionId The {@link FirebasePerformanceSessionSubscriber#getAqsMappedToPerfSession(String)} to which the collected Gauge Metrics
* should be associated with.
* @param appState The {@link ApplicationProcessState} for which these gauges are collected.
* @return true if GaugeMetadata was logged, false otherwise.
*/
public boolean logGaugeMetadata(String aqsSessionId, ApplicationProcessState appState) {
if (gaugeMetadataManager != null) {
GaugeMetric gaugeMetric =
GaugeMetric.newBuilder()
.setSessionId(aqsSessionId)
.setGaugeMetadata(getGaugeMetadata())
.build();
transportManager.log(gaugeMetric, appState);
return true;
}
return false;
public void logGaugeMetadata(String aqsSessionId) {
// TODO(b/394127311): This can now throw an NPE. Explore if there's anything that should be
// verified.
AndroidLogger.getInstance().debug("CFPR logGaugeMetadata: " + aqsSessionId);
GaugeMetric gaugeMetric =
GaugeMetric.newBuilder()
.setSessionId(aqsSessionId)
.setGaugeMetadata(getGaugeMetadata())
.build();
transportManager.log(gaugeMetric, this.applicationProcessState);
}

private GaugeMetadata getGaugeMetadata() {
Expand Down
Loading
Loading