Skip to content

Commit 3f2b6e7

Browse files
committed
Merge branch 'fireperf-aqs' into td/aqs-usage
2 parents da8acfa + 1e8b629 commit 3f2b6e7

File tree

6 files changed

+83
-68
lines changed

6 files changed

+83
-68
lines changed

firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerformance.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.google.firebase.perf.config.RemoteConfigManager;
3535
import com.google.firebase.perf.logging.AndroidLogger;
3636
import com.google.firebase.perf.logging.ConsoleUrlGenerator;
37+
import com.google.firebase.perf.logging.DebugEnforcementCheck;
3738
import com.google.firebase.perf.metrics.HttpMetric;
3839
import com.google.firebase.perf.metrics.Trace;
3940
import com.google.firebase.perf.session.FirebasePerformanceSessionSubscriber;
@@ -43,6 +44,7 @@
4344
import com.google.firebase.perf.util.ImmutableBundle;
4445
import com.google.firebase.perf.util.Timer;
4546
import com.google.firebase.remoteconfig.RemoteConfigComponent;
47+
import com.google.firebase.sessions.BuildConfig;
4648
import com.google.firebase.sessions.api.FirebaseSessionsDependencies;
4749
import com.google.firebase.sessions.api.SessionSubscriber;
4850
import java.lang.annotation.Retention;
@@ -173,6 +175,7 @@ public static FirebasePerformance getInstance() {
173175
this.sessionSubscriber = new FirebasePerformanceSessionSubscriber(false);
174176
return;
175177
}
178+
DebugEnforcementCheck.setEnforcement(BuildConfig.DEBUG);
176179

177180
TransportManager.getInstance()
178181
.initialize(firebaseApp, firebaseInstallationsApi, transportFactoryProvider);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2025 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.perf.logging
18+
19+
class DebugEnforcementCheck {
20+
companion object {
21+
/** When enabled, failed preconditions will cause assertion errors for debugging. */
22+
@JvmStatic var enforcement: Boolean = false
23+
private var logger: AndroidLogger = AndroidLogger.getInstance()
24+
25+
public fun checkSession(isAqsAvailable: Boolean, failureMessage: String) {
26+
if (!isAqsAvailable) {
27+
Companion.logger.debug(failureMessage)
28+
assert(!enforcement) { failureMessage }
29+
}
30+
}
31+
}
32+
}

firebase-perf/src/main/java/com/google/firebase/perf/session/FirebasePerformanceSessionSubscriber.kt

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.google.firebase.perf.session
1818

