diff --git a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/CrashlyticsController.java b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/CrashlyticsController.java index 37202c170e8..cb347b3fc69 100644 --- a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/CrashlyticsController.java +++ b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/CrashlyticsController.java @@ -895,7 +895,15 @@ private void writeApplicationExitInfoEventIfRelevant(String sessionId) { // Passes the latest applicationExitInfo to ReportCoordinator, which persists it if it // happened during the session. if (applicationExitInfoList.size() != 0) { - reportingCoordinator.persistAppExitInfoEvent(sessionId, applicationExitInfoList.get(0)); + final LogFileManager relevantSessionLogManager = + new LogFileManager(context, logFileDirectoryProvider, sessionId); + final UserMetadata relevantUserMetadata = new UserMetadata(); + relevantUserMetadata.setCustomKeys(new MetaDataStore(getFilesDir()).readKeyData(sessionId)); + reportingCoordinator.persistAppExitInfoEvent( + sessionId, + applicationExitInfoList.get(0), + relevantSessionLogManager, + relevantUserMetadata); } } } diff --git a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/SessionReportingCoordinator.java b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/SessionReportingCoordinator.java index abbc354f3a3..2d65a89760b 100644 --- a/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/SessionReportingCoordinator.java +++ b/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/SessionReportingCoordinator.java @@ -134,7 +134,11 @@ public void persistNonFatalEvent( } @RequiresApi(api = Build.VERSION_CODES.R) - public void persistAppExitInfoEvent(String sessionId, ApplicationExitInfo applicationExitInfo) { + public void persistAppExitInfoEvent( + String sessionId, + ApplicationExitInfo applicationExitInfo, + LogFileManager logFileManagerForSession, + UserMetadata userMetadataForSession) { long sessionStartTime = reportPersistence.getStartTimestampMillis(sessionId); // ApplicationExitInfo did not occur during the session. if (applicationExitInfo.getTimestamp() < sessionStartTime) { @@ -150,7 +154,11 @@ public void persistAppExitInfoEvent(String sessionId, ApplicationExitInfo applic dataCapture.captureAnrEventData(convertApplicationExitInfo(applicationExitInfo)); Logger.getLogger().d("Persisting anr for session " + sessionId); - reportPersistence.persistEvent(addLogsAndCustomKeysToEvent(capturedEvent), sessionId, true); + reportPersistence.persistEvent( + addLogsAndCustomKeysToEvent( + capturedEvent, logFileManagerForSession, userMetadataForSession), + sessionId, + true); } public void finalizeSessionWithNativeEvent( @@ -218,6 +226,13 @@ public Task sendReports(@NonNull Executor reportSendCompleteExecutor) { private CrashlyticsReport.Session.Event addLogsAndCustomKeysToEvent( CrashlyticsReport.Session.Event capturedEvent) { + return addLogsAndCustomKeysToEvent(capturedEvent, logFileManager, reportMetadata); + } + + private CrashlyticsReport.Session.Event addLogsAndCustomKeysToEvent( + CrashlyticsReport.Session.Event capturedEvent, + LogFileManager logFileManager, + UserMetadata reportMetadata) { final CrashlyticsReport.Session.Event.Builder eventBuilder = capturedEvent.toBuilder(); final String content = logFileManager.getLogString(); diff --git a/firebase-crashlytics/src/test/java/com/google/firebase/crashlytics/internal/common/CrashlyticsControllerRobolectricTest.java b/firebase-crashlytics/src/test/java/com/google/firebase/crashlytics/internal/common/CrashlyticsControllerRobolectricTest.java index f389e6afc32..0624f2d89c7 100644 --- a/firebase-crashlytics/src/test/java/com/google/firebase/crashlytics/internal/common/CrashlyticsControllerRobolectricTest.java +++ b/firebase-crashlytics/src/test/java/com/google/firebase/crashlytics/internal/common/CrashlyticsControllerRobolectricTest.java @@ -29,6 +29,7 @@ import androidx.test.core.app.ApplicationProvider; import com.google.firebase.crashlytics.internal.ProviderProxyNativeComponent; import com.google.firebase.crashlytics.internal.analytics.AnalyticsEventLogger; +import com.google.firebase.crashlytics.internal.log.LogFileManager; import com.google.firebase.crashlytics.internal.persistence.FileStore; import com.google.firebase.crashlytics.internal.settings.SettingsDataProvider; import com.google.firebase.crashlytics.internal.settings.model.FeaturesSettingsData; @@ -54,6 +55,7 @@ public class CrashlyticsControllerRobolectricTest { @Mock private File mockFilesDirectory; @Mock private SessionReportingCoordinator mockSessionReportingCoordinator; @Mock private DataCollectionArbiter mockDataCollectionArbiter; + @Mock private LogFileManager.DirectoryProvider mockLogFileDirecotryProvider; @Before public void setUp() { @@ -72,7 +74,9 @@ public void testDoCloseSession_enabledAnrs_doesNotPersistsAppExitInfoIfItDoesntE controller.doCloseSessions(mockSettingsDataProvider); // Since we haven't added any app exit info to the shadow activity manager, there won't exist a // single app exit info, and so this method won't be called. - verify(mockSessionReportingCoordinator, never()).persistAppExitInfoEvent(eq(sessionId), any()); + verify(mockSessionReportingCoordinator, never()) + .persistAppExitInfoEvent( + eq(sessionId), any(), any(LogFileManager.class), any(UserMetadata.class)); } @Test @@ -86,7 +90,11 @@ public void testDoCloseSession_enabledAnrs_persistsAppExitInfoIfItExists() { mockSettingsData(true); controller.doCloseSessions(mockSettingsDataProvider); verify(mockSessionReportingCoordinator) - .persistAppExitInfoEvent(eq(sessionId), eq(testApplicationExitInfo)); + .persistAppExitInfoEvent( + eq(sessionId), + eq(testApplicationExitInfo), + any(LogFileManager.class), + any(UserMetadata.class)); } @Test @@ -98,7 +106,9 @@ public void testDoCloseSession_disabledAnrs_doesNotPersistsAppExitInfo() { .thenReturn(Collections.singletonList(sessionId)); mockSettingsData(false); controller.doCloseSessions(mockSettingsDataProvider); - verify(mockSessionReportingCoordinator, never()).persistAppExitInfoEvent(eq(sessionId), any()); + verify(mockSessionReportingCoordinator, never()) + .persistAppExitInfoEvent( + eq(sessionId), any(), any(LogFileManager.class), any(UserMetadata.class)); } private void mockSettingsData(boolean collectAnrs) { @@ -130,7 +140,7 @@ private CrashlyticsController createController() { appData, null, null, - null, + mockLogFileDirecotryProvider, mockSessionReportingCoordinator, new ProviderProxyNativeComponent(() -> null), mock(AnalyticsEventLogger.class)); diff --git a/firebase-crashlytics/src/test/java/com/google/firebase/crashlytics/internal/common/SessionReportingCoordinatorRobolectricTest.java b/firebase-crashlytics/src/test/java/com/google/firebase/crashlytics/internal/common/SessionReportingCoordinatorRobolectricTest.java index d9de7d64232..8aa09151308 100644 --- a/firebase-crashlytics/src/test/java/com/google/firebase/crashlytics/internal/common/SessionReportingCoordinatorRobolectricTest.java +++ b/firebase-crashlytics/src/test/java/com/google/firebase/crashlytics/internal/common/SessionReportingCoordinatorRobolectricTest.java @@ -53,6 +53,8 @@ public class SessionReportingCoordinatorRobolectricTest { @Mock private CrashlyticsReport.Session.Event.Builder mockEventBuilder; @Mock private CrashlyticsReport.Session.Event.Application mockEventApp; @Mock private CrashlyticsReport.Session.Event.Application.Builder mockEventAppBuilder; + @Mock private LogFileManager mockLogFileManager; + @Mock UserMetadata mockUserMetadata; private SessionReportingCoordinator reportingCoordinator; @@ -78,7 +80,8 @@ public void testAppExitInfoEvent_persistIfAnrWithinSession() { ApplicationExitInfo testApplicationExitInfo = addAppExitInfo(ApplicationExitInfo.REASON_ANR); reportingCoordinator.onBeginSession(sessionId, sessionStartTimestamp); - reportingCoordinator.persistAppExitInfoEvent(sessionId, testApplicationExitInfo); + reportingCoordinator.persistAppExitInfoEvent( + sessionId, testApplicationExitInfo, mockLogFileManager, mockUserMetadata); verify(dataCapture).captureAnrEventData(convertApplicationExitInfo(testApplicationExitInfo)); verify(reportPersistence).persistEvent(any(), eq(sessionId), eq(true)); @@ -95,7 +98,8 @@ public void testAppExitInfoEvent_notPersistIfAnrBeforeSession() { ApplicationExitInfo testApplicationExitInfo = addAppExitInfo(ApplicationExitInfo.REASON_ANR); reportingCoordinator.onBeginSession(sessionId, sessionStartTimestamp); - reportingCoordinator.persistAppExitInfoEvent(sessionId, testApplicationExitInfo); + reportingCoordinator.persistAppExitInfoEvent( + sessionId, testApplicationExitInfo, mockLogFileManager, mockUserMetadata); verify(dataCapture, never()) .captureAnrEventData(convertApplicationExitInfo(testApplicationExitInfo)); @@ -114,7 +118,8 @@ public void testAppExitInfoEvent_notPersistIfAppExitInfoNotAnrButWithinSession() addAppExitInfo(ApplicationExitInfo.REASON_DEPENDENCY_DIED); reportingCoordinator.onBeginSession(sessionId, sessionStartTimestamp); - reportingCoordinator.persistAppExitInfoEvent(sessionId, testApplicationExitInfo); + reportingCoordinator.persistAppExitInfoEvent( + sessionId, testApplicationExitInfo, mockLogFileManager, mockUserMetadata); verify(dataCapture, never()) .captureAnrEventData(convertApplicationExitInfo(testApplicationExitInfo));