Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -34,29 +34,30 @@
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.
ConfigResolver configResolver = ConfigResolver.getInstance();
configResolver.setApplicationContext(context);

AppStateMonitor appStateMonitor = AppStateMonitor.getInstance();
appStateMonitor.setSessionManager(sessionManager);
appStateMonitor.registerActivityLifecycleCallbacks(context);
appStateMonitor.registerForAppColdStart(new FirebasePerformanceInitializer());

if (startupTime != null) {
AppStartTrace appStartTrace = AppStartTrace.getInstance();
appStartTrace.setSessionManager(sessionManager);
appStartTrace.registerActivityLifecycleCallbacks(context);
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.
SessionManager.getInstance().initializeGaugeCollection();
sessionManager.initializeGaugeCollection();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
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.SessionManager;
import com.google.firebase.platforminfo.LibraryVersionComponent;
import com.google.firebase.remoteconfig.RemoteConfigComponent;
import java.util.Arrays;
Expand Down Expand Up @@ -59,21 +60,27 @@ public List<Component<?>> 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)
.name(EARLY_LIBRARY_NAME)
.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() //TODO: JR: Remove getInstance in subsequent phases
).build(),
/**
* Fireperf SDK is lazily by {@link FirebasePerformanceInitializer} during {@link
* com.google.firebase.perf.application.AppStateMonitor#onActivityResumed(Activity)}. we use
Expand All @@ -94,7 +101,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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ public static FirebasePerformance getInstance() {
private final Provider<RemoteConfigComponent> firebaseRemoteConfigProvider;
private final FirebaseInstallationsApi firebaseInstallationsApi;
private final Provider<TransportFactory> transportFactoryProvider;
private final SessionManager sessionManager;

/**
* Constructs the FirebasePerformance class and allows injecting dependencies.
Expand All @@ -151,7 +152,6 @@ public static FirebasePerformance getInstance() {
* @param firebaseRemoteConfigProvider The {@link Provider} for FirebaseRemoteConfig instance.
* @param firebaseInstallationsApi The FirebaseInstallationsApi instance.
* @param transportFactoryProvider The {@link Provider} for the the {@link TransportFactory}.
* @param remoteConfigManager The RemoteConfigManager instance.
* @param configResolver The ConfigResolver instance.
* @param sessionManager The SessionManager instance.
*/
Expand All @@ -162,14 +162,14 @@ public static FirebasePerformance getInstance() {
Provider<RemoteConfigComponent> firebaseRemoteConfigProvider,
FirebaseInstallationsApi firebaseInstallationsApi,
Provider<TransportFactory> transportFactoryProvider,
RemoteConfigManager remoteConfigManager,
ConfigResolver configResolver,
SessionManager sessionManager) {

this.firebaseApp = firebaseApp;
this.firebaseRemoteConfigProvider = firebaseRemoteConfigProvider;
this.firebaseInstallationsApi = firebaseInstallationsApi;
this.transportFactoryProvider = transportFactoryProvider;
this.sessionManager = sessionManager;

if (firebaseApp == null) {
this.mPerformanceCollectionForceEnabledState = false;
Expand All @@ -179,17 +179,17 @@ public static FirebasePerformance getInstance() {
}

TransportManager.getInstance()
.initialize(firebaseApp, firebaseInstallationsApi, transportFactoryProvider);
.initialize(firebaseApp, firebaseInstallationsApi, transportFactoryProvider, sessionManager);

Context appContext = firebaseApp.getApplicationContext();
// TODO(b/110178816): Explore moving off of main thread.
mMetadataBundle = extractMetadata(appContext);

remoteConfigManager.setFirebaseRemoteConfigProvider(firebaseRemoteConfigProvider);
this.configResolver = configResolver;
this.configResolver.getRemoteConfigManager().setFirebaseRemoteConfigProvider(firebaseRemoteConfigProvider);
this.configResolver.setMetadataBundle(mMetadataBundle);
this.configResolver.setApplicationContext(appContext);
sessionManager.setApplicationContext(appContext);
this.sessionManager.setApplicationContext(appContext);

mPerformanceCollectionForceEnabledState = configResolver.getIsPerformanceCollectionEnabled();
if (logger.isLogcatEnabled() && isPerformanceCollectionEnabled()) {
Expand Down Expand Up @@ -425,7 +425,7 @@ public Trace newTrace(@NonNull String traceName) {
*/
@NonNull
public HttpMetric newHttpMetric(@NonNull String url, @NonNull @HttpMethod String httpMethod) {
return new HttpMetric(url, httpMethod, TransportManager.getInstance(), new Timer());
return new HttpMetric(url, httpMethod, TransportManager.getInstance(), new Timer(), sessionManager);
}

/**
Expand All @@ -438,7 +438,7 @@ public HttpMetric newHttpMetric(@NonNull String url, @NonNull @HttpMethod String
*/
@NonNull
public HttpMetric newHttpMetric(@NonNull URL url, @NonNull @HttpMethod String httpMethod) {
return new HttpMetric(url, httpMethod, TransportManager.getInstance(), new Timer());
return new HttpMetric(url, httpMethod, TransportManager.getInstance(), new Timer(), sessionManager);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public class AppStateMonitor implements ActivityLifecycleCallbacks {
private boolean isRegisteredForLifecycleCallbacks = false;
private boolean isColdStart = true;

private SessionManager sessionManager;

public static AppStateMonitor getInstance() {
if (instance == null) {
synchronized (AppStateMonitor.class) {
Expand Down Expand Up @@ -159,7 +161,7 @@ private void startFrameMonitoring(Activity activity) {
activityToRecorderMap.put(activity, recorder);
if (activity instanceof FragmentActivity) {
FragmentStateMonitor fragmentStateMonitor =
new FragmentStateMonitor(clock, transportManager, this, recorder);
new FragmentStateMonitor(clock, transportManager, this, recorder, sessionManager);
activityToFragmentStateMonitorMap.put(activity, fragmentStateMonitor);
FragmentActivity fragmentActivity = (FragmentActivity) activity;
fragmentActivity
Expand Down Expand Up @@ -379,7 +381,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) {
Expand Down Expand Up @@ -414,6 +416,10 @@ private static boolean isScreenPerformanceRecordingSupported() {
return FrameMetricsRecorder.isFrameMetricsRecordingSupported();
}

public SessionManager getSessionManager() {
return sessionManager;
}

/** An interface to be implemented by subscribers which needs to receive app state update. */
public static interface AppStateCallback {
public void onUpdateAppState(ApplicationProcessState newState);
Expand Down Expand Up @@ -463,4 +469,8 @@ Timer getResumeTime() {
public void setIsColdStart(boolean isColdStart) {
this.isColdStart = isColdStart;
}

public void setSessionManager(SessionManager sessionManager) {
this.sessionManager = sessionManager;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.firebase.perf.logging.AndroidLogger;
import com.google.firebase.perf.metrics.FrameMetricsCalculator.PerfFrameMetrics;
import com.google.firebase.perf.metrics.Trace;
import com.google.firebase.perf.session.SessionManager;
import com.google.firebase.perf.transport.TransportManager;
import com.google.firebase.perf.util.Clock;
import com.google.firebase.perf.util.Constants;
Expand All @@ -33,18 +34,21 @@ public class FragmentStateMonitor extends FragmentManager.FragmentLifecycleCallb
private final WeakHashMap<Fragment, Trace> fragmentToTraceMap = new WeakHashMap<>();
private final Clock clock;
private final TransportManager transportManager;
private final SessionManager sessionManager;
private final AppStateMonitor appStateMonitor;
private final FrameMetricsRecorder activityFramesRecorder;

public FragmentStateMonitor(
Clock clock,
TransportManager transportManager,
AppStateMonitor appStateMonitor,
FrameMetricsRecorder recorder) {
FrameMetricsRecorder recorder,
SessionManager sessionManager) {
this.clock = clock;
this.transportManager = transportManager;
this.appStateMonitor = appStateMonitor;
this.activityFramesRecorder = recorder;
this.sessionManager = sessionManager;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public class ConfigResolver {
private static volatile ConfigResolver instance;

// Configuration Storage objects.
private final RemoteConfigManager remoteConfigManager;
private RemoteConfigManager remoteConfigManager;
private ImmutableBundle metadataBundle;
private DeviceCacheManager deviceCacheManager;

Expand All @@ -75,7 +75,7 @@ public ConfigResolver(
@Nullable ImmutableBundle metadataBundle,
@Nullable DeviceCacheManager deviceCacheManager) {
this.remoteConfigManager =
remoteConfigManager == null ? RemoteConfigManager.getInstance() : remoteConfigManager;
remoteConfigManager != null ? remoteConfigManager : new RemoteConfigManager();
this.metadataBundle = metadataBundle == null ? new ImmutableBundle() : metadataBundle;
this.deviceCacheManager =
deviceCacheManager == null ? DeviceCacheManager.getInstance() : deviceCacheManager;
Expand All @@ -98,6 +98,11 @@ public void setDeviceCacheManager(DeviceCacheManager deviceCacheManager) {
this.deviceCacheManager = deviceCacheManager;
}

@VisibleForTesting
public void setRemoteConfigManager(RemoteConfigManager remoteConfigManager) {
this.remoteConfigManager = remoteConfigManager;
}

public void setContentProviderContext(Context context) {
setApplicationContext(context.getApplicationContext());
}
Expand Down Expand Up @@ -916,4 +921,8 @@ private boolean isGaugeCaptureFrequencyMsValid(long frequencyMilliseconds) {
private boolean isSessionsMaxDurationMinutesValid(long maxDurationMin) {
return maxDurationMin > 0;
}

public RemoteConfigManager getRemoteConfigManager() {
return remoteConfigManager;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
public class RemoteConfigManager {

private static final AndroidLogger logger = AndroidLogger.getInstance();
private static final RemoteConfigManager instance = new RemoteConfigManager();
private static final String FIREPERF_FRC_NAMESPACE_NAME = "fireperf";
private static final long TIME_AFTER_WHICH_A_FETCH_IS_CONSIDERED_STALE_MS =
TimeUnit.HOURS.toMillis(12);
Expand All @@ -67,7 +66,7 @@ public class RemoteConfigManager {

// TODO(b/258263016): Migrate to go/firebase-android-executors
@SuppressLint("ThreadPoolCreation")
private RemoteConfigManager() {
public RemoteConfigManager() {
this(
DeviceCacheManager.getInstance(),
new ThreadPoolExecutor(
Expand Down Expand Up @@ -96,11 +95,6 @@ private RemoteConfigManager() {
this.remoteConfigFetchDelayInMs = remoteConfigFetchDelayInMs;
}

/** Gets the singleton instance. */
public static RemoteConfigManager getInstance() {
return instance;
}

/**
* Sets the {@link Provider} for {@link RemoteConfigComponent} from which we can extract the
* {@link FirebaseRemoteConfig} instance whenever it gets available.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.google.firebase.perf.injection.components;

import androidx.annotation.NonNull;

import com.google.firebase.perf.injection.modules.SessionManagerModule;
import com.google.firebase.perf.session.SessionManager;

import javax.inject.Singleton;

import dagger.Component;

@Component(modules = {SessionManagerModule.class})
@Singleton
public interface SessionManagerComponent {
@NonNull
SessionManager getSessionManager();
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,19 @@ public class FirebasePerformanceModule {
private final FirebaseInstallationsApi firebaseInstallations;
private final Provider<RemoteConfigComponent> remoteConfigComponentProvider;
private final Provider<TransportFactory> transportFactoryProvider;
private final SessionManager sessionManager;

public FirebasePerformanceModule(
@NonNull FirebaseApp firebaseApp,
@NonNull FirebaseInstallationsApi firebaseInstallations,
@NonNull Provider<RemoteConfigComponent> remoteConfigComponentProvider,
@NonNull Provider<TransportFactory> transportFactoryProvider) {
@NonNull Provider<TransportFactory> transportFactoryProvider,
@NonNull SessionManager sessionManager) {
this.firebaseApp = firebaseApp;
this.firebaseInstallations = firebaseInstallations;
this.remoteConfigComponentProvider = remoteConfigComponentProvider;
this.transportFactoryProvider = transportFactoryProvider;
this.sessionManager = sessionManager;
}

@Provides
Expand All @@ -66,18 +69,13 @@ Provider<TransportFactory> providesTransportFactoryProvider() {
return transportFactoryProvider;
}

@Provides
RemoteConfigManager providesRemoteConfigManager() {
return RemoteConfigManager.getInstance();
}

@Provides
ConfigResolver providesConfigResolver() {
return ConfigResolver.getInstance();
}

@Provides
SessionManager providesSessionManager() {
return SessionManager.getInstance();
return sessionManager;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.google.firebase.perf.injection.modules;

import androidx.annotation.NonNull;

import com.google.firebase.perf.session.SessionManager;

import dagger.Module;
import dagger.Provides;

@Module
public class SessionManagerModule {
private final SessionManager sessionManager;

public SessionManagerModule(@NonNull SessionManager sessionManager) {
this.sessionManager = sessionManager;
}

@Provides
SessionManager providesSessionManager() {
return sessionManager;
}
}
Loading