|
32 | 32 | import com.google.firebase.analytics.connector.AnalyticsConnector;
|
33 | 33 | import com.google.firebase.crashlytics.internal.CrashlyticsNativeComponent;
|
34 | 34 | import com.google.firebase.crashlytics.internal.Logger;
|
| 35 | +import com.google.firebase.crashlytics.internal.NativeSessionFileProvider; |
35 | 36 | import com.google.firebase.crashlytics.internal.analytics.AnalyticsConnectorReceiver;
|
36 | 37 | import com.google.firebase.crashlytics.internal.analytics.AnalyticsReceiver;
|
37 | 38 | import com.google.firebase.crashlytics.internal.log.LogFileManager;
|
| 39 | +import com.google.firebase.crashlytics.internal.ndk.NativeFileUtils; |
38 | 40 | import com.google.firebase.crashlytics.internal.network.HttpRequestFactory;
|
39 | 41 | import com.google.firebase.crashlytics.internal.persistence.FileStore;
|
40 | 42 | import com.google.firebase.crashlytics.internal.proto.ClsFileOutputStream;
|
|
56 | 58 | import com.google.firebase.crashlytics.internal.stacktrace.StackTraceTrimmingStrategy;
|
57 | 59 | import com.google.firebase.crashlytics.internal.stacktrace.TrimmedThrowableData;
|
58 | 60 | import com.google.firebase.crashlytics.internal.unity.UnityVersionProvider;
|
59 |
| -import java.io.ByteArrayInputStream; |
60 | 61 | import java.io.File;
|
61 | 62 | import java.io.FileInputStream;
|
62 |
| -import java.io.FileNotFoundException; |
63 | 63 | import java.io.FileOutputStream;
|
64 | 64 | import java.io.FilenameFilter;
|
65 | 65 | import java.io.IOException;
|
66 | 66 | import java.io.InputStream;
|
| 67 | +import java.util.ArrayList; |
67 | 68 | import java.util.Arrays;
|
68 | 69 | import java.util.Collections;
|
69 | 70 | import java.util.Comparator;
|
@@ -1104,47 +1105,34 @@ public boolean accept(File dir, String filename) {
|
1104 | 1105 |
|
1105 | 1106 | private void finalizePreviousNativeSession(String previousSessionId) throws IOException {
|
1106 | 1107 | Logger.getLogger().d("Finalizing native report for session " + previousSessionId);
|
1107 |
| - final GzipFileNativeSessionProcessingStrategy strategy = |
1108 |
| - new GzipFileNativeSessionProcessingStrategy( |
1109 |
| - context, (sessionId) -> new File(getNativeSessionFilesDir(), sessionId)); |
1110 |
| - |
1111 |
| - final File filesDir = getFilesDir(); |
1112 |
| - final MetaDataStore metaDataStore = new MetaDataStore(filesDir); |
1113 |
| - final File userFile = metaDataStore.getUserDataFileForSession(previousSessionId); |
1114 |
| - final File keysFile = metaDataStore.getKeysFileForSession(previousSessionId); |
1115 |
| - |
| 1108 | + NativeSessionFileProvider sessionFileProvider = |
| 1109 | + nativeComponent.getSessionFileProvider(previousSessionId); |
| 1110 | + File minidumpFile = sessionFileProvider.getMinidumpFile(); |
| 1111 | + if (minidumpFile == null || !minidumpFile.exists()) { |
| 1112 | + Logger.getLogger().w("No minidump data found for session " + previousSessionId); |
| 1113 | + return; |
| 1114 | + } |
1116 | 1115 | final LogFileManager previousSessionLogManager =
|
1117 |
| - new LogFileManager(getContext(), logFileDirectoryProvider, previousSessionId); |
1118 |
| - byte[] logBytes = previousSessionLogManager.getBytesForLog(); |
| 1116 | + new LogFileManager(context, logFileDirectoryProvider, previousSessionId); |
| 1117 | + final File nativeSessionDirectory = new File(getNativeSessionFilesDir(), previousSessionId); |
1119 | 1118 |
|
1120 |
| - InputStream keysInput = null; |
1121 |
| - InputStream logsInput = null; |
1122 |
| - InputStream userInput = null; |
1123 |
| - try { |
1124 |
| - userInput = openFileStream(userFile); |
1125 |
| - keysInput = openFileStream(keysFile); |
1126 |
| - if (logBytes != null && logBytes.length > 0) { |
1127 |
| - logsInput = new ByteArrayInputStream(logBytes); |
1128 |
| - } |
1129 |
| - strategy.processNativeSession( |
1130 |
| - nativeComponent, previousSessionId, keysInput, logsInput, userInput); |
1131 |
| - } finally { |
1132 |
| - CommonUtils.closeQuietly(keysInput); |
1133 |
| - CommonUtils.closeQuietly(logsInput); |
1134 |
| - CommonUtils.closeQuietly(userInput); |
| 1119 | + if (!nativeSessionDirectory.mkdirs()) { |
| 1120 | + Logger.getLogger().d("Couldn't create native sessions directory"); |
| 1121 | + return; |
1135 | 1122 | }
|
1136 | 1123 |
|
1137 |
| - previousSessionLogManager.clearLog(); |
1138 |
| - } |
| 1124 | + List<NativeSessionFile> nativeSessionFiles = |
| 1125 | + getNativeSessionFiles( |
| 1126 | + sessionFileProvider, |
| 1127 | + previousSessionId, |
| 1128 | + getContext(), |
| 1129 | + getFilesDir(), |
| 1130 | + previousSessionLogManager.getBytesForLog()); |
1139 | 1131 |
|
1140 |
| - private static FileInputStream openFileStream(File f) { |
1141 |
| - FileInputStream stream; |
1142 |
| - try { |
1143 |
| - stream = new FileInputStream(f); |
1144 |
| - } catch (FileNotFoundException fnf) { |
1145 |
| - stream = null; |
1146 |
| - } |
1147 |
| - return stream; |
| 1132 | + NativeSessionFileGzipper.processNativeSessions(nativeSessionDirectory, nativeSessionFiles); |
| 1133 | + reportingCoordinator.finalizeNativeEvent(nativeSessionFiles, previousSessionId); |
| 1134 | + |
| 1135 | + previousSessionLogManager.clearLog(); |
1148 | 1136 | }
|
1149 | 1137 |
|
1150 | 1138 | /** Removes dashes in the Crashlytics session identifier to conform to Firebase constraints. */
|
@@ -1860,6 +1848,42 @@ public void run() {
|
1860 | 1848 | }
|
1861 | 1849 | }
|
1862 | 1850 |
|
| 1851 | + static List<NativeSessionFile> getNativeSessionFiles( |
| 1852 | + NativeSessionFileProvider fileProvider, |
| 1853 | + String previousSessionId, |
| 1854 | + Context context, |
| 1855 | + File filesDir, |
| 1856 | + byte[] logBytes) { |
| 1857 | + |
| 1858 | + final MetaDataStore metaDataStore = new MetaDataStore(filesDir); |
| 1859 | + final File userFile = metaDataStore.getUserDataFileForSession(previousSessionId); |
| 1860 | + final File keysFile = metaDataStore.getKeysFileForSession(previousSessionId); |
| 1861 | + |
| 1862 | + byte[] binaryImageBytes = null; |
| 1863 | + try { |
| 1864 | + binaryImageBytes = |
| 1865 | + NativeFileUtils.binaryImagesJsonFromMapsFile(fileProvider.getBinaryImagesFile(), context); |
| 1866 | + } catch (IOException e) { |
| 1867 | + // Keep processing, we'll add an empty binaryImages object. |
| 1868 | + } |
| 1869 | + |
| 1870 | + List<NativeSessionFile> nativeSessionFiles = new ArrayList<>(); |
| 1871 | + nativeSessionFiles.add(new BytesBackedNativeSessionFile("logs", logBytes)); |
| 1872 | + nativeSessionFiles.add(new BytesBackedNativeSessionFile("binaryImages", binaryImageBytes)); |
| 1873 | + nativeSessionFiles.add( |
| 1874 | + new FileBackedNativeSessionFile("metadata", fileProvider.getMetadataFile())); |
| 1875 | + nativeSessionFiles.add( |
| 1876 | + new FileBackedNativeSessionFile("session", fileProvider.getSessionFile())); |
| 1877 | + nativeSessionFiles.add(new FileBackedNativeSessionFile("app", fileProvider.getAppFile())); |
| 1878 | + nativeSessionFiles.add(new FileBackedNativeSessionFile("device", fileProvider.getDeviceFile())); |
| 1879 | + nativeSessionFiles.add(new FileBackedNativeSessionFile("os", fileProvider.getOsFile())); |
| 1880 | + nativeSessionFiles.add( |
| 1881 | + new FileBackedNativeSessionFile("minidump", fileProvider.getMinidumpFile())); |
| 1882 | + nativeSessionFiles.add(new FileBackedNativeSessionFile("user", userFile)); |
| 1883 | + nativeSessionFiles.add(new FileBackedNativeSessionFile("keys", keysFile)); |
| 1884 | + return nativeSessionFiles; |
| 1885 | + } |
| 1886 | + |
1863 | 1887 | private static final class LogFileDirectoryProvider implements LogFileManager.DirectoryProvider {
|
1864 | 1888 |
|
1865 | 1889 | private static final String LOG_FILES_DIR = "log-files";
|
|
0 commit comments