diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfEarly.java b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfEarly.java index 01a081ca9b7..14f27aa0233 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfEarly.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfEarly.java @@ -22,6 +22,7 @@ import com.google.firebase.perf.config.ConfigResolver; import com.google.firebase.perf.metrics.AppStartTrace; import com.google.firebase.perf.session.FirebasePerformanceSessionSubscriber; +import com.google.firebase.perf.session.SessionManager; import com.google.firebase.sessions.api.FirebaseSessionsDependencies; import java.util.concurrent.Executor; @@ -35,7 +36,7 @@ public class FirebasePerfEarly { public FirebasePerfEarly( - FirebaseApp app, @Nullable StartupTime startupTime, Executor uiExecutor) { + FirebaseApp app, @Nullable StartupTime startupTime, Executor uiExecutor, SessionManager sessionManager) { Context context = app.getApplicationContext(); // Initialize ConfigResolver early for accessing device caching layer. @@ -44,14 +45,14 @@ public FirebasePerfEarly( // Register FirebasePerformance as a subscriber ASAP - which will start collecting gauges if the // FirebaseSession is verbose. - FirebaseSessionsDependencies.register(new FirebasePerformanceSessionSubscriber(configResolver)); + FirebaseSessionsDependencies.register(new FirebasePerformanceSessionSubscriber(configResolver, sessionManager)); AppStateMonitor appStateMonitor = AppStateMonitor.getInstance(); appStateMonitor.registerActivityLifecycleCallbacks(context); appStateMonitor.registerForAppColdStart(new FirebasePerformanceInitializer()); if (startupTime != null) { - AppStartTrace appStartTrace = AppStartTrace.getInstance(); + AppStartTrace appStartTrace = AppStartTrace.getInstance(sessionManager); appStartTrace.registerActivityLifecycleCallbacks(context); uiExecutor.execute(new AppStartTrace.StartFromBackgroundRunnable(appStartTrace)); } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfRegistrar.java b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfRegistrar.java index daffc2de81a..7473f9e03de 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfRegistrar.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfRegistrar.java @@ -28,6 +28,9 @@ import com.google.firebase.perf.injection.components.DaggerFirebasePerformanceComponent; import com.google.firebase.perf.injection.components.FirebasePerformanceComponent; import com.google.firebase.perf.injection.modules.FirebasePerformanceModule; +import com.google.firebase.perf.session.PerfSession; +import com.google.firebase.perf.session.SessionManager; +import com.google.firebase.perf.session.gauges.GaugeManager; import com.google.firebase.platforminfo.LibraryVersionComponent; import com.google.firebase.remoteconfig.RemoteConfigComponent; import com.google.firebase.sessions.api.FirebaseSessionsDependencies; @@ -66,6 +69,7 @@ public List> getComponents() { .add(Dependency.required(FirebaseInstallationsApi.class)) .add(Dependency.requiredProvider(TransportFactory.class)) .add(Dependency.required(FirebasePerfEarly.class)) + .add(Dependency.required(SessionManager.class)) .factory(FirebasePerfRegistrar::providesFirebasePerformance) .build(), Component.builder(FirebasePerfEarly.class) @@ -73,13 +77,18 @@ public List> getComponents() { .add(Dependency.required(FirebaseApp.class)) .add(Dependency.optionalProvider(StartupTime.class)) .add(Dependency.required(uiExecutor)) + .add(Dependency.required(SessionManager.class)) .eagerInDefaultApp() .factory( container -> new FirebasePerfEarly( container.get(FirebaseApp.class), container.getProvider(StartupTime.class).get(), - container.get(uiExecutor))) + container.get(uiExecutor), + container.get(SessionManager.class))) + .build(), + Component.builder(SessionManager.class) + .factory(container -> SessionManager.getInstance()) .build(), /** * Fireperf SDK is lazily by {@link FirebasePerformanceInitializer} during {@link @@ -101,7 +110,8 @@ private static FirebasePerformance providesFirebasePerformance(ComponentContaine container.get(FirebaseApp.class), container.get(FirebaseInstallationsApi.class), container.getProvider(RemoteConfigComponent.class), - container.getProvider(TransportFactory.class))) + container.getProvider(TransportFactory.class), + container.get(SessionManager.class))) .build(); return component.getFirebasePerformance(); diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerformance.java b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerformance.java index da2ed21d947..2a9eb992ecb 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerformance.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerformance.java @@ -171,7 +171,7 @@ public static FirebasePerformance getInstance() { FirebaseSessionsEnforcementCheck.setEnforcement(BuildConfig.ENFORCE_LEGACY_SESSIONS); TransportManager.getInstance() - .initialize(firebaseApp, firebaseInstallationsApi, transportFactoryProvider); + .initialize(firebaseApp, firebaseInstallationsApi, transportFactoryProvider, sessionManager); Context appContext = firebaseApp.getApplicationContext(); mMetadataBundle = extractMetadata(appContext); diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/application/AppStateMonitor.java b/firebase-perf/src/main/java/com/google/firebase/perf/application/AppStateMonitor.java index b014d82bb83..d44db9d83a7 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/application/AppStateMonitor.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/application/AppStateMonitor.java @@ -70,6 +70,7 @@ public class AppStateMonitor implements ActivityLifecycleCallbacks { private final TransportManager transportManager; private final ConfigResolver configResolver; private final Clock clock; + private final SessionManager sessionManager; private final boolean screenPerformanceRecordingSupported; private Timer resumeTime; // The time app comes to foreground @@ -84,18 +85,19 @@ public static AppStateMonitor getInstance() { if (instance == null) { synchronized (AppStateMonitor.class) { if (instance == null) { - instance = new AppStateMonitor(TransportManager.getInstance(), new Clock()); + instance = new AppStateMonitor(TransportManager.getInstance(), new Clock(), SessionManager.getInstance()); } } } return instance; } - AppStateMonitor(TransportManager transportManager, Clock clock) { + AppStateMonitor(TransportManager transportManager, Clock clock, SessionManager sessionManager) { this( transportManager, clock, ConfigResolver.getInstance(), + sessionManager, isScreenPerformanceRecordingSupported()); } @@ -104,10 +106,12 @@ public static AppStateMonitor getInstance() { TransportManager transportManager, Clock clock, ConfigResolver configResolver, + SessionManager sessionManager, boolean screenPerformanceRecordingSupported) { this.transportManager = transportManager; this.clock = clock; this.configResolver = configResolver; + this.sessionManager = sessionManager; this.screenPerformanceRecordingSupported = screenPerformanceRecordingSupported; } @@ -379,7 +383,7 @@ private void sendSessionLog(String name, Timer startTime, Timer endTime) { .setName(name) .setClientStartTimeUs(startTime.getMicros()) .setDurationUs(startTime.getDurationMicros(endTime)) - .addPerfSessions(SessionManager.getInstance().perfSession().build()); + .addPerfSessions(sessionManager.perfSession().build()); // Atomically get mTsnsCount and set it to zero. int tsnsCount = this.tsnsCount.getAndSet(0); synchronized (metricToCountMap) { diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/injection/modules/FirebasePerformanceModule.java b/firebase-perf/src/main/java/com/google/firebase/perf/injection/modules/FirebasePerformanceModule.java index 799a6cdccd9..0bcda21c26c 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/injection/modules/FirebasePerformanceModule.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/injection/modules/FirebasePerformanceModule.java @@ -34,16 +34,19 @@ public class FirebasePerformanceModule { private final FirebaseInstallationsApi firebaseInstallations; private final Provider remoteConfigComponentProvider; private final Provider transportFactoryProvider; + private final SessionManager sessionManager; public FirebasePerformanceModule( @NonNull FirebaseApp firebaseApp, @NonNull FirebaseInstallationsApi firebaseInstallations, @NonNull Provider remoteConfigComponentProvider, - @NonNull Provider transportFactoryProvider) { + @NonNull Provider transportFactoryProvider, + @NonNull SessionManager sessionManager) { this.firebaseApp = firebaseApp; this.firebaseInstallations = firebaseInstallations; this.remoteConfigComponentProvider = remoteConfigComponentProvider; this.transportFactoryProvider = transportFactoryProvider; + this.sessionManager = sessionManager; } @Provides @@ -78,6 +81,6 @@ ConfigResolver providesConfigResolver() { @Provides SessionManager providesSessionManager() { - return SessionManager.getInstance(); + return sessionManager; } } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/metrics/AppStartTrace.java b/firebase-perf/src/main/java/com/google/firebase/perf/metrics/AppStartTrace.java index 2d4588c2d2d..e38944ed0d2 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/metrics/AppStartTrace.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/metrics/AppStartTrace.java @@ -92,6 +92,7 @@ public class AppStartTrace implements ActivityLifecycleCallbacks, LifecycleObser private final TransportManager transportManager; private final Clock clock; private final ConfigResolver configResolver; + private final SessionManager sessionManager; private final TraceMetric.Builder experimentTtid; private Context appContext; @@ -166,13 +167,13 @@ public static void setLauncherActivityOnResumeTime(String activity) { // no-op, for backward compatibility with old version plugin. } - public static AppStartTrace getInstance() { - return instance != null ? instance : getInstance(TransportManager.getInstance(), new Clock()); + public static AppStartTrace getInstance(SessionManager sessionManager) { + return instance != null ? instance : getInstance(TransportManager.getInstance(), new Clock(), sessionManager); } // TODO(b/258263016): Migrate to go/firebase-android-executors @SuppressLint("ThreadPoolCreation") - static AppStartTrace getInstance(TransportManager transportManager, Clock clock) { + static AppStartTrace getInstance(TransportManager transportManager, Clock clock, SessionManager sessionManager) { if (instance == null) { synchronized (AppStartTrace.class) { if (instance == null) { @@ -181,6 +182,7 @@ static AppStartTrace getInstance(TransportManager transportManager, Clock clock) transportManager, clock, ConfigResolver.getInstance(), + sessionManager, new ThreadPoolExecutor( CORE_POOL_SIZE, MAX_POOL_SIZE, @@ -198,10 +200,12 @@ static AppStartTrace getInstance(TransportManager transportManager, Clock clock) @NonNull TransportManager transportManager, @NonNull Clock clock, @NonNull ConfigResolver configResolver, + @NonNull SessionManager sessionManager, @NonNull ExecutorService executorService) { this.transportManager = transportManager; this.clock = clock; this.configResolver = configResolver; + this.sessionManager = sessionManager; this.executorService = executorService; this.experimentTtid = TraceMetric.newBuilder().setName("_experiment_app_start_ttid"); // Set the timestamp for process-start (beginning of BIND_APPLICATION), if available @@ -415,7 +419,7 @@ public synchronized void onActivityResumed(Activity activity) { appStartActivity = new WeakReference(activity); onResumeTime = clock.getTime(); - this.startSession = SessionManager.getInstance().perfSession(); + this.startSession = sessionManager.perfSession(); AndroidLogger.getInstance() .debug( "onResume(): " @@ -560,11 +564,11 @@ public static boolean isAnyAppProcessInForeground(Context appContext) { if (appProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { continue; } - if (appProcess.processName.equals(appProcessName) - || appProcess.processName.startsWith(allowedAppProcessNamePrefix)) { - // Returns true if the process with `IMPORTANCE_FOREGROUND` matches current process. - return true; - } +// if (appProcess.processName.equals(appProcessName) +// || appProcess.processName.startsWith(allowedAppProcessNamePrefix)) { +// // Returns true if the process with `IMPORTANCE_FOREGROUND` matches current process. +// return true; +// } } } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/metrics/NetworkRequestMetricBuilder.java b/firebase-perf/src/main/java/com/google/firebase/perf/metrics/NetworkRequestMetricBuilder.java index 6afbb2a4de9..db78d61ff9c 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/metrics/NetworkRequestMetricBuilder.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/metrics/NetworkRequestMetricBuilder.java @@ -57,6 +57,7 @@ public final class NetworkRequestMetricBuilder extends AppStateUpdateHandler private final List sessions; private final GaugeManager gaugeManager; private final TransportManager transportManager; + private final SessionManager sessionManager; private final NetworkRequestMetric.Builder builder = NetworkRequestMetric.newBuilder(); private final WeakReference weakReference = new WeakReference<>(this); @@ -89,7 +90,7 @@ public static NetworkRequestMetricBuilder builder(TransportManager transportMana * initialize them. */ private NetworkRequestMetricBuilder(TransportManager transportManager) { - this(transportManager, AppStateMonitor.getInstance(), GaugeManager.getInstance()); + this(transportManager, AppStateMonitor.getInstance(), GaugeManager.getInstance(), SessionManager.getInstance()); } /** @@ -99,11 +100,13 @@ private NetworkRequestMetricBuilder(TransportManager transportManager) { public NetworkRequestMetricBuilder( TransportManager transportManager, AppStateMonitor appStateMonitor, - GaugeManager gaugeManager) { + GaugeManager gaugeManager, + SessionManager sessionManager) { super(appStateMonitor); this.transportManager = transportManager; this.gaugeManager = gaugeManager; + this.sessionManager = sessionManager; sessions = Collections.synchronizedList(new ArrayList<>()); registerForAppState(); @@ -227,9 +230,8 @@ public NetworkRequestMetricBuilder setCustomAttributes(Map attri * @see PerfSession#isVerbose() */ public NetworkRequestMetricBuilder setRequestStartTimeMicros(long time) { - SessionManager sessionManager = SessionManager.getInstance(); PerfSession perfSession = sessionManager.perfSession(); - SessionManager.getInstance().registerForSessionUpdates(weakReference); + sessionManager.registerForSessionUpdates(weakReference); builder.setClientStartTimeUs(time); updateSession(perfSession); @@ -270,8 +272,8 @@ public long getTimeToResponseInitiatedMicros() { public NetworkRequestMetricBuilder setTimeToResponseCompletedMicros(long time) { builder.setTimeToResponseCompletedUs(time); - if (SessionManager.getInstance().perfSession().isVerbose()) { - gaugeManager.collectGaugeMetricOnce(SessionManager.getInstance().perfSession().getTimer()); + if (sessionManager.perfSession().isVerbose()) { + gaugeManager.collectGaugeMetricOnce(sessionManager.perfSession().getTimer()); } return this; @@ -309,7 +311,7 @@ public NetworkRequestMetricBuilder setNetworkClientErrorReason() { /** Builds the current {@link NetworkRequestMetric}. */ public NetworkRequestMetric build() { - SessionManager.getInstance().unregisterForSessionUpdates(weakReference); + sessionManager.unregisterForSessionUpdates(weakReference); unregisterForAppState(); com.google.firebase.perf.v1.PerfSession[] perfSessions = diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/metrics/Trace.java b/firebase-perf/src/main/java/com/google/firebase/perf/metrics/Trace.java index 6e9cc6fa47a..0f5651da156 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/metrics/Trace.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/metrics/Trace.java @@ -57,6 +57,7 @@ public class Trace extends AppStateUpdateHandler private final Trace parent; private final GaugeManager gaugeManager; + private final SessionManager sessionManager; private final String name; private final Map counterNameToCounterMap; @@ -138,6 +139,7 @@ private Trace( transportManager = parent.transportManager; sessions = Collections.synchronizedList(new ArrayList<>()); gaugeManager = this.parent.gaugeManager; + sessionManager = this.parent.sessionManager; } /** @@ -154,6 +156,14 @@ public Trace( this(name, transportManager, clock, appStateMonitor, GaugeManager.getInstance()); } + public Trace( + @NonNull String name, + @NonNull TransportManager transportManager, + @NonNull Clock clock, + @NonNull AppStateMonitor appStateMonitor, + @NonNull GaugeManager gaugeManager) { + this(name, transportManager, clock, appStateMonitor, gaugeManager, SessionManager.getInstance()); + } /** * Creates a Trace object with the given name. TransportManager, Clock and GaugeManager instances * are for testing. @@ -165,7 +175,8 @@ public Trace( @NonNull TransportManager transportManager, @NonNull Clock clock, @NonNull AppStateMonitor appStateMonitor, - @NonNull GaugeManager gaugeManager) { + @NonNull GaugeManager gaugeManager, + @NonNull SessionManager sessionManager) { super(appStateMonitor); parent = null; this.name = name.trim(); @@ -176,6 +187,7 @@ public Trace( this.transportManager = transportManager; sessions = Collections.synchronizedList(new ArrayList<>()); this.gaugeManager = gaugeManager; + this.sessionManager = sessionManager; } private Trace(@NonNull Parcel in, boolean isDataOnly) { @@ -201,6 +213,7 @@ private Trace(@NonNull Parcel in, boolean isDataOnly) { clock = new Clock(); gaugeManager = GaugeManager.getInstance(); } + sessionManager = SessionManager.getInstance(); } /** Starts this trace. */ @@ -227,9 +240,8 @@ public void start() { registerForAppState(); - SessionManager sessionManager = SessionManager.getInstance(); PerfSession perfSession = sessionManager.perfSession(); - SessionManager.getInstance().registerForSessionUpdates(sessionAwareObject); + sessionManager.registerForSessionUpdates(sessionAwareObject); updateSession(perfSession); @@ -250,7 +262,7 @@ public void stop() { return; } - SessionManager.getInstance().unregisterForSessionUpdates(sessionAwareObject); + sessionManager.unregisterForSessionUpdates(sessionAwareObject); unregisterForAppState(); endTime = clock.getTime(); @@ -259,9 +271,9 @@ public void stop() { if (!name.isEmpty()) { transportManager.log(new TraceMetricBuilder(this).build(), getAppState()); - if (SessionManager.getInstance().perfSession().isVerbose()) { + if (sessionManager.perfSession().isVerbose()) { gaugeManager.collectGaugeMetricOnce( - SessionManager.getInstance().perfSession().getTimer()); + sessionManager.perfSession().getTimer()); } } else { logger.error("Trace name is empty, no log is sent to server"); diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/session/FirebasePerformanceSessionSubscriber.kt b/firebase-perf/src/main/java/com/google/firebase/perf/session/FirebasePerformanceSessionSubscriber.kt index f524e52ed34..2e51a1498d1 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/session/FirebasePerformanceSessionSubscriber.kt +++ b/firebase-perf/src/main/java/com/google/firebase/perf/session/FirebasePerformanceSessionSubscriber.kt @@ -20,7 +20,7 @@ import com.google.firebase.perf.config.ConfigResolver import com.google.firebase.perf.logging.FirebaseSessionsEnforcementCheck.Companion.checkSession import com.google.firebase.sessions.api.SessionSubscriber -class FirebasePerformanceSessionSubscriber(val configResolver: ConfigResolver) : SessionSubscriber { +class FirebasePerformanceSessionSubscriber(val configResolver: ConfigResolver, private val sessionManager: SessionManager) : SessionSubscriber { override val sessionSubscriberName: SessionSubscriber.Name = SessionSubscriber.Name.PERFORMANCE @@ -28,11 +28,11 @@ class FirebasePerformanceSessionSubscriber(val configResolver: ConfigResolver) : get() = configResolver.isPerformanceCollectionEnabled ?: false override fun onSessionChanged(sessionDetails: SessionSubscriber.SessionDetails) { - val currentPerfSession = SessionManager.getInstance().perfSession() + val currentPerfSession = sessionManager.perfSession() // TODO(b/394127311): Add logic to deal with app start gauges if necessary. checkSession(currentPerfSession.sessionId(), "Existing session in onSessionChanged().") val updatedSession = PerfSession.createWithId(sessionDetails.sessionId) - SessionManager.getInstance().updatePerfSession(updatedSession) + sessionManager.updatePerfSession(updatedSession) } } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/transport/TransportManager.java b/firebase-perf/src/main/java/com/google/firebase/perf/transport/TransportManager.java index 3478e6d96fc..f40a2eaf5ad 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/transport/TransportManager.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/transport/TransportManager.java @@ -126,6 +126,7 @@ public class TransportManager implements AppStateCallback { private ApplicationInfo.Builder applicationInfoBuilder; private String packageName; private String projectId; + private SessionManager sessionManager; private boolean isForegroundState = false; @@ -200,9 +201,11 @@ void initializeForTest( public void initialize( @NonNull FirebaseApp firebaseApp, @NonNull FirebaseInstallationsApi firebaseInstallationsApi, - @NonNull Provider flgTransportFactoryProvider) { + @NonNull Provider flgTransportFactoryProvider, + @NonNull SessionManager sessionManager) { this.firebaseApp = firebaseApp; + this.sessionManager = sessionManager; projectId = firebaseApp.getOptions().getProjectId(); this.firebaseInstallationsApi = firebaseInstallationsApi; this.flgTransportFactoryProvider = flgTransportFactoryProvider; @@ -389,7 +392,7 @@ private void syncLog(PerfMetric.Builder perfMetricBuilder, ApplicationProcessSta dispatchLog(perfMetric); // Check if the session is expired. If so, stop gauge collection. - SessionManager.getInstance().stopGaugeCollectionIfSessionRunningTooLong(); + sessionManager.stopGaugeCollectionIfSessionRunningTooLong(); } } diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/FirebasePerformanceTestBase.java b/firebase-perf/src/test/java/com/google/firebase/perf/FirebasePerformanceTestBase.java index f1f258e518c..8908176cdd3 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/FirebasePerformanceTestBase.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/FirebasePerformanceTestBase.java @@ -26,10 +26,12 @@ import com.google.firebase.perf.session.PerfSession; import com.google.firebase.perf.session.SessionManager; import com.google.firebase.perf.session.gauges.GaugeCounter; +import com.google.firebase.perf.session.gauges.GaugeManager; +import com.google.firebase.perf.util.Clock; import com.google.firebase.perf.util.ImmutableBundle; import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; +import org.mockito.Mock; import org.robolectric.shadows.ShadowPackageManager; public class FirebasePerformanceTestBase { @@ -53,15 +55,12 @@ public class FirebasePerformanceTestBase { protected static final String FAKE_FIREBASE_API_KEY = "AIzaSyBcE-OOIbhjyR83gm4r2MFCu4MJmprNXsw"; protected static final String FAKE_FIREBASE_DB_URL = "https://fir-perftestapp.firebaseio.com"; protected static final String FAKE_FIREBASE_PROJECT_ID = "fir-perftestapp"; + @Mock private GaugeManager mockGaugeManager; + private PerfSession session = new PerfSession("sessionId", new Clock()); + protected SessionManager sessionManager = new SessionManager(mockGaugeManager, session); protected Context appContext; - @BeforeClass - public static void setUpBeforeClass() { - // TODO(b/394127311): Explore removing this. - GaugeCounter.resetCounter(); - } - @Before public void setUpFirebaseApp() { appContext = ApplicationProvider.getApplicationContext(); @@ -85,6 +84,7 @@ public void setUpFirebaseApp() { @After public void tearDownFirebaseApp() { FirebaseApp.clearInstancesForTest(); + GaugeCounter.resetCounter(); } protected static void forceSessionsFeatureDisabled() { @@ -93,19 +93,23 @@ protected static void forceSessionsFeatureDisabled() { ConfigResolver.getInstance().setMetadataBundle(new ImmutableBundle(bundle)); } - protected static void forceVerboseSession() { + protected void forceVerboseSession() { forceVerboseSessionWithSamplingPercentage(100); } - protected static void forceNonVerboseSession() { + protected void forceNonVerboseSession() { forceVerboseSessionWithSamplingPercentage(0); } - private static void forceVerboseSessionWithSamplingPercentage(long samplingPercentage) { + private void forceVerboseSessionWithSamplingPercentage(long samplingPercentage) { Bundle bundle = new Bundle(); bundle.putFloat("sessions_sampling_percentage", samplingPercentage); ConfigResolver.getInstance().setMetadataBundle(new ImmutableBundle(bundle)); - SessionManager.getInstance().setPerfSession(PerfSession.createWithId("sessionId")); + provideSessionManager().setPerfSession(PerfSession.createWithId("sessionId")); + } + + protected SessionManager provideSessionManager() { + return sessionManager; } } diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/application/AppStateMonitorTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/application/AppStateMonitorTest.java index f30ee5d73a0..de193c2066e 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/application/AppStateMonitorTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/application/AppStateMonitorTest.java @@ -53,6 +53,7 @@ import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Map; +import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -79,10 +80,11 @@ public class AppStateMonitorTest extends FirebasePerformanceTestBase { private Activity activity1; private Activity activity2; + @Before public void setUp() { currentTime = 0; - SessionManager.getInstance().updatePerfSession(PerfSession.createWithId("sessionId")); + sessionManager.updatePerfSession(PerfSession.createWithId("sessionId")); initMocks(this); doAnswer((Answer) invocationOnMock -> new Timer(currentTime)).when(clock).getTime(); @@ -98,7 +100,7 @@ public void setUp() { @Test public void foregroundBackgroundEvent_activityStateChanges_fgBgEventsCreated() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); // activity1 comes to foreground. currentTime = 1; monitor.incrementCount("counter1", 10); @@ -158,7 +160,7 @@ public void foregroundBackgroundEvent_activityStateChanges_fgBgEventsCreated() { @Test public void testIncrementCount() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); monitor.incrementCount("counter1", 10); monitor.incrementCount("counter2", 20); @@ -178,7 +180,7 @@ public void testIncrementCount() { @Test public void testTwoActivities() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); // activity1 comes to foreground. currentTime = 1; monitor.onActivityResumed(activity1); @@ -252,7 +254,7 @@ public void testTwoActivities() { @Test public void testAppStateCallbackWithTrace() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Trace trace = new Trace("TRACE_1", transportManager, clock, monitor); // Trace is not started yet, default state is APPLICATION_PROCESS_STATE_UNKNOWN Assert.assertEquals( @@ -291,11 +293,11 @@ public void testAppStateCallbackWithTrace() { @Test public void testAppStateCallbackWithNetworkRequestMetricBuilder() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); // registerForAppState() is called by NetworkRequestMetricBuilder's constructor. NetworkRequestMetricBuilder builder = new NetworkRequestMetricBuilder( - mock(TransportManager.class), monitor, mock(GaugeManager.class)); + mock(TransportManager.class), monitor, mock(GaugeManager.class), sessionManager); Assert.assertEquals(ApplicationProcessState.BACKGROUND, builder.getAppState()); // activity1 comes to foreground. currentTime = 1; @@ -322,7 +324,7 @@ public void testAppStateCallbackWithNetworkRequestMetricBuilder() { @Test public void testRegisterActivityLifecycleCallbacks() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Context context = mock(Context.class); Application application = mock(Application.class); when(context.getApplicationContext()).thenReturn(application); @@ -336,7 +338,7 @@ public void testRegisterActivityLifecycleCallbacks() { @Test public void testUnregisterActivityLifecycleCallbacks() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Context context = mock(Context.class); Application application = mock(Application.class); when(context.getApplicationContext()).thenReturn(application); @@ -348,7 +350,7 @@ public void testUnregisterActivityLifecycleCallbacks() { @Test public void testUnregisterActivityLifecycleCallbacksBeforeItWasRegistered() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Context context = mock(Context.class); Application application = mock(Application.class); when(context.getApplicationContext()).thenReturn(application); @@ -359,7 +361,7 @@ public void testUnregisterActivityLifecycleCallbacksBeforeItWasRegistered() { @Test public void screenTrace_twoActivities_traceStartedAndStoppedWithActivityLifecycle() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Activity[] arr = {activity1, activity2}; for (int i = 0; i < arr.length; ++i) { @@ -378,7 +380,7 @@ public void screenTrace_twoActivities_traceStartedAndStoppedWithActivityLifecycl @Test public void screenTrace_noHardwareAccelerated_noExceptionThrown() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Activity activityWithNonHardwareAcceleratedView = createFakeActivity(/* isHardwareAccelerated= */ false); @@ -390,7 +392,7 @@ public void screenTrace_noHardwareAccelerated_noExceptionThrown() { @Test public void screenTrace_perfMonDisabledAtBuildTime_traceNotCreated() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Activity activityWithNonHardwareAcceleratedView = createFakeActivity(/* isHardwareAccelerated= */ true); @@ -406,7 +408,7 @@ public void screenTrace_perfMonDisabledAtBuildTime_traceNotCreated() { @Test public void screenTrace_perfMonEnabledSwitchAtRuntime_traceCreationDependsOnRuntime() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Activity activityWithNonHardwareAcceleratedView = createFakeActivity(/* isHardwareAccelerated= */ true); @@ -438,7 +440,7 @@ public void screenTrace_perfMonEnabledSwitchAtRuntime_traceCreationDependsOnRunt @Test public void screenTrace_perfMonDeactivated_traceNotCreated() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Activity activityWithNonHardwareAcceleratedView = createFakeActivity(/* isHardwareAccelerated= */ true); ConfigResolver configResolver = ConfigResolver.getInstance(); @@ -460,7 +462,7 @@ public void screenTrace_perfMonDeactivated_traceNotCreated() { @Test public void foregroundTrace_perfMonDisabledAtRuntime_traceNotCreated() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); // activity1 comes to foreground. currentTime = 1; @@ -490,7 +492,7 @@ public void foregroundTrace_perfMonDisabledAtRuntime_traceNotCreated() { @Test public void foregroundTrace_perfMonEnabledAtRuntime_traceCreated() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); // Firebase Performance is disabled at build time. Bundle bundle = new Bundle(); @@ -527,7 +529,7 @@ public void foregroundTrace_perfMonEnabledAtRuntime_traceCreated() { @Test public void foregroundTrace_perfMonDeactivated_traceCreated() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); // Firebase Performance is deactivated at build time. Bundle bundle = new Bundle(); @@ -562,7 +564,7 @@ public void foregroundTrace_perfMonDeactivated_traceCreated() { @Test public void backgroundTrace_perfMonDisabledAtRuntime_traceNotCreated() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); // activity1 comes to background. currentTime = 1; @@ -595,7 +597,7 @@ public void backgroundTrace_perfMonDisabledAtRuntime_traceNotCreated() { @Test public void backgroundTrace_perfMonEnabledAtRuntime_traceCreated() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); // Firebase Performance is disabled at build time. Bundle bundle = new Bundle(); @@ -633,7 +635,7 @@ public void backgroundTrace_perfMonEnabledAtRuntime_traceCreated() { @Test public void backgroundTrace_perfMonDeactivated_traceCreated() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); // Firebase Performance is deactivated at build time. Bundle bundle = new Bundle(); @@ -669,7 +671,7 @@ public void backgroundTrace_perfMonDeactivated_traceCreated() { @Test public void activityStateChanges_singleSubscriber_callbackIsCalled() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Map subscriberState = new HashMap<>(); // Register callbacks, but note that each callback is saved in a local variable. Otherwise @@ -689,7 +691,7 @@ public void activityStateChanges_singleSubscriber_callbackIsCalled() { @Test public void activityStateChanges_multipleSubscribers_callbackCalledOnEachSubscriber() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); Map subscriberState = new HashMap<>(); // Register callbacks, but note that each callback is saved in a local variable. Otherwise @@ -721,7 +723,7 @@ public void activityStateChanges_multipleSubscribers_callbackCalledOnEachSubscri @Test public void appColdStart_singleSubscriber_callbackIsCalled() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); FirebasePerformanceInitializer mockInitializer = mock(FirebasePerformanceInitializer.class); monitor.registerForAppColdStart(mockInitializer); @@ -732,7 +734,7 @@ public void appColdStart_singleSubscriber_callbackIsCalled() { @Test public void appHotStart_singleSubscriber_callbackIsNotCalled() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); FirebasePerformanceInitializer mockInitializer = mock(FirebasePerformanceInitializer.class); monitor.registerForAppColdStart(mockInitializer); @@ -750,7 +752,7 @@ public void appHotStart_singleSubscriber_callbackIsNotCalled() { @Test public void appColdStart_multipleSubscriber_callbackIsCalled() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); FirebasePerformanceInitializer mockInitializer1 = mock(FirebasePerformanceInitializer.class); FirebasePerformanceInitializer mockInitializer2 = mock(FirebasePerformanceInitializer.class); monitor.registerForAppColdStart(mockInitializer1); @@ -764,7 +766,7 @@ public void appColdStart_multipleSubscriber_callbackIsCalled() { @Test public void appColdStart_singleSubscriberRegistersForMultipleTimes_oneCallbackIsCalled() { - AppStateMonitor monitor = new AppStateMonitor(transportManager, clock); + AppStateMonitor monitor = new AppStateMonitor(transportManager, clock, sessionManager); FirebasePerformanceInitializer mockInitializer1 = mock(FirebasePerformanceInitializer.class); monitor.registerForAppColdStart(mockInitializer1); monitor.registerForAppColdStart(mockInitializer1); diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/application/FragmentStateMonitorTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/application/FragmentStateMonitorTest.java index fd7814f8175..f1888f4c1c3 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/application/FragmentStateMonitorTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/application/FragmentStateMonitorTest.java @@ -38,6 +38,9 @@ import com.google.firebase.perf.config.DeviceCacheManager; import com.google.firebase.perf.metrics.FrameMetricsCalculator.PerfFrameMetrics; import com.google.firebase.perf.metrics.Trace; +import com.google.firebase.perf.session.PerfSession; +import com.google.firebase.perf.session.SessionManager; +import com.google.firebase.perf.session.gauges.GaugeManager; import com.google.firebase.perf.transport.TransportManager; import com.google.firebase.perf.util.Clock; import com.google.firebase.perf.util.Constants; @@ -77,6 +80,9 @@ public class FragmentStateMonitorTest extends FirebasePerformanceTestBase { @Mock private Bundle savedInstanceState; @Mock private Fragment mockFragment1; @Mock private Fragment mockFragment2; + @Mock private GaugeManager mockGaugeManager; + private PerfSession session = new PerfSession("sessionId", new Clock()); + private SessionManager sessionManager = new SessionManager(mockGaugeManager, session); @Captor private ArgumentCaptor argTraceMetric; @@ -229,7 +235,7 @@ public void fragmentTraceCreation_whenFrameMetricsIsAbsent_dropsTrace() { @Test public void fragmentTraceCreation_dropsTrace_whenFragmentNameTooLong() { AppStateMonitor appStateMonitor = - spy(new AppStateMonitor(mockTransportManager, clock, configResolver, true)); + spy(new AppStateMonitor(mockTransportManager, clock, configResolver, sessionManager, true)); FragmentStateMonitor fragmentMonitor = spy(new FragmentStateMonitor(clock, mockTransportManager, appStateMonitor, recorder)); when(appStateMonitor.isScreenTraceSupported()).thenReturn(true); diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/metrics/AppStartTraceTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/metrics/AppStartTraceTest.java index daa80ad29a2..ba1b907c386 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/metrics/AppStartTraceTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/metrics/AppStartTraceTest.java @@ -34,9 +34,11 @@ import android.view.View; import androidx.test.core.app.ApplicationProvider; import com.google.firebase.perf.FirebasePerformanceTestBase; +import com.google.firebase.perf.application.AppStateMonitor; import com.google.firebase.perf.config.ConfigResolver; import com.google.firebase.perf.session.PerfSession; import com.google.firebase.perf.session.SessionManager; +import com.google.firebase.perf.session.gauges.GaugeManager; import com.google.firebase.perf.transport.TransportManager; import com.google.firebase.perf.util.Clock; import com.google.firebase.perf.util.Constants; @@ -105,7 +107,7 @@ public void reset() { public void testLaunchActivity() { FakeScheduledExecutorService fakeExecutorService = new FakeScheduledExecutorService(); AppStartTrace trace = - new AppStartTrace(transportManager, clock, configResolver, fakeExecutorService); + new AppStartTrace(transportManager, clock, configResolver, sessionManager, fakeExecutorService); trace.registerActivityLifecycleCallbacks(appContext); // first activity goes through onCreate()->onStart()->onResume() state change. currentTime = 1; @@ -179,7 +181,7 @@ private void verifyFinalState( public void testInterleavedActivity() { FakeScheduledExecutorService fakeExecutorService = new FakeScheduledExecutorService(); AppStartTrace trace = - new AppStartTrace(transportManager, clock, configResolver, fakeExecutorService); + new AppStartTrace(transportManager, clock, configResolver, sessionManager, fakeExecutorService); trace.registerActivityLifecycleCallbacks(appContext); // first activity onCreate() currentTime = 1; @@ -216,7 +218,7 @@ public void testInterleavedActivity() { public void testDelayedAppStart() { FakeScheduledExecutorService fakeExecutorService = new FakeScheduledExecutorService(); AppStartTrace trace = - new AppStartTrace(transportManager, clock, configResolver, fakeExecutorService); + new AppStartTrace(transportManager, clock, configResolver, sessionManager, fakeExecutorService); trace.registerActivityLifecycleCallbacks(appContext); // Delays activity creation after 1 minute from app start time. currentTime = @@ -243,7 +245,7 @@ public void testStartFromBackground_within50ms() { FakeScheduledExecutorService fakeExecutorService = new FakeScheduledExecutorService(); Timer fakeTimer = spy(new Timer(currentTime)); AppStartTrace trace = - new AppStartTrace(transportManager, clock, configResolver, fakeExecutorService); + new AppStartTrace(transportManager, clock, configResolver, sessionManager, fakeExecutorService); trace.registerActivityLifecycleCallbacks(appContext); trace.setMainThreadRunnableTime(fakeTimer); @@ -271,7 +273,7 @@ public void testStartFromBackground_moreThan50ms() { FakeScheduledExecutorService fakeExecutorService = new FakeScheduledExecutorService(); Timer fakeTimer = spy(new Timer(currentTime)); AppStartTrace trace = - new AppStartTrace(transportManager, clock, configResolver, fakeExecutorService); + new AppStartTrace(transportManager, clock, configResolver, sessionManager, fakeExecutorService); trace.registerActivityLifecycleCallbacks(appContext); trace.setMainThreadRunnableTime(fakeTimer); @@ -304,7 +306,7 @@ public void timeToInitialDisplay_isLogged() { when(configResolver.getIsExperimentTTIDEnabled()).thenReturn(true); FakeScheduledExecutorService fakeExecutorService = new FakeScheduledExecutorService(); AppStartTrace trace = - new AppStartTrace(transportManager, clock, configResolver, fakeExecutorService); + new AppStartTrace(transportManager, clock, configResolver, sessionManager, fakeExecutorService); trace.registerActivityLifecycleCallbacks(appContext); // Simulate resume and manually stepping time forward ShadowSystemClock.advanceBy(Duration.ofMillis(1000)); diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/metrics/NetworkRequestMetricBuilderTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/metrics/NetworkRequestMetricBuilderTest.java index 4a90184936c..9a0a7c46c58 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/metrics/NetworkRequestMetricBuilderTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/metrics/NetworkRequestMetricBuilderTest.java @@ -26,6 +26,7 @@ import com.google.firebase.perf.session.SessionManager; import com.google.firebase.perf.session.gauges.GaugeManager; import com.google.firebase.perf.transport.TransportManager; +import com.google.firebase.perf.util.Clock; import com.google.firebase.perf.util.Constants; import com.google.firebase.perf.util.Timer; import com.google.firebase.perf.v1.NetworkRequestMetric; @@ -37,6 +38,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentMatchers; import org.mockito.Mock; +import org.mockito.Spy; import org.robolectric.RobolectricTestRunner; /** Unit tests for {@link com.google.firebase.perf.metrics.NetworkRequestMetricBuilder}. */ @@ -44,8 +46,15 @@ public class NetworkRequestMetricBuilderTest extends FirebasePerformanceTestBase { @Mock private TransportManager mockTransportManager; - @Mock private GaugeManager mockGaugeManager; - @Mock private AppStateMonitor mockAppStateMonitor; + @Spy private GaugeManager mockGaugeManager = GaugeManager.getInstance(); + @Spy private AppStateMonitor mockAppStateMonitor = AppStateMonitor.getInstance(); + private PerfSession session = new PerfSession("sessionId", new Clock()); + private SessionManager sessionManager = new SessionManager(mockGaugeManager, session); + + @Override + protected SessionManager provideSessionManager() { + return sessionManager; + } private NetworkRequestMetricBuilder networkMetricBuilder; @@ -54,7 +63,7 @@ public void setUp() { initMocks(this); networkMetricBuilder = new NetworkRequestMetricBuilder( - mockTransportManager, mockAppStateMonitor, mockGaugeManager); + mockTransportManager, mockAppStateMonitor, mockGaugeManager, sessionManager); } @Test diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeManagerTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeManagerTest.java index c111f5fb7a2..9dd0e9e82d8 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeManagerTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeManagerTest.java @@ -47,6 +47,7 @@ import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -76,6 +77,13 @@ public final class GaugeManagerTest extends FirebasePerformanceTestBase { private CpuGaugeCollector fakeCpuGaugeCollector = null; private MemoryGaugeCollector fakeMemoryGaugeCollector = null; + @BeforeClass + public static void setUpBeforeClass() { + // TODO(b/394127311): Explore removing this. + GaugeCounter.resetCounter(); + } + + @Before public void setUp() { fakeScheduledExecutorService = new FakeScheduledExecutorService();