Skip to content

Commit 83ef216

Browse files
committed
convert perf session to use aqs support session id
1 parent fcd270c commit 83ef216

File tree

8 files changed

+101
-109
lines changed

8 files changed

+101
-109
lines changed

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

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,16 @@ package com.google.firebase.perf.session
1919
import com.google.firebase.perf.session.gauges.GaugeManager
2020
import com.google.firebase.perf.v1.ApplicationProcessState
2121
import com.google.firebase.sessions.api.SessionSubscriber
22-
import java.util.UUID
2322

2423
class FirebasePerformanceSessionSubscriber(override val isDataCollectionEnabled: Boolean) :
2524
SessionSubscriber {
2625

2726
override val sessionSubscriberName: SessionSubscriber.Name = SessionSubscriber.Name.PERFORMANCE
2827

2928
override fun onSessionChanged(sessionDetails: SessionSubscriber.SessionDetails) {
30-
val currentPerfSession = SessionManager.getInstance().perfSession()
31-
32-
// A [PerfSession] was created before a session was started.
33-
if (currentPerfSession.aqsSessionId() == null) {
34-
currentPerfSession.setAQSId(sessionDetails)
35-
GaugeManager.getInstance()
36-
.logGaugeMetadata(currentPerfSession.aqsSessionId(), ApplicationProcessState.FOREGROUND)
37-
return
38-
}
39-
40-
val updatedSession = PerfSession.createWithId(UUID.randomUUID().toString())
41-
updatedSession.setAQSId(sessionDetails)
29+
val updatedSession = PerfSession.createWithId(sessionDetails.sessionId)
4230
SessionManager.getInstance().updatePerfSession(updatedSession)
4331
GaugeManager.getInstance()
44-
.logGaugeMetadata(updatedSession.aqsSessionId(), ApplicationProcessState.FOREGROUND)
32+
.logGaugeMetadata(updatedSession.sessionId(), ApplicationProcessState.FOREGROUND)
4533
}
4634
}

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

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,62 +23,55 @@
2323
import com.google.firebase.perf.util.Clock;
2424
import com.google.firebase.perf.util.Timer;
2525
import com.google.firebase.perf.v1.SessionVerbosity;
26-
import com.google.firebase.sessions.api.SessionSubscriber;
2726
import java.util.List;
27+
import java.util.UUID;
2828
import java.util.concurrent.TimeUnit;
2929

