2525import com .google .android .gms .tasks .Tasks ;
2626import com .google .firebase .crashlytics .internal .Logger ;
2727import com .google .firebase .crashlytics .internal .concurrency .CrashlyticsWorkers ;
28+ import com .google .firebase .crashlytics .internal .metadata .EventMetadata ;
2829import com .google .firebase .crashlytics .internal .metadata .LogFileManager ;
2930import com .google .firebase .crashlytics .internal .metadata .UserMetadata ;
3031import com .google .firebase .crashlytics .internal .model .CrashlyticsReport ;
4243import java .nio .charset .StandardCharsets ;
4344import java .util .ArrayList ;
4445import java .util .Collections ;
46+ import java .util .HashMap ;
4547import java .util .List ;
4648import java .util .Map ;
4749import java .util .SortedSet ;
@@ -124,13 +126,14 @@ public void onBeginSession(@NonNull String sessionId, long timestampSeconds) {
124126 public void persistFatalEvent (
125127 @ NonNull Throwable event , @ NonNull Thread thread , @ NonNull String sessionId , long timestamp ) {
126128 Logger .getLogger ().v ("Persisting fatal event for session " + sessionId );
127- persistEvent (event , thread , sessionId , EVENT_TYPE_CRASH , timestamp , true );
129+ EventMetadata eventMetadata = new EventMetadata (sessionId , timestamp , Map .of ());
130+ persistEvent (event , thread , EVENT_TYPE_CRASH , eventMetadata , true );
128131 }
129132
130133 public void persistNonFatalEvent (
131- @ NonNull Throwable event , @ NonNull Thread thread , @ NonNull String sessionId , long timestamp ) {
132- Logger .getLogger ().v ("Persisting non-fatal event for session " + sessionId );
133- persistEvent (event , thread , sessionId , EVENT_TYPE_LOGGED , timestamp , false );
134+ @ NonNull Throwable event , @ NonNull Thread thread , @ NonNull EventMetadata eventMetadata ) {
135+ Logger .getLogger ().v ("Persisting non-fatal event for session " + eventMetadata . getSessionId () );
136+ persistEvent (event , thread , EVENT_TYPE_LOGGED , eventMetadata , false );
134137 }
135138
136139 @ RequiresApi (api = Build .VERSION_CODES .R )
@@ -253,23 +256,20 @@ private CrashlyticsReportWithSessionId ensureHasFid(CrashlyticsReportWithSession
253256 }
254257
255258 private CrashlyticsReport .Session .Event addMetaDataToEvent (
256- CrashlyticsReport .Session .Event capturedEvent ) {
259+ CrashlyticsReport .Session .Event capturedEvent , Map < String , String > eventCustomKeys ) {
257260 CrashlyticsReport .Session .Event eventWithLogsAndCustomKeys =
258- addLogsAndCustomKeysToEvent (capturedEvent , logFileManager , reportMetadata );
261+ addLogsCustomKeysAndEventKeysToEvent (
262+ capturedEvent , logFileManager , reportMetadata , eventCustomKeys );
259263 CrashlyticsReport .Session .Event eventWithRollouts =
260264 addRolloutsStateToEvent (eventWithLogsAndCustomKeys , reportMetadata );
261265 return eventWithRollouts ;
262266 }
263267
264- private CrashlyticsReport .Session .Event addLogsAndCustomKeysToEvent (
265- CrashlyticsReport .Session .Event capturedEvent ) {
266- return addLogsAndCustomKeysToEvent (capturedEvent , logFileManager , reportMetadata );
267- }
268-
269- private CrashlyticsReport .Session .Event addLogsAndCustomKeysToEvent (
268+ private CrashlyticsReport .Session .Event addLogsCustomKeysAndEventKeysToEvent (
270269 CrashlyticsReport .Session .Event capturedEvent ,
271270 LogFileManager logFileManager ,
272- UserMetadata reportMetadata ) {
271+ UserMetadata reportMetadata ,
272+ Map <String , String > eventKeys ) {
273273 final CrashlyticsReport .Session .Event .Builder eventBuilder = capturedEvent .toBuilder ();
274274 final String content = logFileManager .getLogString ();
275275
@@ -283,12 +283,18 @@ private CrashlyticsReport.Session.Event addLogsAndCustomKeysToEvent(
283283 // TODO: Put this back once support for reports endpoint is removed.
284284 // logFileManager.clearLog(); // Clear log to prepare for next event.
285285
286+ // Merges the app level custom keys, with the event specific custom keys.
287+ Map <String , String > customKeysMergedWithEventKeys =
288+ new HashMap <>(reportMetadata .getCustomKeys ());
289+ customKeysMergedWithEventKeys .putAll (eventKeys );
290+
286291 final List <CustomAttribute > sortedCustomAttributes =
287- getSortedCustomAttributes (reportMetadata . getCustomKeys () );
292+ getSortedCustomAttributes (customKeysMergedWithEventKeys );
288293 final List <CustomAttribute > sortedInternalKeys =
289294 getSortedCustomAttributes (reportMetadata .getInternalKeys ());
290295
291296 if (!sortedCustomAttributes .isEmpty () || !sortedInternalKeys .isEmpty ()) {
297+ // TODO(b/380072776): Change implementation to *not* override existing custom attributes.
292298 eventBuilder .setApp (
293299 capturedEvent .getApp ().toBuilder ()
294300 .setCustomAttributes (sortedCustomAttributes )
@@ -299,6 +305,14 @@ private CrashlyticsReport.Session.Event addLogsAndCustomKeysToEvent(
299305 return eventBuilder .build ();
300306 }
301307
308+ private CrashlyticsReport .Session .Event addLogsAndCustomKeysToEvent (
309+ CrashlyticsReport .Session .Event capturedEvent ,
310+ LogFileManager logFileManager ,
311+ UserMetadata reportMetadata ) {
312+ return addLogsCustomKeysAndEventKeysToEvent (
313+ capturedEvent , logFileManager , reportMetadata , Map .of ());
314+ }
315+
302316 private CrashlyticsReport .Session .Event addRolloutsStateToEvent (
303317 CrashlyticsReport .Session .Event capturedEvent , UserMetadata reportMetadata ) {
304318 List <CrashlyticsReport .Session .Event .RolloutAssignment > reportRolloutAssignments =
@@ -319,9 +333,8 @@ private CrashlyticsReport.Session.Event addRolloutsStateToEvent(
319333 private void persistEvent (
320334 @ NonNull Throwable event ,
321335 @ NonNull Thread thread ,
322- @ NonNull String sessionId ,
323336 @ NonNull String eventType ,
324- long timestamp ,
337+ @ NonNull EventMetadata eventMetadata ,
325338 boolean isFatal ) {
326339
327340 final boolean isHighPriority = eventType .equals (EVENT_TYPE_CRASH );
@@ -331,23 +344,25 @@ private void persistEvent(
331344 event ,
332345 thread ,
333346 eventType ,
334- timestamp ,
347+ eventMetadata . getTimestamp () ,
335348 EVENT_THREAD_IMPORTANCE ,
336349 MAX_CHAINED_EXCEPTION_DEPTH ,
337350 isFatal );
338- CrashlyticsReport .Session .Event finallizedEvent = addMetaDataToEvent (capturedEvent );
351+ CrashlyticsReport .Session .Event finallizedEvent =
352+ addMetaDataToEvent (capturedEvent , eventMetadata .getUserInfo ());
339353
340354 // Non-fatal, persistence write task we move to diskWriteWorker
341355 if (!isFatal ) {
342356 crashlyticsWorkers .diskWrite .submit (
343357 () -> {
344358 Logger .getLogger ().d ("disk worker: log non-fatal event to persistence" );
345- reportPersistence .persistEvent (finallizedEvent , sessionId , isHighPriority );
359+ reportPersistence .persistEvent (
360+ finallizedEvent , eventMetadata .getSessionId (), isHighPriority );
346361 });
347362 return ;
348363 }
349364
350- reportPersistence .persistEvent (finallizedEvent , sessionId , isHighPriority );
365+ reportPersistence .persistEvent (finallizedEvent , eventMetadata . getSessionId () , isHighPriority );
351366 }
352367
353368 private boolean onReportSendComplete (@ NonNull Task <CrashlyticsReportWithSessionId > task ) {
0 commit comments