1919
import com.google.firebase.perf.session.gauges.GaugeManager
20-
import com.google.firebase.perf.util.Constants
2120
import com.google.firebase.perf.v1.ApplicationProcessState
2221
import com.google.firebase.sessions.api.SessionSubscriber
2322
import java.util.UUID
@@ -28,26 +27,18 @@ class FirebasePerformanceSessionSubscriber(override val isDataCollectionEnabled:
2827
override val sessionSubscriberName: SessionSubscriber.Name = SessionSubscriber.Name.PERFORMANCE
2928

3029
override fun onSessionChanged(sessionDetails: SessionSubscriber.SessionDetails) {
31-
val sessionManager = SessionManager.getInstance()
32-
val currentPerfSession = sessionManager.perfSession()
33-
val gaugeManager = GaugeManager.getInstance()
30+
val currentPerfSession = SessionManager.getInstance().perfSession()
3431

3532
// A [PerfSession] was created before a session was started.
36-
if (currentPerfSession.aqsSessionId().equals(Constants.UNDEFINED_AQS_ID)) {
37-
currentPerfSession.setAQSId(sessionDetails)
38-
gaugeManager.logGaugeMetadata(
39-
currentPerfSession.aqsSessionId(),
40-
ApplicationProcessState.FOREGROUND
41-
)
42-
// Gauge collection is started in [FirebasePerfEarly] - but it's not scheduled to be
43-
// uploaded. This starts uploading the gauges if it's verbose.
44-
gaugeManager.updateGaugeCollection(ApplicationProcessState.FOREGROUND)
33+
if (!currentPerfSession.isAqsReady) {
34+
GaugeManager.getInstance()
35+
.logGaugeMetadata(currentPerfSession.sessionId(), ApplicationProcessState.FOREGROUND)
4536
return
4637
}
4738

4839
val updatedSession = PerfSession.createWithId(UUID.randomUUID().toString())
49-
updatedSession.setAQSId(sessionDetails)
50-
gaugeManager.logGaugeMetadata(updatedSession.aqsSessionId(), ApplicationProcessState.FOREGROUND)
51-
sessionManager.updatePerfSession(updatedSession)
40+
SessionManager.getInstance().updatePerfSession(updatedSession)
41+
GaugeManager.getInstance()
42+
.logGaugeMetadata(updatedSession.sessionId(), ApplicationProcessState.FOREGROUND)
5243
}
5344
}

firebase-perf/src/main/java/com/google/firebase/perf/session/PerfSession.java

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,70 +21,58 @@
2121
import androidx.annotation.VisibleForTesting;
2222
import com.google.firebase.perf.config.ConfigResolver;
2323
import com.google.firebase.perf.util.Clock;
24-
import com.google.firebase.perf.util.Constants;
2524
import com.google.firebase.perf.util.Timer;
2625
import com.google.firebase.perf.v1.SessionVerbosity;
27-
import com.google.firebase.sessions.api.SessionSubscriber;
2826
import java.util.List;
27+
import java.util.UUID;
2928
import java.util.concurrent.TimeUnit;
3029

3130
/** Details of a session including a unique Id and related information. */
3231
public class PerfSession implements Parcelable {
33-
34-
private final String sessionId;
3532
private final Timer creationTime;
36-
// TODO(b/394127311): Remove this once this isn't needed.
37-
private String aqsSessionId = Constants.UNDEFINED_AQS_ID;
38-
33+
private final String sessionId;
3934
private boolean isGaugeAndEventCollectionEnabled = false;
35+
public final boolean isAqsReady;
4036

4137
/*
4238
* Creates a PerfSession object and decides what metrics to collect.
4339
*/
44-
public static PerfSession createWithId(@NonNull String sessionId) {
45-
String prunedSessionId = sessionId.replace("-", "");
46-
PerfSession session = new PerfSession(prunedSessionId, new Clock());
47-
session.setGaugeAndEventCollectionEnabled(shouldCollectGaugesAndEvents());
48-
40+
public static PerfSession createWithId(@Nullable String aqsSessionId) {
41+
String sessionId;
42+
Boolean isAqsReady;
43+
if (aqsSessionId != null) {
44+
sessionId = aqsSessionId;
45+
isAqsReady = true;
46+
} else {
47+
sessionId = UUID.randomUUID().toString().replace("-", "");
48+
isAqsReady = false;
49+
}
50+
PerfSession session = new PerfSession(sessionId, new Clock(), isAqsReady);
51+
session.setGaugeAndEventCollectionEnabled(shouldCollectGaugesAndEvents(sessionId));
4952
return session;
5053
}
5154

5255
/** Creates a PerfSession with the provided {@code sessionId} and {@code clock}. */
5356
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
54-
public PerfSession(String sessionId, Clock clock) {
57+
public PerfSession(String sessionId, Clock clock, boolean isAqsReady) {
5558
this.sessionId = sessionId;
59+
this.isAqsReady = isAqsReady;
5660
creationTime = clock.getTime();
5761
}
5862

5963
private PerfSession(@NonNull Parcel in) {
6064
super();
6165
sessionId = in.readString();
6266
isGaugeAndEventCollectionEnabled = in.readByte() != 0;
67+
isAqsReady = in.readByte() != 0;
6368
creationTime = in.readParcelable(Timer.class.getClassLoader());
6469
}
6570

66-
/** Returns the sessionId of the session. */
71+
/** Returns the sessionId for the given session. */
6772
public String sessionId() {
6873
return sessionId;
6974
}
7075

71-
/** Returns the AQS sessionId for the given session. */
72-
public String aqsSessionId() {
73-
// This is a fallback for if/when the AQS ID is undefined.
74-
if (aqsSessionId.equals(Constants.UNDEFINED_AQS_ID)) {
75-
// TODO(b/394127311): Explore returning a valid - but different ID.
76-
return Constants.UNDEFINED_AQS_ID;
77-
}
78-
return aqsSessionId;
79-
}
80-
81-
/** Returns the AQS sessionId for the given session. */
82-
public void setAQSId(SessionSubscriber.SessionDetails aqs) {
83-
if (aqsSessionId.equals(Constants.UNDEFINED_AQS_ID)) {
84-
aqsSessionId = aqs.getSessionId();
85-
}
86-
}
87-
8876
/**
8977
* Returns a timer object that has been seeded with the system time at which the session began.
9078
*/
@@ -111,18 +99,6 @@ public boolean isVerbose() {
11199
return isGaugeAndEventCollectionEnabled;
112100
}
113101

114-
/** Checks if the current {@link com.google.firebase.perf.v1.PerfSession} is verbose or not. */
115-
@VisibleForTesting
116-
static boolean isVerbose(@NonNull com.google.firebase.perf.v1.PerfSession perfSession) {
117-
for (SessionVerbosity sessionVerbosity : perfSession.getSessionVerbosityList()) {
118-
if (sessionVerbosity == SessionVerbosity.GAUGES_AND_SYSTEM_EVENTS) {
119-
return true;
120-
}
121-
}
122-
123-
return false;
124-
}
125-
126102
/**
127103
* Checks if it has been more than {@link ConfigResolver#getSessionsMaxDurationMinutes()} time
128104
* since the creation time of the current session.
@@ -134,9 +110,8 @@ public boolean isSessionRunningTooLong() {
134110

135111
/** Creates and returns the proto object for PerfSession object. */
136112
public com.google.firebase.perf.v1.PerfSession build() {
137-
// TODO(b/394127311): Switch to using AQS.
138113
com.google.firebase.perf.v1.PerfSession.Builder sessionMetric =
139-
com.google.firebase.perf.v1.PerfSession.newBuilder().setSessionId(aqsSessionId);
114+
com.google.firebase.perf.v1.PerfSession.newBuilder().setSessionId(sessionId);
140115

141116
// If gauge collection is enabled, enable gauge collection verbosity.
142117
if (isGaugeAndEventCollectionEnabled) {
@@ -185,11 +160,10 @@ public static com.google.firebase.perf.v1.PerfSession[] buildAndSort(
185160
}
186161

187162
/** If true, Session Gauge collection is enabled. */
188-
public static boolean shouldCollectGaugesAndEvents() {
163+
public static boolean shouldCollectGaugesAndEvents(String sessionId) {
189164
ConfigResolver configResolver = ConfigResolver.getInstance();
190-
191165
return configResolver.isPerformanceMonitoringEnabled()
192-
&& Math.random() < configResolver.getSessionsSamplingRate();
166+
&& (Math.abs(sessionId.hashCode() % 100) < configResolver.getSessionsSamplingRate() * 100);
193167
}
194168

195169
/**
@@ -213,6 +187,7 @@ public int describeContents() {
213187
public void writeToParcel(@NonNull Parcel out, int flags) {
214188
out.writeString(sessionId);
215189
out.writeByte((byte) (isGaugeAndEventCollectionEnabled ? 1 : 0));
190+
out.writeByte((byte) (isAqsReady ? 1 : 0));
216191
out.writeParcelable(creationTime, 0);
217192
}
218193

@@ -230,4 +205,16 @@ public PerfSession[] newArray(int size) {
230205
return new PerfSession[size];
231206
}
232207
};
208+
209+
/** Checks if the current {@link com.google.firebase.perf.v1.PerfSession} is verbose or not. */
210+
@VisibleForTesting
211+
static boolean isVerbose(@NonNull com.google.firebase.perf.v1.PerfSession perfSession) {
212+
for (SessionVerbosity sessionVerbosity : perfSession.getSessionVerbosityList()) {
213+
if (sessionVerbosity == SessionVerbosity.GAUGES_AND_SYSTEM_EVENTS) {
214+
return true;
215+
}
216+
}
217+
218+
return false;
219+
}
233220
}

firebase-perf/src/test/java/com/google/firebase/perf/application/AppStateMonitorTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
import com.google.firebase.perf.config.DeviceCacheManager;
4040
import com.google.firebase.perf.metrics.NetworkRequestMetricBuilder;
4141
import com.google.firebase.perf.metrics.Trace;
42+
import com.google.firebase.perf.session.PerfSession;
43+
import com.google.firebase.perf.session.SessionManager;
4244
import com.google.firebase.perf.session.gauges.GaugeManager;
4345
import com.google.firebase.perf.transport.TransportManager;
4446
import com.google.firebase.perf.util.Clock;
@@ -80,6 +82,7 @@ public class AppStateMonitorTest extends FirebasePerformanceTestBase {
8082
@Before
8183
public void setUp() {
8284
currentTime = 0;
85+
SessionManager.getInstance().updatePerfSession(PerfSession.createWithId("sessionId"));
8386
initMocks(this);
8487
doAnswer((Answer<Timer>) invocationOnMock -> new Timer(currentTime)).when(clock).getTime();
8588

firebase-perf/src/test/java/com/google/firebase/perf/session/SessionManagerTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public void setUp() {
6666
public void testInstanceCreation() {
6767
assertThat(SessionManager.getInstance()).isNotNull();
6868
assertThat(SessionManager.getInstance()).isEqualTo(SessionManager.getInstance());
69-
assertThat(SessionManager.getInstance().perfSession().sessionId()).isNotNull();
7069
}
7170

7271
@Test
@@ -113,7 +112,7 @@ public void testSessionIdDoesNotUpdateIfPerfSessionRunsTooLong() {
113112
Timer mockTimer = mock(Timer.class);
114113
when(mockClock.getTime()).thenReturn(mockTimer);
115114

116-
PerfSession session = new PerfSession("sessionId", mockClock);
115+
PerfSession session = new PerfSession("sessionId", mockClock, true);
117116
SessionManager testSessionManager =
118117
new SessionManager(mockGaugeManager, session, mockAppStateMonitor);
119118

@@ -132,10 +131,10 @@ public void testUpdatePerfSessionStartsCollectingGaugesIfSessionIsVerbose() {
132131
when(mockClock.getTime()).thenReturn(mockTimer);
133132
when(mockAppStateMonitor.getAppState()).thenReturn(ApplicationProcessState.FOREGROUND);
134133

135-
PerfSession previousSession = new PerfSession("previousSession", mockClock);
134+
PerfSession previousSession = new PerfSession("previousSession", mockClock, true);
136135
previousSession.setGaugeAndEventCollectionEnabled(false);
137136

138-
PerfSession newSession = new PerfSession("newSession", mockClock);
137+
PerfSession newSession = new PerfSession("newSession", mockClock, true);
139138
newSession.setGaugeAndEventCollectionEnabled(true);
140139

141140
SessionManager testSessionManager =

0 commit comments

Comments
 (0)