3030
/** Details of a session including a unique Id and related information. */
3131
public class PerfSession implements Parcelable {
32-
33-
private final String sessionId;
3432
private final Timer creationTime;
35-
@Nullable private String aqsSessionId;
33+
private final String sessionId;
34+
35+
public final boolean isAqsReady;
3636

3737
private boolean isGaugeAndEventCollectionEnabled = false;
3838

3939
/*
4040
* Creates a PerfSession object and decides what metrics to collect.
4141
*/
42-
public static PerfSession createWithId(@NonNull String sessionId) {
43-
String prunedSessionId = sessionId.replace("-", "");
44-
PerfSession session = new PerfSession(prunedSessionId, new Clock());
45-
session.setGaugeAndEventCollectionEnabled(shouldCollectGaugesAndEvents());
46-
42+
public static PerfSession createWithId(@Nullable String aqsSessionId) {
43+
String sessionId = UUID.randomUUID().toString().replace("-", "");
44+
Boolean isAqsReady = false;
45+
if (aqsSessionId != null) {
46+
sessionId = aqsSessionId;
47+
isAqsReady = true;
48+
}
49+
PerfSession session = new PerfSession(sessionId, new Clock(), isAqsReady);
50+
session.setGaugeAndEventCollectionEnabled(shouldCollectGaugesAndEvents(sessionId));
4751
return session;
4852
}
4953

5054
/** Creates a PerfSession with the provided {@code sessionId} and {@code clock}. */
5155
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
52-
public PerfSession(String sessionId, Clock clock) {
56+
public PerfSession(String sessionId, Clock clock, boolean isAqsReady) {
5357
this.sessionId = sessionId;
58+
this.isAqsReady = isAqsReady;
5459
creationTime = clock.getTime();
5560
}
5661

5762
private PerfSession(@NonNull Parcel in) {
5863
super();
5964
sessionId = in.readString();
6065
isGaugeAndEventCollectionEnabled = in.readByte() != 0;
66+
isAqsReady = in.readByte() != 0;
6167
creationTime = in.readParcelable(Timer.class.getClassLoader());
6268
}
6369

64-
/** Returns the sessionId of the session. */
70+
/** Returns the sessionId for the given session. */
6571
public String sessionId() {
6672
return sessionId;
6773
}
6874

69-
/** Returns the AQS sessionId for the given session. */
70-
@Nullable
71-
public String aqsSessionId() {
72-
return aqsSessionId;
73-
}
74-
75-
/** Sets the AQS sessionId for the given session. */
76-
public void setAQSId(SessionSubscriber.SessionDetails aqs) {
77-
if (aqsSessionId == null) {
78-
aqsSessionId = aqs.getSessionId();
79-
}
80-
}
81-
8275
/**
8376
* Returns a timer object that has been seeded with the system time at which the session began.
8477
*/
@@ -105,18 +98,6 @@ public boolean isVerbose() {
10598
return isGaugeAndEventCollectionEnabled;
10699
}
107100

108-
/** Checks if the current {@link com.google.firebase.perf.v1.PerfSession} is verbose or not. */
109-
@VisibleForTesting
110-
static boolean isVerbose(@NonNull com.google.firebase.perf.v1.PerfSession perfSession) {
111-
for (SessionVerbosity sessionVerbosity : perfSession.getSessionVerbosityList()) {
112-
if (sessionVerbosity == SessionVerbosity.GAUGES_AND_SYSTEM_EVENTS) {
113-
return true;
114-
}
115-
}
116-
117-
return false;
118-
}
119-
120101
/**
121102
* Checks if it has been more than {@link ConfigResolver#getSessionsMaxDurationMinutes()} time
122103
* since the creation time of the current session.
@@ -128,7 +109,6 @@ public boolean isSessionRunningTooLong() {
128109

129110
/** Creates and returns the proto object for PerfSession object. */
130111
public com.google.firebase.perf.v1.PerfSession build() {
131-
// TODO(b/394127311): Switch to using AQS.
132112
com.google.firebase.perf.v1.PerfSession.Builder sessionMetric =
133113
com.google.firebase.perf.v1.PerfSession.newBuilder().setSessionId(sessionId);
134114

@@ -179,11 +159,10 @@ public static com.google.firebase.perf.v1.PerfSession[] buildAndSort(
179159
}
180160

181161
/** If true, Session Gauge collection is enabled. */
182-
public static boolean shouldCollectGaugesAndEvents() {
162+
public static boolean shouldCollectGaugesAndEvents(String sessionId) {
183163
ConfigResolver configResolver = ConfigResolver.getInstance();
184-
185164
return configResolver.isPerformanceMonitoringEnabled()
186-
&& Math.random() < configResolver.getSessionsSamplingRate();
165+
&& (sessionId.hashCode() % 100 < configResolver.getSessionsSamplingRate() * 100);
187166
}
188167

189168
/**
@@ -207,6 +186,7 @@ public int describeContents() {
207186
public void writeToParcel(@NonNull Parcel out, int flags) {
208187
out.writeString(sessionId);
209188
out.writeByte((byte) (isGaugeAndEventCollectionEnabled ? 1 : 0));
189+
out.writeByte((byte) (isAqsReady ? 1 : 0));
210190
out.writeParcelable(creationTime, 0);
211191
}
212192

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

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import androidx.annotation.Keep;
2020
import androidx.annotation.VisibleForTesting;
2121
import com.google.firebase.perf.application.AppStateMonitor;
22+
import com.google.firebase.perf.logging.AndroidLogger;
2223
import com.google.firebase.perf.session.gauges.GaugeManager;
2324
import com.google.firebase.perf.v1.ApplicationProcessState;
2425
import com.google.firebase.perf.v1.GaugeMetadata;
@@ -28,11 +29,11 @@
2829
import java.util.Iterator;
2930
import java.util.Objects;
3031
import java.util.Set;
31-
import java.util.UUID;
3232

3333
/** Session manager to generate sessionIDs and broadcast to the application. */
3434
@Keep // Needed because of b/117526359.
3535
public class SessionManager {
36+
private final AndroidLogger logger = AndroidLogger.getInstance();
3637

3738
@SuppressLint("StaticFieldLeak")
3839
private static final SessionManager instance = new SessionManager();
@@ -50,15 +51,15 @@ public static SessionManager getInstance() {
5051

5152
/** Returns the currently active PerfSession. */
5253
public final PerfSession perfSession() {
54+
if (!perfSession.isAqsReady) {
55+
logger.warn("Access perf session from manger without aqs ready");
56+
}
5357
return perfSession;
5458
}
5559

5660
private SessionManager() {
57-
// Generate a new sessionID for every cold start.
58-
this(
59-
GaugeManager.getInstance(),
60-
PerfSession.createWithId(UUID.randomUUID().toString()),
61-
AppStateMonitor.getInstance());
61+
// session should quickly updated by session subscriber.
62+
this(GaugeManager.getInstance(), PerfSession.createWithId(null), AppStateMonitor.getInstance());
6263
}
6364

6465
@VisibleForTesting
@@ -83,6 +84,10 @@ public void setApplicationContext(final Context appContext) {
8384
* @see PerfSession#isSessionRunningTooLong()
8485
*/
8586
public void stopGaugeCollectionIfSessionRunningTooLong() {
87+
if (!perfSession.isAqsReady) {
88+
logger.warn(
89+
"Session is not ready while trying to stopGaugeCollectionIfSessionRunningTooLong");
90+
}
8691
if (perfSession.isSessionRunningTooLong()) {
8792
gaugeManager.stopCollectingGauges();
8893
}
@@ -156,6 +161,9 @@ public void unregisterForSessionUpdates(WeakReference<SessionAwareObject> client
156161
}
157162

158163
private void startOrStopCollectingGauges(ApplicationProcessState appState) {
164+
if (!perfSession.isAqsReady) {
165+
logger.warn("Session is not ready while trying to startOrStopCollectingGauges");
166+
}
159167
if (perfSession.isGaugeAndEventCollectionEnabled()) {
160168
gaugeManager.startCollectingGauges(perfSession, appState);
161169
} else {

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/PerfSessionTest.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public void setUp() {
6262

6363
@Test
6464
public void instanceCreation() {
65-
PerfSession session = new PerfSession("sessionId", mockClock);
65+
PerfSession session = new PerfSession("sessionId", mockClock, true);
6666
assertThat(session).isNotNull();
6767
session.setGaugeAndEventCollectionEnabled(true);
6868
Assert.assertTrue(session.isGaugeAndEventCollectionEnabled());
@@ -78,17 +78,17 @@ public void shouldCollectGaugesAndEvents_perfMonDisabledAtRuntime_sessionNotVerb
7878
configResolver.setMetadataBundle(new ImmutableBundle(bundle));
7979

8080
// By default, session is verbose if developer has set 100% of session verbosity.
81-
assertThat(PerfSession.shouldCollectGaugesAndEvents()).isTrue();
81+
assertThat(PerfSession.shouldCollectGaugesAndEvents("sessionId")).isTrue();
8282

8383
// Case #1: developer has disabled Performance Monitoring during runtime.
8484
configResolver.setIsPerformanceCollectionEnabled(false);
8585

86-
assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse();
86+
assertThat(PerfSession.shouldCollectGaugesAndEvents("sessionId")).isFalse();
8787

8888
// Case #2: developer has enabled Performance Monitoring during runtime.
8989
configResolver.setIsPerformanceCollectionEnabled(true);
9090

91-
assertThat(PerfSession.shouldCollectGaugesAndEvents()).isTrue();
91+
assertThat(PerfSession.shouldCollectGaugesAndEvents("sessionId")).isTrue();
9292
}
9393

9494
@Test
@@ -102,17 +102,17 @@ public void shouldCollectGaugesAndEvents_perfMonDisabledAtBuildtime_verbosityDep
102102

103103
// By default, session is not verbose if developer disabled performance monitoring at build
104104
// time.
105-
assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse();
105+
assertThat(PerfSession.shouldCollectGaugesAndEvents("sessionId")).isFalse();
106106

107107
// Case #1: developer has enabled Performance Monitoring during runtime.
108108
configResolver.setIsPerformanceCollectionEnabled(true);
109109

110-
assertThat(PerfSession.shouldCollectGaugesAndEvents()).isTrue();
110+
assertThat(PerfSession.shouldCollectGaugesAndEvents("sessionId")).isTrue();
111111

112112
// Case #2: developer has disabled Performance Monitoring during runtime.
113113
configResolver.setIsPerformanceCollectionEnabled(false);
114114

115-
assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse();
115+
assertThat(PerfSession.shouldCollectGaugesAndEvents("sessionId")).isFalse();
116116
}
117117

118118
@Test
@@ -124,22 +124,22 @@ public void shouldCollectGaugesAndEvents_perfMonDeactivated_sessionNotVerbose()
124124
configResolver.setMetadataBundle(new ImmutableBundle(bundle));
125125

126126
// Session will never be verbose if developer deactivated performance monitoring at build time.
127-
assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse();
127+
assertThat(PerfSession.shouldCollectGaugesAndEvents("sessionId")).isFalse();
128128

129129
// Case #1: developer has enabled Performance Monitoring during runtime.
130130
configResolver.setIsPerformanceCollectionEnabled(true);
131131

132-
assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse();
132+
assertThat(PerfSession.shouldCollectGaugesAndEvents("sessionId")).isFalse();
133133

134134
// Case #2: developer has disabled Performance Monitoring during runtime.
135135
configResolver.setIsPerformanceCollectionEnabled(false);
136136

137-
assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse();
137+
assertThat(PerfSession.shouldCollectGaugesAndEvents("sessionId")).isFalse();
138138
}
139139

140140
@Test
141141
public void testPerfSessionConversion() {
142-
PerfSession session1 = new PerfSession("sessionId", mockClock);
142+
PerfSession session1 = new PerfSession("sessionId", mockClock, true);
143143
session1.setGaugeAndEventCollectionEnabled(true);
144144

145145
com.google.firebase.perf.v1.PerfSession perfSession = session1.build();
@@ -150,7 +150,7 @@ public void testPerfSessionConversion() {
150150

151151
@Test
152152
public void testPerfSessionConversionWithoutVerbosity() {
153-
PerfSession session1 = new PerfSession("sessionId", mockClock);
153+
PerfSession session1 = new PerfSession("sessionId", mockClock, true);
154154

155155
com.google.firebase.perf.v1.PerfSession perfSession = session1.build();
156156
Assert.assertEquals(session1.sessionId(), perfSession.getSessionId());
@@ -216,7 +216,7 @@ public void testIsExpiredReturnsFalseWhenCurrentSessionLengthIsLessThanMaxSessio
216216
- TimeUnit.MINUTES.toMicros(1)); // Default Max Session Length is 4 hours
217217
when(mockClock.getTime()).thenReturn(mockTimer);
218218

219-
PerfSession session = new PerfSession("sessionId", mockClock);
219+
PerfSession session = new PerfSession("sessionId", mockClock, true);
220220
assertThat(session.isSessionRunningTooLong()).isFalse();
221221
}
222222

@@ -227,7 +227,7 @@ public void testIsExpiredReturnsFalseWhenCurrentSessionLengthIsEqualToMaxSession
227227
.thenReturn(TimeUnit.HOURS.toMicros(4)); // Default Max Session Length is 4 hours
228228
when(mockClock.getTime()).thenReturn(mockTimer);
229229

230-
PerfSession session = new PerfSession("sessionId", mockClock);
230+
PerfSession session = new PerfSession("sessionId", mockClock, true);
231231
assertThat(session.isSessionRunningTooLong()).isFalse();
232232
}
233233

@@ -238,7 +238,7 @@ public void testIsExpiredReturnsTrueWhenCurrentSessionLengthIsGreaterThanMaxSess
238238
.thenReturn(TimeUnit.HOURS.toMicros(5)); // Default Max Session Length is 4 hours
239239
when(mockClock.getTime()).thenReturn(mockTimer);
240240

241-
PerfSession session = new PerfSession("sessionId", mockClock);
241+
PerfSession session = new PerfSession("sessionId", mockClock, true);
242242
assertThat(session.isSessionRunningTooLong()).isTrue();
243243
}
244244
}

0 commit comments

Comments
 (0)