From 87a393b762ee6921226fc2db8c66d8c610e4dc76 Mon Sep 17 00:00:00 2001 From: jrothfeder Date: Thu, 19 Oct 2023 14:53:11 -0400 Subject: [PATCH 1/6] Remove passthrough `register` method from `FirebaseSessions` since `FirebaseSessionsDependencies` can be accessed directly. --- .../firebase-crashlytics.gradle | 1 + .../crashlytics/CrashlyticsRegistrar.java | 2 +- .../crashlytics/FirebaseCrashlytics.java | 5 +++-- .../google/firebase/perf/FirebasePerfEarly.java | 5 ++--- .../firebase/perf/FirebasePerfRegistrar.java | 1 - .../firebase/sessions/FirebaseSessions.kt | 17 ----------------- .../api/FirebaseSessionsDependencies.kt | 3 ++- .../testing/sessions/FirebaseSessionsTest.kt | 2 +- gradle/libs.versions.toml | 1 + 9 files changed, 11 insertions(+), 26 deletions(-) diff --git a/firebase-crashlytics/firebase-crashlytics.gradle b/firebase-crashlytics/firebase-crashlytics.gradle index 532689e3a5f..1146aee4c93 100644 --- a/firebase-crashlytics/firebase-crashlytics.gradle +++ b/firebase-crashlytics/firebase-crashlytics.gradle @@ -59,6 +59,7 @@ thirdPartyLicenses { } dependencies { + implementation libs.firebase.sessions androidTestImplementation "androidx.test.ext:junit:$androidxTestJUnitVersion" androidTestImplementation "androidx.test:core:$androidxTestCoreVersion" androidTestImplementation "com.google.truth:truth:$googleTruthVersion" diff --git a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/CrashlyticsRegistrar.java b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/CrashlyticsRegistrar.java index 708beec5224..c34b87f7790 100644 --- a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/CrashlyticsRegistrar.java +++ b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/CrashlyticsRegistrar.java @@ -69,6 +69,6 @@ private FirebaseCrashlytics buildCrashlytics(ComponentContainer container) { FirebaseSessions firebaseSessions = container.get(FirebaseSessions.class); return FirebaseCrashlytics.init( - app, firebaseInstallations, firebaseSessions, nativeComponent, analyticsConnector); + app, firebaseInstallations, nativeComponent, analyticsConnector); } } diff --git a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java index 4c28ef35024..671dc50d3cf 100644 --- a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java +++ b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java @@ -42,6 +42,8 @@ import com.google.firebase.inject.Deferred; import com.google.firebase.installations.FirebaseInstallationsApi; import com.google.firebase.sessions.FirebaseSessions; +import com.google.firebase.sessions.api.FirebaseSessionsDependencies; + import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -64,7 +66,6 @@ public class FirebaseCrashlytics { static @Nullable FirebaseCrashlytics init( @NonNull FirebaseApp app, @NonNull FirebaseInstallationsApi firebaseInstallationsApi, - @NonNull FirebaseSessions firebaseSessions, @NonNull Deferred nativeComponent, @NonNull Deferred analyticsConnector) { @@ -93,7 +94,7 @@ public class FirebaseCrashlytics { CrashlyticsAppQualitySessionsSubscriber sessionsSubscriber = new CrashlyticsAppQualitySessionsSubscriber(arbiter, fileStore); - firebaseSessions.register(sessionsSubscriber); + FirebaseSessionsDependencies.register(sessionsSubscriber); final CrashlyticsCore core = new CrashlyticsCore( 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 3d3e4555061..ecc1ce637a2 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 @@ -24,7 +24,7 @@ import com.google.firebase.perf.metrics.AppStartTrace; import com.google.firebase.perf.session.PerfSession; import com.google.firebase.perf.session.SessionManager; -import com.google.firebase.sessions.FirebaseSessions; +import com.google.firebase.sessions.api.FirebaseSessionsDependencies; import com.google.firebase.sessions.api.SessionSubscriber; import java.util.concurrent.Executor; @@ -39,7 +39,6 @@ public class FirebasePerfEarly { public FirebasePerfEarly( FirebaseApp app, - FirebaseSessions firebaseSessions, @Nullable StartupTime startupTime, Executor uiExecutor) { Context context = app.getApplicationContext(); @@ -59,7 +58,7 @@ public FirebasePerfEarly( } // Register with Firebase sessions to receive updates about session changes. - firebaseSessions.register( + FirebaseSessionsDependencies.register( new SessionSubscriber() { @Override public void onSessionChanged(@NonNull SessionDetails sessionDetails) { 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 1ab9c988376..7e1500447a3 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 @@ -79,7 +79,6 @@ public List> getComponents() { container -> new FirebasePerfEarly( container.get(FirebaseApp.class), - container.get(FirebaseSessions.class), container.getProvider(StartupTime.class).get(), container.get(uiExecutor))) .build(), diff --git a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessions.kt b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessions.kt index 016db180d16..558f279a162 100644 --- a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessions.kt +++ b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessions.kt @@ -21,7 +21,6 @@ import android.util.Log import com.google.firebase.Firebase import com.google.firebase.FirebaseApp import com.google.firebase.app -import com.google.firebase.sessions.api.FirebaseSessionsDependencies import com.google.firebase.sessions.api.SessionSubscriber import com.google.firebase.sessions.settings.SessionsSettings import kotlin.coroutines.CoroutineContext @@ -63,22 +62,6 @@ internal constructor( } } - /** Register the [subscriber]. This must be called for every dependency. */ - fun register(subscriber: SessionSubscriber) { - if (!settings.sessionsEnabled) { - Log.d(TAG, "Sessions SDK disabled. Ignoring dependency registration.") - return - } - - FirebaseSessionsDependencies.register(subscriber) - - Log.d( - TAG, - "Registering Sessions SDK subscriber with name: ${subscriber.sessionSubscriberName}, " + - "data collection enabled: ${subscriber.isDataCollectionEnabled}" - ) - } - /** Calculate whether we should sample events using [sessionSettings] data. */ companion object { private const val TAG = "FirebaseSessions" diff --git a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/api/FirebaseSessionsDependencies.kt b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/api/FirebaseSessionsDependencies.kt index 13283cb6f6c..29d67b346f1 100644 --- a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/api/FirebaseSessionsDependencies.kt +++ b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/api/FirebaseSessionsDependencies.kt @@ -53,7 +53,8 @@ object FirebaseSessionsDependencies { * Register and unlock the subscriber. This must be called before [getRegisteredSubscribers] can * return. */ - internal fun register(subscriber: SessionSubscriber) { + @JvmStatic + fun register(subscriber: SessionSubscriber) { val subscriberName = subscriber.sessionSubscriberName val dependency = getDependency(subscriberName) diff --git a/firebase-sessions/test-app/src/androidTest/kotlin/com/google/firebase/testing/sessions/FirebaseSessionsTest.kt b/firebase-sessions/test-app/src/androidTest/kotlin/com/google/firebase/testing/sessions/FirebaseSessionsTest.kt index 216855bcb9e..1db255306eb 100644 --- a/firebase-sessions/test-app/src/androidTest/kotlin/com/google/firebase/testing/sessions/FirebaseSessionsTest.kt +++ b/firebase-sessions/test-app/src/androidTest/kotlin/com/google/firebase/testing/sessions/FirebaseSessionsTest.kt @@ -49,7 +49,7 @@ class FirebaseSessionsTest { // Add a fake dependency and register it, otherwise sessions will never send. val fakeSessionSubscriber = FakeSessionSubscriber() - FirebaseSessions.instance.register(fakeSessionSubscriber) + FirebaseSessionsDependencies.register(fakeSessionSubscriber) // Wait for the session start event to send. Thread.sleep(TIME_TO_LOG_SESSION) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e2c7a96d8ef..08b789013ed 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -59,6 +59,7 @@ kotest-runner = { module = "io.kotest:kotest-runner-junit4-jvm", version.ref = " kotest-assertions = { module = "io.kotest:kotest-assertions-core-jvm", version.ref = "kotest" } kotest-property = { module = "io.kotest:kotest-property-jvm", version.ref = "kotest" } quickcheck = { module = "net.java:quickcheck", version.ref = "quickcheck" } +firebase-sessions = { group = "com.google.firebase", name = "firebase-sessions", version = "1.0.2" } [bundles] kotest = ["kotest-runner", "kotest-assertions", "kotest-property"] From 9308bb6e736f34cc95e26c9c26aefc247d225d43 Mon Sep 17 00:00:00 2001 From: jrothfeder Date: Thu, 19 Oct 2023 15:12:01 -0400 Subject: [PATCH 2/6] API update --- firebase-sessions/api.txt | 40 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/firebase-sessions/api.txt b/firebase-sessions/api.txt index 3ae1e4b3fde..621450832bf 100644 --- a/firebase-sessions/api.txt +++ b/firebase-sessions/api.txt @@ -3,16 +3,50 @@ package com.google.firebase.sessions { public final class FirebaseSessions { method @NonNull public static com.google.firebase.sessions.FirebaseSessions getInstance(); - method @NonNull public static com.google.firebase.sessions.FirebaseSessions getInstance(@NonNull com.google.firebase.FirebaseApp app); - method public void register(@NonNull com.google.firebase.sessions.api.SessionSubscriber subscriber); + method @Deprecated @NonNull public static com.google.firebase.sessions.FirebaseSessions getInstance(@NonNull com.google.firebase.FirebaseApp app); property @NonNull public static final com.google.firebase.sessions.FirebaseSessions instance; field @NonNull public static final com.google.firebase.sessions.FirebaseSessions.Companion Companion; } public static final class FirebaseSessions.Companion { method @NonNull public com.google.firebase.sessions.FirebaseSessions getInstance(); - method @NonNull public com.google.firebase.sessions.FirebaseSessions getInstance(@NonNull com.google.firebase.FirebaseApp app); + method @Deprecated @NonNull public com.google.firebase.sessions.FirebaseSessions getInstance(@NonNull com.google.firebase.FirebaseApp app); property @NonNull public final com.google.firebase.sessions.FirebaseSessions instance; } } + +package com.google.firebase.sessions.api { + + public final class FirebaseSessionsDependencies { + method public void addDependency(@NonNull com.google.firebase.sessions.api.SessionSubscriber.Name subscriberName); + method public static void register(@NonNull com.google.firebase.sessions.api.SessionSubscriber subscriber); + field @NonNull public static final com.google.firebase.sessions.api.FirebaseSessionsDependencies INSTANCE; + } + + public interface SessionSubscriber { + method @NonNull public com.google.firebase.sessions.api.SessionSubscriber.Name getSessionSubscriberName(); + method public boolean isDataCollectionEnabled(); + method public void onSessionChanged(@NonNull com.google.firebase.sessions.api.SessionSubscriber.SessionDetails sessionDetails); + property public abstract boolean isDataCollectionEnabled; + property @NonNull public abstract com.google.firebase.sessions.api.SessionSubscriber.Name sessionSubscriberName; + } + + public enum SessionSubscriber.Name { + method @NonNull public static com.google.firebase.sessions.api.SessionSubscriber.Name valueOf(@NonNull String name) throws java.lang.IllegalArgumentException; + method @NonNull public static com.google.firebase.sessions.api.SessionSubscriber.Name[] values(); + enum_constant public static final com.google.firebase.sessions.api.SessionSubscriber.Name CRASHLYTICS; + enum_constant @Discouraged(message="This is for testing purposes only.") public static final com.google.firebase.sessions.api.SessionSubscriber.Name MATT_SAYS_HI; + enum_constant public static final com.google.firebase.sessions.api.SessionSubscriber.Name PERFORMANCE; + } + + public static final class SessionSubscriber.SessionDetails { + ctor public SessionSubscriber.SessionDetails(@NonNull String sessionId); + method @NonNull public String component1(); + method @NonNull public com.google.firebase.sessions.api.SessionSubscriber.SessionDetails copy(@NonNull String sessionId); + method @NonNull public String getSessionId(); + property @NonNull public final String sessionId; + } + +} + From 30d8b33462da30cefba62913601c324a54e09a4c Mon Sep 17 00:00:00 2001 From: jrothfeder Date: Thu, 19 Oct 2023 15:31:51 -0400 Subject: [PATCH 3/6] Remove unused import --- .../com/google/firebase/crashlytics/FirebaseCrashlytics.java | 1 - 1 file changed, 1 deletion(-) diff --git a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java index 671dc50d3cf..289b6a97e88 100644 --- a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java +++ b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java @@ -41,7 +41,6 @@ import com.google.firebase.crashlytics.internal.settings.SettingsController; import com.google.firebase.inject.Deferred; import com.google.firebase.installations.FirebaseInstallationsApi; -import com.google.firebase.sessions.FirebaseSessions; import com.google.firebase.sessions.api.FirebaseSessionsDependencies; import java.util.List; From c726a685d4a9b9a9cdd8a4d157b774205b5f198c Mon Sep 17 00:00:00 2001 From: jrothfeder Date: Thu, 19 Oct 2023 16:07:05 -0400 Subject: [PATCH 4/6] Reformat --- .../crashlytics/FirebaseCrashlytics.java | 862 +++++++++--------- 1 file changed, 433 insertions(+), 429 deletions(-) diff --git a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java index 289b6a97e88..2ba74ac6c9b 100644 --- a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java +++ b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java @@ -58,439 +58,443 @@ */ public class FirebaseCrashlytics { - static final String FIREBASE_CRASHLYTICS_ANALYTICS_ORIGIN = "clx"; - static final String LEGACY_CRASH_ANALYTICS_ORIGIN = "crash"; - static final int APP_EXCEPTION_CALLBACK_TIMEOUT_MS = 500; - - static @Nullable FirebaseCrashlytics init( - @NonNull FirebaseApp app, - @NonNull FirebaseInstallationsApi firebaseInstallationsApi, - @NonNull Deferred nativeComponent, - @NonNull Deferred analyticsConnector) { - - Context context = app.getApplicationContext(); - final String appIdentifier = context.getPackageName(); - Logger.getLogger() - .i( - "Initializing Firebase Crashlytics " - + CrashlyticsCore.getVersion() - + " for " - + appIdentifier); - - FileStore fileStore = new FileStore(context); - final DataCollectionArbiter arbiter = new DataCollectionArbiter(app); - final IdManager idManager = - new IdManager(context, appIdentifier, firebaseInstallationsApi, arbiter); - final CrashlyticsNativeComponentDeferredProxy deferredNativeComponent = - new CrashlyticsNativeComponentDeferredProxy(nativeComponent); - - // Integration with Firebase Analytics - final AnalyticsDeferredProxy analyticsDeferredProxy = - new AnalyticsDeferredProxy(analyticsConnector); - - final ExecutorService crashHandlerExecutor = - ExecutorUtils.buildSingleThreadExecutorService("Crashlytics Exception Handler"); - - CrashlyticsAppQualitySessionsSubscriber sessionsSubscriber = - new CrashlyticsAppQualitySessionsSubscriber(arbiter, fileStore); - FirebaseSessionsDependencies.register(sessionsSubscriber); - - final CrashlyticsCore core = - new CrashlyticsCore( - app, - idManager, - deferredNativeComponent, - arbiter, - analyticsDeferredProxy.getDeferredBreadcrumbSource(), - analyticsDeferredProxy.getAnalyticsEventLogger(), - fileStore, - crashHandlerExecutor, - sessionsSubscriber); - - final String googleAppId = app.getOptions().getApplicationId(); - final String mappingFileId = CommonUtils.getMappingFileId(context); - final List buildIdInfoList = CommonUtils.getBuildIdInfo(context); - - Logger.getLogger().d("Mapping file ID is: " + mappingFileId); - - for (BuildIdInfo buildIdInfo : buildIdInfoList) { - Logger.getLogger() - .d( - String.format( - "Build id for %s on %s: %s", - buildIdInfo.getLibraryName(), buildIdInfo.getArch(), buildIdInfo.getBuildId())); + static final String FIREBASE_CRASHLYTICS_ANALYTICS_ORIGIN = "clx"; + static final String LEGACY_CRASH_ANALYTICS_ORIGIN = "crash"; + static final int APP_EXCEPTION_CALLBACK_TIMEOUT_MS = 500; + + static @Nullable FirebaseCrashlytics init( + @NonNull FirebaseApp app, + @NonNull FirebaseInstallationsApi firebaseInstallationsApi, + @NonNull Deferred nativeComponent, + @NonNull Deferred analyticsConnector) { + + Context context = app.getApplicationContext(); + final String appIdentifier = context.getPackageName(); + Logger.getLogger() + .i( + "Initializing Firebase Crashlytics " + + CrashlyticsCore.getVersion() + + " for " + + appIdentifier); + + FileStore fileStore = new FileStore(context); + final DataCollectionArbiter arbiter = new DataCollectionArbiter(app); + final IdManager idManager = + new IdManager(context, appIdentifier, firebaseInstallationsApi, arbiter); + final CrashlyticsNativeComponentDeferredProxy deferredNativeComponent = + new CrashlyticsNativeComponentDeferredProxy(nativeComponent); + + // Integration with Firebase Analytics + final AnalyticsDeferredProxy analyticsDeferredProxy = + new AnalyticsDeferredProxy(analyticsConnector); + + final ExecutorService crashHandlerExecutor = + ExecutorUtils.buildSingleThreadExecutorService("Crashlytics Exception Handler"); + + CrashlyticsAppQualitySessionsSubscriber sessionsSubscriber = + new CrashlyticsAppQualitySessionsSubscriber(arbiter, fileStore); + FirebaseSessionsDependencies.register(sessionsSubscriber); + + final CrashlyticsCore core = + new CrashlyticsCore( + app, + idManager, + deferredNativeComponent, + arbiter, + analyticsDeferredProxy.getDeferredBreadcrumbSource(), + analyticsDeferredProxy.getAnalyticsEventLogger(), + fileStore, + crashHandlerExecutor, + sessionsSubscriber); + + final String googleAppId = app.getOptions().getApplicationId(); + final String mappingFileId = CommonUtils.getMappingFileId(context); + final List buildIdInfoList = CommonUtils.getBuildIdInfo(context); + + Logger.getLogger().d("Mapping file ID is: " + mappingFileId); + + for (BuildIdInfo buildIdInfo : buildIdInfoList) { + Logger.getLogger() + .d( + String.format( + "Build id for %s on %s: %s", + buildIdInfo.getLibraryName(), + buildIdInfo.getArch(), + buildIdInfo.getBuildId())); + } + + final DevelopmentPlatformProvider developmentPlatformProvider = + new DevelopmentPlatformProvider(context); + + AppData appData; + try { + appData = + AppData.create( + context, + idManager, + googleAppId, + mappingFileId, + buildIdInfoList, + developmentPlatformProvider); + } catch (PackageManager.NameNotFoundException e) { + Logger.getLogger().e("Error retrieving app package info.", e); + return null; + } + + Logger.getLogger().v("Installer package name is: " + appData.installerPackageName); + + final ExecutorService threadPoolExecutor = + ExecutorUtils.buildSingleThreadExecutorService( + "com.google.firebase.crashlytics.startup"); + + final SettingsController settingsController = + SettingsController.create( + context, + googleAppId, + idManager, + new HttpRequestFactory(), + appData.versionCode, + appData.versionName, + fileStore, + arbiter); + + // Kick off actually fetching the settings. + settingsController + .loadSettingsData(threadPoolExecutor) + .continueWith( + threadPoolExecutor, + new Continuation() { + @Override + public Object then(@NonNull Task task) throws Exception { + if (!task.isSuccessful()) { + Logger.getLogger() + .e("Error fetching settings.", task.getException()); + } + return null; + } + }); + + final boolean finishCoreInBackground = core.onPreExecute(appData, settingsController); + + Tasks.call( + threadPoolExecutor, + new Callable() { + @Override + public Void call() throws Exception { + if (finishCoreInBackground) { + core.doBackgroundInitializationAsync(settingsController); + } + return null; + } + }); + + return new FirebaseCrashlytics(core); } - final DevelopmentPlatformProvider developmentPlatformProvider = - new DevelopmentPlatformProvider(context); - - AppData appData; - try { - appData = - AppData.create( - context, - idManager, - googleAppId, - mappingFileId, - buildIdInfoList, - developmentPlatformProvider); - } catch (PackageManager.NameNotFoundException e) { - Logger.getLogger().e("Error retrieving app package info.", e); - return null; + @VisibleForTesting // accessible for smoke tests + final CrashlyticsCore core; + + private FirebaseCrashlytics(@NonNull CrashlyticsCore core) { + this.core = core; } - Logger.getLogger().v("Installer package name is: " + appData.installerPackageName); - - final ExecutorService threadPoolExecutor = - ExecutorUtils.buildSingleThreadExecutorService("com.google.firebase.crashlytics.startup"); - - final SettingsController settingsController = - SettingsController.create( - context, - googleAppId, - idManager, - new HttpRequestFactory(), - appData.versionCode, - appData.versionName, - fileStore, - arbiter); - - // Kick off actually fetching the settings. - settingsController - .loadSettingsData(threadPoolExecutor) - .continueWith( - threadPoolExecutor, - new Continuation() { - @Override - public Object then(@NonNull Task task) throws Exception { - if (!task.isSuccessful()) { - Logger.getLogger().e("Error fetching settings.", task.getException()); - } - return null; - } - }); - - final boolean finishCoreInBackground = core.onPreExecute(appData, settingsController); - - Tasks.call( - threadPoolExecutor, - new Callable() { - @Override - public Void call() throws Exception { - if (finishCoreInBackground) { - core.doBackgroundInitializationAsync(settingsController); - } - return null; - } - }); - - return new FirebaseCrashlytics(core); - } - - @VisibleForTesting // accessible for smoke tests - final CrashlyticsCore core; - - private FirebaseCrashlytics(@NonNull CrashlyticsCore core) { - this.core = core; - } - - /** - * Gets the singleton {@link FirebaseCrashlytics} instance. - * - *

The default {@link FirebaseApp} instance must be initialized before this function is called. - * See - * FirebaseApp for more information. - */ - @NonNull - public static FirebaseCrashlytics getInstance() { - final FirebaseApp app = FirebaseApp.getInstance(); - final FirebaseCrashlytics instance = app.get(FirebaseCrashlytics.class); - if (instance == null) { - throw new NullPointerException("FirebaseCrashlytics component is not present."); + /** + * Gets the singleton {@link FirebaseCrashlytics} instance. + * + *

The default {@link FirebaseApp} instance must be initialized before this function is + * called. See + * FirebaseApp for more information. + */ + @NonNull + public static FirebaseCrashlytics getInstance() { + final FirebaseApp app = FirebaseApp.getInstance(); + final FirebaseCrashlytics instance = app.get(FirebaseCrashlytics.class); + if (instance == null) { + throw new NullPointerException("FirebaseCrashlytics component is not present."); + } + return instance; + } + + /** + * Records a non-fatal report to send to Crashlytics. + * + * @param throwable a {@link Throwable} to be recorded as a non-fatal event. + */ + public void recordException(@NonNull Throwable throwable) { + if (throwable == null) { // Users could call this with null despite the annotation. + Logger.getLogger().w("A null value was passed to recordException. Ignoring."); + return; + } + core.logException(throwable); + } + + /** + * Logs a message that's included in the next fatal, non-fatal, or ANR report. + * + *

Logs are visible in the session view on the Firebase Crashlytics console. + * + *

Newline characters are stripped and extremely long messages are truncated. The maximum log + * size is 64k. If exceeded, the log rolls such that messages are removed, starting from the + * oldest. + * + * @param message the message to be logged + */ + public void log(@NonNull String message) { + core.log(message); + } + + /** + * Records a user ID (identifier) that's associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

The user ID is visible in the session view on the Firebase Crashlytics console. + * + *

Identifiers longer than 1024 characters will be truncated. + * + * @param identifier a unique identifier for the current user + */ + public void setUserId(@NonNull String identifier) { + core.setUserId(identifier); } - return instance; - } - - /** - * Records a non-fatal report to send to Crashlytics. - * - * @param throwable a {@link Throwable} to be recorded as a non-fatal event. - */ - public void recordException(@NonNull Throwable throwable) { - if (throwable == null) { // Users could call this with null despite the annotation. - Logger.getLogger().w("A null value was passed to recordException. Ignoring."); - return; + + /** + * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with + * that event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or + * values that exceed 1024 characters are truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, boolean value) { + core.setCustomKey(key, Boolean.toString(value)); + } + + /** + * Sets a custom key and value that are associated with subsequent fatal and non-fatal reports. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal or non-fatal event is associated with that + * event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or + * values that exceed 1024 characters are truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, double value) { + core.setCustomKey(key, Double.toString(value)); + } + + /** + * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with + * that event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or + * values that exceed 1024 characters are truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, float value) { + core.setCustomKey(key, Float.toString(value)); + } + + /** + * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with + * that event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or + * values that exceed 1024 characters are truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, int value) { + core.setCustomKey(key, Integer.toString(value)); + } + + /** + * Records a custom key and value to be associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

Multiple calls to this method with the same key will update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event will be associated + * with that event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

A maximum of 64 key/value pairs can be written, and new keys added beyond that limit will + * be ignored. Keys or values that exceed 1024 characters will be truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, long value) { + core.setCustomKey(key, Long.toString(value)); + } + + /** + * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with + * that event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or + * values that exceed 1024 characters are truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, @NonNull String value) { + core.setCustomKey(key, value); + } + + /** + * Sets multiple custom keys and values that are associated with subsequent fatal, non-fatal, + * and ANR reports. This method is intended as an alternative to {@code setCustomKey} in order + * to reduce the computational load of writing out multiple key/value pairs at the same time. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with + * that event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. If calling this method results in the number of + * custom keys exceeding this limit, only some of the keys will be logged (however many are + * needed to get to 64). Which keys are logged versus dropped is unpredictable as there is no + * intrinsic sorting of keys. Keys or values that exceed 1024 characters are truncated. + * + * @param keysAndValues A dictionary of keys and the values to associate with each key + */ + public void setCustomKeys(@NonNull CustomKeysAndValues keysAndValues) { + core.setCustomKeys(keysAndValues.keysAndValues); + } + + // region Unsent report management. + + /** + * Checks a device for any fatal crash, non-fatal error, or ANR reports that haven't yet been + * sent to Crashlytics. If automatic data collection is enabled, then reports are uploaded + * automatically and this always returns false. If automatic data collection is disabled, this + * method can be used to check whether the user opts-in to send crash reports from their device. + * + * @return a Task that is resolved with the result. + */ + @NonNull + public Task checkForUnsentReports() { + return core.checkForUnsentReports(); + } + + /** + * If automatic data collection is disabled, this method queues up all the reports on a device + * to send to Crashlytics. Otherwise, this method is a no-op. + */ + public void sendUnsentReports() { + core.sendUnsentReports(); + } + + /** + * If automatic data collection is disabled, this method queues up all the reports on a device + * for deletion. Otherwise, this method is a no-op. + */ + public void deleteUnsentReports() { + core.deleteUnsentReports(); + } + + // endregion + + /** + * Checks whether the app crashed on its previous run. + * + * @return true if a crash was recorded during the previous run of the app. + */ + public boolean didCrashOnPreviousExecution() { + return core.didCrashOnPreviousExecution(); + } + + /** + * Enables or disables the automatic data collection configuration for Crashlytics. + * + *

If this is set, it overrides any automatic data collection settings configured in the + * AndroidManifest.xml as well as any Firebase-wide settings. + * + *

If automatic data collection is disabled for Crashlytics, crash reports are stored on the + * device. To check for reports, use the {@link #checkForUnsentReports()} method. Use {@link + * #sendUnsentReports()} to upload existing reports even when automatic data collection is + * disabled. Use {@link #deleteUnsentReports()} to delete any reports stored on the device + * without sending them to Crashlytics. + * + * @param enabled whether to enable automatic data collection. When set to {@code false}, the + * new value does not apply until the next run of the app. To disable data collection by + * default for all app runs, add the {@code firebase_crashlytics_collection_enabled} flag to + * your app's AndroidManifest.xml. + */ + public void setCrashlyticsCollectionEnabled(boolean enabled) { + core.setCrashlyticsCollectionEnabled(enabled); + } + + /** + * Enables or disables the automatic data collection configuration for Crashlytics. + * + *

If this is set, it overrides any automatic data collection settings configured in the + * AndroidManifest.xml as well as any Firebase-wide settings. If set to {@code null}, the + * override is cleared. + * + *

If automatic data collection is disabled for Crashlytics, crash reports are stored on the + * device. To check for reports, use the {@link #checkForUnsentReports()} method. Use {@link + * #sendUnsentReports()} to upload existing reports even when automatic data collection is + * disabled. Use {@link #deleteUnsentReports()} to delete any reports stored on the device + * without sending them to Crashlytics. + * + * @param enabled whether to enable or disable automatic data collection. When set to {@code + * false}, the new value does not apply until the next run of the app. When set to {@code + * null}, the override is cleared and automatic data collection settings are determined by + * the configuration in your AndroidManifest.xml or other Firebase-wide settings. + */ + public void setCrashlyticsCollectionEnabled(@Nullable Boolean enabled) { + core.setCrashlyticsCollectionEnabled(enabled); } - core.logException(throwable); - } - - /** - * Logs a message that's included in the next fatal, non-fatal, or ANR report. - * - *

Logs are visible in the session view on the Firebase Crashlytics console. - * - *

Newline characters are stripped and extremely long messages are truncated. The maximum log - * size is 64k. If exceeded, the log rolls such that messages are removed, starting from the - * oldest. - * - * @param message the message to be logged - */ - public void log(@NonNull String message) { - core.log(message); - } - - /** - * Records a user ID (identifier) that's associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

The user ID is visible in the session view on the Firebase Crashlytics console. - * - *

Identifiers longer than 1024 characters will be truncated. - * - * @param identifier a unique identifier for the current user - */ - public void setUserId(@NonNull String identifier) { - core.setUserId(identifier); - } - - /** - * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with that - * event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or - * values that exceed 1024 characters are truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, boolean value) { - core.setCustomKey(key, Boolean.toString(value)); - } - - /** - * Sets a custom key and value that are associated with subsequent fatal and non-fatal reports. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal or non-fatal event is associated with that - * event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or - * values that exceed 1024 characters are truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, double value) { - core.setCustomKey(key, Double.toString(value)); - } - - /** - * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with that - * event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or - * values that exceed 1024 characters are truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, float value) { - core.setCustomKey(key, Float.toString(value)); - } - - /** - * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with that - * event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or - * values that exceed 1024 characters are truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, int value) { - core.setCustomKey(key, Integer.toString(value)); - } - - /** - * Records a custom key and value to be associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

Multiple calls to this method with the same key will update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event will be associated with - * that event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

A maximum of 64 key/value pairs can be written, and new keys added beyond that limit will be - * ignored. Keys or values that exceed 1024 characters will be truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, long value) { - core.setCustomKey(key, Long.toString(value)); - } - - /** - * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with that - * event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or - * values that exceed 1024 characters are truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, @NonNull String value) { - core.setCustomKey(key, value); - } - - /** - * Sets multiple custom keys and values that are associated with subsequent fatal, non-fatal, and - * ANR reports. This method is intended as an alternative to {@code setCustomKey} in order to - * reduce the computational load of writing out multiple key/value pairs at the same time. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with that - * event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. If calling this method results in the number of - * custom keys exceeding this limit, only some of the keys will be logged (however many are needed - * to get to 64). Which keys are logged versus dropped is unpredictable as there is no intrinsic - * sorting of keys. Keys or values that exceed 1024 characters are truncated. - * - * @param keysAndValues A dictionary of keys and the values to associate with each key - */ - public void setCustomKeys(@NonNull CustomKeysAndValues keysAndValues) { - core.setCustomKeys(keysAndValues.keysAndValues); - } - - // region Unsent report management. - - /** - * Checks a device for any fatal crash, non-fatal error, or ANR reports that haven't yet been sent - * to Crashlytics. If automatic data collection is enabled, then reports are uploaded - * automatically and this always returns false. If automatic data collection is disabled, this - * method can be used to check whether the user opts-in to send crash reports from their device. - * - * @return a Task that is resolved with the result. - */ - @NonNull - public Task checkForUnsentReports() { - return core.checkForUnsentReports(); - } - - /** - * If automatic data collection is disabled, this method queues up all the reports on a device to - * send to Crashlytics. Otherwise, this method is a no-op. - */ - public void sendUnsentReports() { - core.sendUnsentReports(); - } - - /** - * If automatic data collection is disabled, this method queues up all the reports on a device for - * deletion. Otherwise, this method is a no-op. - */ - public void deleteUnsentReports() { - core.deleteUnsentReports(); - } - - // endregion - - /** - * Checks whether the app crashed on its previous run. - * - * @return true if a crash was recorded during the previous run of the app. - */ - public boolean didCrashOnPreviousExecution() { - return core.didCrashOnPreviousExecution(); - } - - /** - * Enables or disables the automatic data collection configuration for Crashlytics. - * - *

If this is set, it overrides any automatic data collection settings configured in the - * AndroidManifest.xml as well as any Firebase-wide settings. - * - *

If automatic data collection is disabled for Crashlytics, crash reports are stored on the - * device. To check for reports, use the {@link #checkForUnsentReports()} method. Use {@link - * #sendUnsentReports()} to upload existing reports even when automatic data collection is - * disabled. Use {@link #deleteUnsentReports()} to delete any reports stored on the device without - * sending them to Crashlytics. - * - * @param enabled whether to enable automatic data collection. When set to {@code false}, the new - * value does not apply until the next run of the app. To disable data collection by default - * for all app runs, add the {@code firebase_crashlytics_collection_enabled} flag to your - * app's AndroidManifest.xml. - */ - public void setCrashlyticsCollectionEnabled(boolean enabled) { - core.setCrashlyticsCollectionEnabled(enabled); - } - - /** - * Enables or disables the automatic data collection configuration for Crashlytics. - * - *

If this is set, it overrides any automatic data collection settings configured in the - * AndroidManifest.xml as well as any Firebase-wide settings. If set to {@code null}, the override - * is cleared. - * - *

If automatic data collection is disabled for Crashlytics, crash reports are stored on the - * device. To check for reports, use the {@link #checkForUnsentReports()} method. Use {@link - * #sendUnsentReports()} to upload existing reports even when automatic data collection is - * disabled. Use {@link #deleteUnsentReports()} to delete any reports stored on the device without - * sending them to Crashlytics. - * - * @param enabled whether to enable or disable automatic data collection. When set to {@code - * false}, the new value does not apply until the next run of the app. When set to {@code - * null}, the override is cleared and automatic data collection settings are determined by the - * configuration in your AndroidManifest.xml or other Firebase-wide settings. - */ - public void setCrashlyticsCollectionEnabled(@Nullable Boolean enabled) { - core.setCrashlyticsCollectionEnabled(enabled); - } } From 4f06c9d39bf339c94260ded7d584dbfd4d72e9a6 Mon Sep 17 00:00:00 2001 From: jrothfeder Date: Thu, 19 Oct 2023 16:21:44 -0400 Subject: [PATCH 5/6] Formatting --- .../crashlytics/FirebaseCrashlytics.java | 863 +++++++++--------- .../firebase/perf/FirebasePerfEarly.java | 4 +- 2 files changed, 430 insertions(+), 437 deletions(-) diff --git a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java index 2ba74ac6c9b..2dde4a3a6cf 100644 --- a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java +++ b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java @@ -42,7 +42,6 @@ import com.google.firebase.inject.Deferred; import com.google.firebase.installations.FirebaseInstallationsApi; import com.google.firebase.sessions.api.FirebaseSessionsDependencies; - import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -58,443 +57,439 @@ */ public class FirebaseCrashlytics { - static final String FIREBASE_CRASHLYTICS_ANALYTICS_ORIGIN = "clx"; - static final String LEGACY_CRASH_ANALYTICS_ORIGIN = "crash"; - static final int APP_EXCEPTION_CALLBACK_TIMEOUT_MS = 500; - - static @Nullable FirebaseCrashlytics init( - @NonNull FirebaseApp app, - @NonNull FirebaseInstallationsApi firebaseInstallationsApi, - @NonNull Deferred nativeComponent, - @NonNull Deferred analyticsConnector) { - - Context context = app.getApplicationContext(); - final String appIdentifier = context.getPackageName(); - Logger.getLogger() - .i( - "Initializing Firebase Crashlytics " - + CrashlyticsCore.getVersion() - + " for " - + appIdentifier); - - FileStore fileStore = new FileStore(context); - final DataCollectionArbiter arbiter = new DataCollectionArbiter(app); - final IdManager idManager = - new IdManager(context, appIdentifier, firebaseInstallationsApi, arbiter); - final CrashlyticsNativeComponentDeferredProxy deferredNativeComponent = - new CrashlyticsNativeComponentDeferredProxy(nativeComponent); - - // Integration with Firebase Analytics - final AnalyticsDeferredProxy analyticsDeferredProxy = - new AnalyticsDeferredProxy(analyticsConnector); - - final ExecutorService crashHandlerExecutor = - ExecutorUtils.buildSingleThreadExecutorService("Crashlytics Exception Handler"); - - CrashlyticsAppQualitySessionsSubscriber sessionsSubscriber = - new CrashlyticsAppQualitySessionsSubscriber(arbiter, fileStore); - FirebaseSessionsDependencies.register(sessionsSubscriber); - - final CrashlyticsCore core = - new CrashlyticsCore( - app, - idManager, - deferredNativeComponent, - arbiter, - analyticsDeferredProxy.getDeferredBreadcrumbSource(), - analyticsDeferredProxy.getAnalyticsEventLogger(), - fileStore, - crashHandlerExecutor, - sessionsSubscriber); - - final String googleAppId = app.getOptions().getApplicationId(); - final String mappingFileId = CommonUtils.getMappingFileId(context); - final List buildIdInfoList = CommonUtils.getBuildIdInfo(context); - - Logger.getLogger().d("Mapping file ID is: " + mappingFileId); - - for (BuildIdInfo buildIdInfo : buildIdInfoList) { - Logger.getLogger() - .d( - String.format( - "Build id for %s on %s: %s", - buildIdInfo.getLibraryName(), - buildIdInfo.getArch(), - buildIdInfo.getBuildId())); - } - - final DevelopmentPlatformProvider developmentPlatformProvider = - new DevelopmentPlatformProvider(context); - - AppData appData; - try { - appData = - AppData.create( - context, - idManager, - googleAppId, - mappingFileId, - buildIdInfoList, - developmentPlatformProvider); - } catch (PackageManager.NameNotFoundException e) { - Logger.getLogger().e("Error retrieving app package info.", e); - return null; - } - - Logger.getLogger().v("Installer package name is: " + appData.installerPackageName); - - final ExecutorService threadPoolExecutor = - ExecutorUtils.buildSingleThreadExecutorService( - "com.google.firebase.crashlytics.startup"); - - final SettingsController settingsController = - SettingsController.create( - context, - googleAppId, - idManager, - new HttpRequestFactory(), - appData.versionCode, - appData.versionName, - fileStore, - arbiter); - - // Kick off actually fetching the settings. - settingsController - .loadSettingsData(threadPoolExecutor) - .continueWith( - threadPoolExecutor, - new Continuation() { - @Override - public Object then(@NonNull Task task) throws Exception { - if (!task.isSuccessful()) { - Logger.getLogger() - .e("Error fetching settings.", task.getException()); - } - return null; - } - }); - - final boolean finishCoreInBackground = core.onPreExecute(appData, settingsController); - - Tasks.call( - threadPoolExecutor, - new Callable() { - @Override - public Void call() throws Exception { - if (finishCoreInBackground) { - core.doBackgroundInitializationAsync(settingsController); - } - return null; - } - }); - - return new FirebaseCrashlytics(core); - } - - @VisibleForTesting // accessible for smoke tests - final CrashlyticsCore core; - - private FirebaseCrashlytics(@NonNull CrashlyticsCore core) { - this.core = core; - } - - /** - * Gets the singleton {@link FirebaseCrashlytics} instance. - * - *

The default {@link FirebaseApp} instance must be initialized before this function is - * called. See - * FirebaseApp for more information. - */ - @NonNull - public static FirebaseCrashlytics getInstance() { - final FirebaseApp app = FirebaseApp.getInstance(); - final FirebaseCrashlytics instance = app.get(FirebaseCrashlytics.class); - if (instance == null) { - throw new NullPointerException("FirebaseCrashlytics component is not present."); - } - return instance; - } - - /** - * Records a non-fatal report to send to Crashlytics. - * - * @param throwable a {@link Throwable} to be recorded as a non-fatal event. - */ - public void recordException(@NonNull Throwable throwable) { - if (throwable == null) { // Users could call this with null despite the annotation. - Logger.getLogger().w("A null value was passed to recordException. Ignoring."); - return; - } - core.logException(throwable); - } - - /** - * Logs a message that's included in the next fatal, non-fatal, or ANR report. - * - *

Logs are visible in the session view on the Firebase Crashlytics console. - * - *

Newline characters are stripped and extremely long messages are truncated. The maximum log - * size is 64k. If exceeded, the log rolls such that messages are removed, starting from the - * oldest. - * - * @param message the message to be logged - */ - public void log(@NonNull String message) { - core.log(message); - } - - /** - * Records a user ID (identifier) that's associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

The user ID is visible in the session view on the Firebase Crashlytics console. - * - *

Identifiers longer than 1024 characters will be truncated. - * - * @param identifier a unique identifier for the current user - */ - public void setUserId(@NonNull String identifier) { - core.setUserId(identifier); - } - - /** - * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with - * that event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or - * values that exceed 1024 characters are truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, boolean value) { - core.setCustomKey(key, Boolean.toString(value)); - } - - /** - * Sets a custom key and value that are associated with subsequent fatal and non-fatal reports. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal or non-fatal event is associated with that - * event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or - * values that exceed 1024 characters are truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, double value) { - core.setCustomKey(key, Double.toString(value)); - } - - /** - * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with - * that event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or - * values that exceed 1024 characters are truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, float value) { - core.setCustomKey(key, Float.toString(value)); - } - - /** - * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with - * that event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or - * values that exceed 1024 characters are truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, int value) { - core.setCustomKey(key, Integer.toString(value)); - } - - /** - * Records a custom key and value to be associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

Multiple calls to this method with the same key will update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event will be associated - * with that event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

A maximum of 64 key/value pairs can be written, and new keys added beyond that limit will - * be ignored. Keys or values that exceed 1024 characters will be truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, long value) { - core.setCustomKey(key, Long.toString(value)); - } - - /** - * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR - * reports. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with - * that event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or - * values that exceed 1024 characters are truncated. - * - * @param key A unique key - * @param value A value to be associated with the given key - */ - public void setCustomKey(@NonNull String key, @NonNull String value) { - core.setCustomKey(key, value); - } - - /** - * Sets multiple custom keys and values that are associated with subsequent fatal, non-fatal, - * and ANR reports. This method is intended as an alternative to {@code setCustomKey} in order - * to reduce the computational load of writing out multiple key/value pairs at the same time. - * - *

Multiple calls to this method with the same key update the value for that key. - * - *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with - * that event. - * - *

Keys and associated values are visible in the session view on the Firebase Crashlytics - * console. - * - *

Accepts a maximum of 64 key/value pairs. If calling this method results in the number of - * custom keys exceeding this limit, only some of the keys will be logged (however many are - * needed to get to 64). Which keys are logged versus dropped is unpredictable as there is no - * intrinsic sorting of keys. Keys or values that exceed 1024 characters are truncated. - * - * @param keysAndValues A dictionary of keys and the values to associate with each key - */ - public void setCustomKeys(@NonNull CustomKeysAndValues keysAndValues) { - core.setCustomKeys(keysAndValues.keysAndValues); + static final String FIREBASE_CRASHLYTICS_ANALYTICS_ORIGIN = "clx"; + static final String LEGACY_CRASH_ANALYTICS_ORIGIN = "crash"; + static final int APP_EXCEPTION_CALLBACK_TIMEOUT_MS = 500; + + static @Nullable FirebaseCrashlytics init( + @NonNull FirebaseApp app, + @NonNull FirebaseInstallationsApi firebaseInstallationsApi, + @NonNull Deferred nativeComponent, + @NonNull Deferred analyticsConnector) { + + Context context = app.getApplicationContext(); + final String appIdentifier = context.getPackageName(); + Logger.getLogger() + .i( + "Initializing Firebase Crashlytics " + + CrashlyticsCore.getVersion() + + " for " + + appIdentifier); + + FileStore fileStore = new FileStore(context); + final DataCollectionArbiter arbiter = new DataCollectionArbiter(app); + final IdManager idManager = + new IdManager(context, appIdentifier, firebaseInstallationsApi, arbiter); + final CrashlyticsNativeComponentDeferredProxy deferredNativeComponent = + new CrashlyticsNativeComponentDeferredProxy(nativeComponent); + + // Integration with Firebase Analytics + final AnalyticsDeferredProxy analyticsDeferredProxy = + new AnalyticsDeferredProxy(analyticsConnector); + + final ExecutorService crashHandlerExecutor = + ExecutorUtils.buildSingleThreadExecutorService("Crashlytics Exception Handler"); + + CrashlyticsAppQualitySessionsSubscriber sessionsSubscriber = + new CrashlyticsAppQualitySessionsSubscriber(arbiter, fileStore); + FirebaseSessionsDependencies.register(sessionsSubscriber); + + final CrashlyticsCore core = + new CrashlyticsCore( + app, + idManager, + deferredNativeComponent, + arbiter, + analyticsDeferredProxy.getDeferredBreadcrumbSource(), + analyticsDeferredProxy.getAnalyticsEventLogger(), + fileStore, + crashHandlerExecutor, + sessionsSubscriber); + + final String googleAppId = app.getOptions().getApplicationId(); + final String mappingFileId = CommonUtils.getMappingFileId(context); + final List buildIdInfoList = CommonUtils.getBuildIdInfo(context); + + Logger.getLogger().d("Mapping file ID is: " + mappingFileId); + + for (BuildIdInfo buildIdInfo : buildIdInfoList) { + Logger.getLogger() + .d( + String.format( + "Build id for %s on %s: %s", + buildIdInfo.getLibraryName(), buildIdInfo.getArch(), buildIdInfo.getBuildId())); } - // region Unsent report management. - - /** - * Checks a device for any fatal crash, non-fatal error, or ANR reports that haven't yet been - * sent to Crashlytics. If automatic data collection is enabled, then reports are uploaded - * automatically and this always returns false. If automatic data collection is disabled, this - * method can be used to check whether the user opts-in to send crash reports from their device. - * - * @return a Task that is resolved with the result. - */ - @NonNull - public Task checkForUnsentReports() { - return core.checkForUnsentReports(); + final DevelopmentPlatformProvider developmentPlatformProvider = + new DevelopmentPlatformProvider(context); + + AppData appData; + try { + appData = + AppData.create( + context, + idManager, + googleAppId, + mappingFileId, + buildIdInfoList, + developmentPlatformProvider); + } catch (PackageManager.NameNotFoundException e) { + Logger.getLogger().e("Error retrieving app package info.", e); + return null; } - /** - * If automatic data collection is disabled, this method queues up all the reports on a device - * to send to Crashlytics. Otherwise, this method is a no-op. - */ - public void sendUnsentReports() { - core.sendUnsentReports(); - } - - /** - * If automatic data collection is disabled, this method queues up all the reports on a device - * for deletion. Otherwise, this method is a no-op. - */ - public void deleteUnsentReports() { - core.deleteUnsentReports(); - } - - // endregion - - /** - * Checks whether the app crashed on its previous run. - * - * @return true if a crash was recorded during the previous run of the app. - */ - public boolean didCrashOnPreviousExecution() { - return core.didCrashOnPreviousExecution(); - } - - /** - * Enables or disables the automatic data collection configuration for Crashlytics. - * - *

If this is set, it overrides any automatic data collection settings configured in the - * AndroidManifest.xml as well as any Firebase-wide settings. - * - *

If automatic data collection is disabled for Crashlytics, crash reports are stored on the - * device. To check for reports, use the {@link #checkForUnsentReports()} method. Use {@link - * #sendUnsentReports()} to upload existing reports even when automatic data collection is - * disabled. Use {@link #deleteUnsentReports()} to delete any reports stored on the device - * without sending them to Crashlytics. - * - * @param enabled whether to enable automatic data collection. When set to {@code false}, the - * new value does not apply until the next run of the app. To disable data collection by - * default for all app runs, add the {@code firebase_crashlytics_collection_enabled} flag to - * your app's AndroidManifest.xml. - */ - public void setCrashlyticsCollectionEnabled(boolean enabled) { - core.setCrashlyticsCollectionEnabled(enabled); + Logger.getLogger().v("Installer package name is: " + appData.installerPackageName); + + final ExecutorService threadPoolExecutor = + ExecutorUtils.buildSingleThreadExecutorService("com.google.firebase.crashlytics.startup"); + + final SettingsController settingsController = + SettingsController.create( + context, + googleAppId, + idManager, + new HttpRequestFactory(), + appData.versionCode, + appData.versionName, + fileStore, + arbiter); + + // Kick off actually fetching the settings. + settingsController + .loadSettingsData(threadPoolExecutor) + .continueWith( + threadPoolExecutor, + new Continuation() { + @Override + public Object then(@NonNull Task task) throws Exception { + if (!task.isSuccessful()) { + Logger.getLogger().e("Error fetching settings.", task.getException()); + } + return null; + } + }); + + final boolean finishCoreInBackground = core.onPreExecute(appData, settingsController); + + Tasks.call( + threadPoolExecutor, + new Callable() { + @Override + public Void call() throws Exception { + if (finishCoreInBackground) { + core.doBackgroundInitializationAsync(settingsController); + } + return null; + } + }); + + return new FirebaseCrashlytics(core); + } + + @VisibleForTesting // accessible for smoke tests + final CrashlyticsCore core; + + private FirebaseCrashlytics(@NonNull CrashlyticsCore core) { + this.core = core; + } + + /** + * Gets the singleton {@link FirebaseCrashlytics} instance. + * + *

The default {@link FirebaseApp} instance must be initialized before this function is called. + * See + * FirebaseApp for more information. + */ + @NonNull + public static FirebaseCrashlytics getInstance() { + final FirebaseApp app = FirebaseApp.getInstance(); + final FirebaseCrashlytics instance = app.get(FirebaseCrashlytics.class); + if (instance == null) { + throw new NullPointerException("FirebaseCrashlytics component is not present."); } - - /** - * Enables or disables the automatic data collection configuration for Crashlytics. - * - *

If this is set, it overrides any automatic data collection settings configured in the - * AndroidManifest.xml as well as any Firebase-wide settings. If set to {@code null}, the - * override is cleared. - * - *

If automatic data collection is disabled for Crashlytics, crash reports are stored on the - * device. To check for reports, use the {@link #checkForUnsentReports()} method. Use {@link - * #sendUnsentReports()} to upload existing reports even when automatic data collection is - * disabled. Use {@link #deleteUnsentReports()} to delete any reports stored on the device - * without sending them to Crashlytics. - * - * @param enabled whether to enable or disable automatic data collection. When set to {@code - * false}, the new value does not apply until the next run of the app. When set to {@code - * null}, the override is cleared and automatic data collection settings are determined by - * the configuration in your AndroidManifest.xml or other Firebase-wide settings. - */ - public void setCrashlyticsCollectionEnabled(@Nullable Boolean enabled) { - core.setCrashlyticsCollectionEnabled(enabled); + return instance; + } + + /** + * Records a non-fatal report to send to Crashlytics. + * + * @param throwable a {@link Throwable} to be recorded as a non-fatal event. + */ + public void recordException(@NonNull Throwable throwable) { + if (throwable == null) { // Users could call this with null despite the annotation. + Logger.getLogger().w("A null value was passed to recordException. Ignoring."); + return; } + core.logException(throwable); + } + + /** + * Logs a message that's included in the next fatal, non-fatal, or ANR report. + * + *

Logs are visible in the session view on the Firebase Crashlytics console. + * + *

Newline characters are stripped and extremely long messages are truncated. The maximum log + * size is 64k. If exceeded, the log rolls such that messages are removed, starting from the + * oldest. + * + * @param message the message to be logged + */ + public void log(@NonNull String message) { + core.log(message); + } + + /** + * Records a user ID (identifier) that's associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

The user ID is visible in the session view on the Firebase Crashlytics console. + * + *

Identifiers longer than 1024 characters will be truncated. + * + * @param identifier a unique identifier for the current user + */ + public void setUserId(@NonNull String identifier) { + core.setUserId(identifier); + } + + /** + * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with that + * event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or + * values that exceed 1024 characters are truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, boolean value) { + core.setCustomKey(key, Boolean.toString(value)); + } + + /** + * Sets a custom key and value that are associated with subsequent fatal and non-fatal reports. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal or non-fatal event is associated with that + * event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or + * values that exceed 1024 characters are truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, double value) { + core.setCustomKey(key, Double.toString(value)); + } + + /** + * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with that + * event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or + * values that exceed 1024 characters are truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, float value) { + core.setCustomKey(key, Float.toString(value)); + } + + /** + * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with that + * event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or + * values that exceed 1024 characters are truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, int value) { + core.setCustomKey(key, Integer.toString(value)); + } + + /** + * Records a custom key and value to be associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

Multiple calls to this method with the same key will update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event will be associated with + * that event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

A maximum of 64 key/value pairs can be written, and new keys added beyond that limit will be + * ignored. Keys or values that exceed 1024 characters will be truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, long value) { + core.setCustomKey(key, Long.toString(value)); + } + + /** + * Sets a custom key and value that are associated with subsequent fatal, non-fatal, and ANR + * reports. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with that + * event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. New keys beyond that limit are ignored. Keys or + * values that exceed 1024 characters are truncated. + * + * @param key A unique key + * @param value A value to be associated with the given key + */ + public void setCustomKey(@NonNull String key, @NonNull String value) { + core.setCustomKey(key, value); + } + + /** + * Sets multiple custom keys and values that are associated with subsequent fatal, non-fatal, and + * ANR reports. This method is intended as an alternative to {@code setCustomKey} in order to + * reduce the computational load of writing out multiple key/value pairs at the same time. + * + *

Multiple calls to this method with the same key update the value for that key. + * + *

The value of any key at the time of a fatal, non-fatal, or ANR event is associated with that + * event. + * + *

Keys and associated values are visible in the session view on the Firebase Crashlytics + * console. + * + *

Accepts a maximum of 64 key/value pairs. If calling this method results in the number of + * custom keys exceeding this limit, only some of the keys will be logged (however many are needed + * to get to 64). Which keys are logged versus dropped is unpredictable as there is no intrinsic + * sorting of keys. Keys or values that exceed 1024 characters are truncated. + * + * @param keysAndValues A dictionary of keys and the values to associate with each key + */ + public void setCustomKeys(@NonNull CustomKeysAndValues keysAndValues) { + core.setCustomKeys(keysAndValues.keysAndValues); + } + + // region Unsent report management. + + /** + * Checks a device for any fatal crash, non-fatal error, or ANR reports that haven't yet been sent + * to Crashlytics. If automatic data collection is enabled, then reports are uploaded + * automatically and this always returns false. If automatic data collection is disabled, this + * method can be used to check whether the user opts-in to send crash reports from their device. + * + * @return a Task that is resolved with the result. + */ + @NonNull + public Task checkForUnsentReports() { + return core.checkForUnsentReports(); + } + + /** + * If automatic data collection is disabled, this method queues up all the reports on a device to + * send to Crashlytics. Otherwise, this method is a no-op. + */ + public void sendUnsentReports() { + core.sendUnsentReports(); + } + + /** + * If automatic data collection is disabled, this method queues up all the reports on a device for + * deletion. Otherwise, this method is a no-op. + */ + public void deleteUnsentReports() { + core.deleteUnsentReports(); + } + + // endregion + + /** + * Checks whether the app crashed on its previous run. + * + * @return true if a crash was recorded during the previous run of the app. + */ + public boolean didCrashOnPreviousExecution() { + return core.didCrashOnPreviousExecution(); + } + + /** + * Enables or disables the automatic data collection configuration for Crashlytics. + * + *

If this is set, it overrides any automatic data collection settings configured in the + * AndroidManifest.xml as well as any Firebase-wide settings. + * + *

If automatic data collection is disabled for Crashlytics, crash reports are stored on the + * device. To check for reports, use the {@link #checkForUnsentReports()} method. Use {@link + * #sendUnsentReports()} to upload existing reports even when automatic data collection is + * disabled. Use {@link #deleteUnsentReports()} to delete any reports stored on the device without + * sending them to Crashlytics. + * + * @param enabled whether to enable automatic data collection. When set to {@code false}, the new + * value does not apply until the next run of the app. To disable data collection by default + * for all app runs, add the {@code firebase_crashlytics_collection_enabled} flag to your + * app's AndroidManifest.xml. + */ + public void setCrashlyticsCollectionEnabled(boolean enabled) { + core.setCrashlyticsCollectionEnabled(enabled); + } + + /** + * Enables or disables the automatic data collection configuration for Crashlytics. + * + *

If this is set, it overrides any automatic data collection settings configured in the + * AndroidManifest.xml as well as any Firebase-wide settings. If set to {@code null}, the override + * is cleared. + * + *

If automatic data collection is disabled for Crashlytics, crash reports are stored on the + * device. To check for reports, use the {@link #checkForUnsentReports()} method. Use {@link + * #sendUnsentReports()} to upload existing reports even when automatic data collection is + * disabled. Use {@link #deleteUnsentReports()} to delete any reports stored on the device without + * sending them to Crashlytics. + * + * @param enabled whether to enable or disable automatic data collection. When set to {@code + * false}, the new value does not apply until the next run of the app. When set to {@code + * null}, the override is cleared and automatic data collection settings are determined by the + * configuration in your AndroidManifest.xml or other Firebase-wide settings. + */ + public void setCrashlyticsCollectionEnabled(@Nullable Boolean enabled) { + core.setCrashlyticsCollectionEnabled(enabled); + } } 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 ecc1ce637a2..5e5d05ee7a4 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 @@ -38,9 +38,7 @@ public class FirebasePerfEarly { public FirebasePerfEarly( - FirebaseApp app, - @Nullable StartupTime startupTime, - Executor uiExecutor) { + FirebaseApp app, @Nullable StartupTime startupTime, Executor uiExecutor) { Context context = app.getApplicationContext(); // Initialize ConfigResolver early for accessing device caching layer. From c24b3deaa8f0ddc2364c70427dec507211a33c31 Mon Sep 17 00:00:00 2001 From: jrothfeder Date: Fri, 20 Oct 2023 15:01:27 -0400 Subject: [PATCH 6/6] PR feedback --- .../firebase-crashlytics.gradle | 1 - firebase-sessions/api.txt | 17 ----------------- .../firebase/sessions/FirebaseSessions.kt | 6 ++---- gradle/libs.versions.toml | 1 - 4 files changed, 2 insertions(+), 23 deletions(-) diff --git a/firebase-crashlytics/firebase-crashlytics.gradle b/firebase-crashlytics/firebase-crashlytics.gradle index 1146aee4c93..532689e3a5f 100644 --- a/firebase-crashlytics/firebase-crashlytics.gradle +++ b/firebase-crashlytics/firebase-crashlytics.gradle @@ -59,7 +59,6 @@ thirdPartyLicenses { } dependencies { - implementation libs.firebase.sessions androidTestImplementation "androidx.test.ext:junit:$androidxTestJUnitVersion" androidTestImplementation "androidx.test:core:$androidxTestCoreVersion" androidTestImplementation "com.google.truth:truth:$googleTruthVersion" diff --git a/firebase-sessions/api.txt b/firebase-sessions/api.txt index 621450832bf..20376d6c21a 100644 --- a/firebase-sessions/api.txt +++ b/firebase-sessions/api.txt @@ -1,21 +1,4 @@ // Signature format: 2.0 -package com.google.firebase.sessions { - - public final class FirebaseSessions { - method @NonNull public static com.google.firebase.sessions.FirebaseSessions getInstance(); - method @Deprecated @NonNull public static com.google.firebase.sessions.FirebaseSessions getInstance(@NonNull com.google.firebase.FirebaseApp app); - property @NonNull public static final com.google.firebase.sessions.FirebaseSessions instance; - field @NonNull public static final com.google.firebase.sessions.FirebaseSessions.Companion Companion; - } - - public static final class FirebaseSessions.Companion { - method @NonNull public com.google.firebase.sessions.FirebaseSessions getInstance(); - method @Deprecated @NonNull public com.google.firebase.sessions.FirebaseSessions getInstance(@NonNull com.google.firebase.FirebaseApp app); - property @NonNull public final com.google.firebase.sessions.FirebaseSessions instance; - } - -} - package com.google.firebase.sessions.api { public final class FirebaseSessionsDependencies { diff --git a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessions.kt b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessions.kt index 558f279a162..162bb4381ed 100644 --- a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessions.kt +++ b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/FirebaseSessions.kt @@ -27,9 +27,8 @@ import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -/** The [FirebaseSessions] API provides methods to register a [SessionSubscriber]. */ -class FirebaseSessions -internal constructor( +/** Responsible for initializing AQS */ +internal class FirebaseSessions( private val firebaseApp: FirebaseApp, private val settings: SessionsSettings, backgroundDispatcher: CoroutineContext, @@ -62,7 +61,6 @@ internal constructor( } } - /** Calculate whether we should sample events using [sessionSettings] data. */ companion object { private const val TAG = "FirebaseSessions" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 08b789013ed..e2c7a96d8ef 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -59,7 +59,6 @@ kotest-runner = { module = "io.kotest:kotest-runner-junit4-jvm", version.ref = " kotest-assertions = { module = "io.kotest:kotest-assertions-core-jvm", version.ref = "kotest" } kotest-property = { module = "io.kotest:kotest-property-jvm", version.ref = "kotest" } quickcheck = { module = "net.java:quickcheck", version.ref = "quickcheck" } -firebase-sessions = { group = "com.google.firebase", name = "firebase-sessions", version = "1.0.2" } [bundles] kotest = ["kotest-runner", "kotest-assertions", "kotest-property"]