Initial import of ADIF API reverse-engineering toolkit

This commit is contained in:
2025-12-16 08:37:56 +01:00
commit 60388529c1
11486 changed files with 1086536 additions and 0 deletions

View File

@@ -0,0 +1,340 @@
package com.google.firebase.crashlytics.internal.persistence;
import C.w;
import L.b;
import N2.a;
import com.google.firebase.crashlytics.internal.Logger;
import com.google.firebase.crashlytics.internal.common.CrashlyticsAppQualitySessionsSubscriber;
import com.google.firebase.crashlytics.internal.common.CrashlyticsReportWithSessionId;
import com.google.firebase.crashlytics.internal.metadata.UserMetadata;
import com.google.firebase.crashlytics.internal.model.CrashlyticsReport;
import com.google.firebase.crashlytics.internal.model.serialization.CrashlyticsReportJsonTransform;
import com.google.firebase.crashlytics.internal.settings.SettingsProvider;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
/* loaded from: classes3.dex */
public class CrashlyticsReportPersistence {
private static final String EVENT_COUNTER_FORMAT = "%010d";
private static final int EVENT_COUNTER_WIDTH = 10;
private static final String EVENT_FILE_NAME_PREFIX = "event";
private static final int MAX_OPEN_SESSIONS = 8;
private static final String NORMAL_EVENT_SUFFIX = "";
private static final String PRIORITY_EVENT_SUFFIX = "_";
private static final String REPORT_FILE_NAME = "report";
private static final String SESSION_START_TIMESTAMP_FILE_NAME = "start-time";
private final AtomicInteger eventCounter = new AtomicInteger(0);
private final FileStore fileStore;
private final CrashlyticsAppQualitySessionsSubscriber sessionsSubscriber;
private final SettingsProvider settingsProvider;
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final int EVENT_NAME_LENGTH = 15;
private static final CrashlyticsReportJsonTransform TRANSFORM = new CrashlyticsReportJsonTransform();
private static final Comparator<? super File> LATEST_SESSION_ID_FIRST_COMPARATOR = new b(2);
private static final FilenameFilter EVENT_FILE_FILTER = new a(0);
public CrashlyticsReportPersistence(FileStore fileStore, SettingsProvider settingsProvider, CrashlyticsAppQualitySessionsSubscriber crashlyticsAppQualitySessionsSubscriber) {
this.fileStore = fileStore;
this.settingsProvider = settingsProvider;
this.sessionsSubscriber = crashlyticsAppQualitySessionsSubscriber;
}
private SortedSet<String> capAndGetOpenSessions(String str) {
this.fileStore.cleanupPreviousFileSystems();
SortedSet<String> openSessionIds = getOpenSessionIds();
if (str != null) {
openSessionIds.remove(str);
}
if (openSessionIds.size() > 8) {
while (openSessionIds.size() > 8) {
String last = openSessionIds.last();
Logger.getLogger().d("Removing session over cap: " + last);
this.fileStore.deleteSessionFiles(last);
openSessionIds.remove(last);
}
}
return openSessionIds;
}
private static int capFilesCount(List<File> list, int i) {
int size = list.size();
for (File file : list) {
if (size <= i) {
break;
}
FileStore.recursiveDelete(file);
size--;
}
return size;
}
private void capFinalizedReports() {
int i = this.settingsProvider.getSettingsSync().sessionData.maxCompleteSessionsCount;
List<File> allFinalizedReportFiles = getAllFinalizedReportFiles();
int size = allFinalizedReportFiles.size();
if (size <= i) {
return;
}
Iterator<File> it = allFinalizedReportFiles.subList(i, size).iterator();
while (it.hasNext()) {
it.next().delete();
}
}
private static long convertTimestampFromSecondsToMs(long j4) {
return j4 * 1000;
}
private void deleteFiles(List<File> list) {
Iterator<File> it = list.iterator();
while (it.hasNext()) {
it.next().delete();
}
}
private static String generateEventFilename(int i, boolean z3) {
return w.o(EVENT_FILE_NAME_PREFIX, String.format(Locale.US, EVENT_COUNTER_FORMAT, Integer.valueOf(i)), z3 ? PRIORITY_EVENT_SUFFIX : "");
}
private List<File> getAllFinalizedReportFiles() {
ArrayList arrayList = new ArrayList();
arrayList.addAll(this.fileStore.getPriorityReports());
arrayList.addAll(this.fileStore.getNativeReports());
Comparator<? super File> comparator = LATEST_SESSION_ID_FIRST_COMPARATOR;
Collections.sort(arrayList, comparator);
List<File> reports = this.fileStore.getReports();
Collections.sort(reports, comparator);
arrayList.addAll(reports);
return arrayList;
}
private static String getEventNameWithoutPriority(String str) {
return str.substring(0, EVENT_NAME_LENGTH);
}
private static boolean isHighPriorityEventFile(String str) {
return str.startsWith(EVENT_FILE_NAME_PREFIX) && str.endsWith(PRIORITY_EVENT_SUFFIX);
}
public static boolean isNormalPriorityEventFile(File file, String str) {
return str.startsWith(EVENT_FILE_NAME_PREFIX) && !str.endsWith(PRIORITY_EVENT_SUFFIX);
}
public static /* synthetic */ int lambda$static$0(File file, File file2) {
return file2.getName().compareTo(file.getName());
}
public static /* synthetic */ boolean lambda$static$1(File file, String str) {
return str.startsWith(EVENT_FILE_NAME_PREFIX);
}
public static int oldestEventFileFirst(File file, File file2) {
return getEventNameWithoutPriority(file.getName()).compareTo(getEventNameWithoutPriority(file2.getName()));
}
private static String readTextFile(File file) throws IOException {
byte[] bArr = new byte[8192];
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
FileInputStream fileInputStream = new FileInputStream(file);
while (true) {
try {
int read = fileInputStream.read(bArr);
if (read <= 0) {
String str = new String(byteArrayOutputStream.toByteArray(), UTF_8);
fileInputStream.close();
return str;
}
byteArrayOutputStream.write(bArr, 0, read);
} catch (Throwable th) {
try {
fileInputStream.close();
} catch (Throwable th2) {
th.addSuppressed(th2);
}
throw th;
}
}
}
private void synthesizeNativeReportFile(File file, CrashlyticsReport.FilesPayload filesPayload, String str, CrashlyticsReport.ApplicationExitInfo applicationExitInfo) {
String appQualitySessionId = this.sessionsSubscriber.getAppQualitySessionId(str);
try {
CrashlyticsReportJsonTransform crashlyticsReportJsonTransform = TRANSFORM;
writeTextFile(this.fileStore.getNativeReport(str), crashlyticsReportJsonTransform.reportToJson(crashlyticsReportJsonTransform.reportFromJson(readTextFile(file)).withNdkPayload(filesPayload).withApplicationExitInfo(applicationExitInfo).withAppQualitySessionId(appQualitySessionId)));
} catch (IOException e4) {
Logger.getLogger().w("Could not synthesize final native report file for " + file, e4);
}
}
private void synthesizeReport(String str, long j4) {
boolean z3;
List<File> sessionFiles = this.fileStore.getSessionFiles(str, EVENT_FILE_FILTER);
if (sessionFiles.isEmpty()) {
Logger.getLogger().v("Session " + str + " has no events.");
return;
}
Collections.sort(sessionFiles);
ArrayList arrayList = new ArrayList();
loop0: while (true) {
z3 = false;
for (File file : sessionFiles) {
try {
arrayList.add(TRANSFORM.eventFromJson(readTextFile(file)));
} catch (IOException e4) {
Logger.getLogger().w("Could not add event to report for " + file, e4);
}
if (z3 || isHighPriorityEventFile(file.getName())) {
z3 = true;
}
}
}
if (!arrayList.isEmpty()) {
synthesizeReportFile(this.fileStore.getSessionFile(str, REPORT_FILE_NAME), arrayList, j4, z3, UserMetadata.readUserId(str, this.fileStore), this.sessionsSubscriber.getAppQualitySessionId(str));
} else {
Logger.getLogger().w("Could not parse event files for session " + str);
}
}
private void synthesizeReportFile(File file, List<CrashlyticsReport.Session.Event> list, long j4, boolean z3, String str, String str2) {
try {
CrashlyticsReportJsonTransform crashlyticsReportJsonTransform = TRANSFORM;
CrashlyticsReport withEvents = crashlyticsReportJsonTransform.reportFromJson(readTextFile(file)).withSessionEndFields(j4, z3, str).withAppQualitySessionId(str2).withEvents(list);
CrashlyticsReport.Session session = withEvents.getSession();
if (session == null) {
return;
}
Logger.getLogger().d("appQualitySessionId: " + str2);
writeTextFile(z3 ? this.fileStore.getPriorityReport(session.getIdentifier()) : this.fileStore.getReport(session.getIdentifier()), crashlyticsReportJsonTransform.reportToJson(withEvents));
} catch (IOException e4) {
Logger.getLogger().w("Could not synthesize final report file for " + file, e4);
}
}
private int trimEvents(String str, int i) {
List<File> sessionFiles = this.fileStore.getSessionFiles(str, new a(1));
Collections.sort(sessionFiles, new b(3));
return capFilesCount(sessionFiles, i);
}
private static void writeTextFile(File file, String str) throws IOException {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file), UTF_8);
try {
outputStreamWriter.write(str);
outputStreamWriter.close();
} catch (Throwable th) {
try {
outputStreamWriter.close();
} catch (Throwable th2) {
th.addSuppressed(th2);
}
throw th;
}
}
public void deleteAllReports() {
deleteFiles(this.fileStore.getReports());
deleteFiles(this.fileStore.getPriorityReports());
deleteFiles(this.fileStore.getNativeReports());
}
public void finalizeReports(String str, long j4) {
for (String str2 : capAndGetOpenSessions(str)) {
Logger.getLogger().v("Finalizing report for session " + str2);
synthesizeReport(str2, j4);
this.fileStore.deleteSessionFiles(str2);
}
capFinalizedReports();
}
public void finalizeSessionWithNativeEvent(String str, CrashlyticsReport.FilesPayload filesPayload, CrashlyticsReport.ApplicationExitInfo applicationExitInfo) {
File sessionFile = this.fileStore.getSessionFile(str, REPORT_FILE_NAME);
Logger.getLogger().d("Writing native session report for " + str + " to file: " + sessionFile);
synthesizeNativeReportFile(sessionFile, filesPayload, str, applicationExitInfo);
}
public SortedSet<String> getOpenSessionIds() {
return new TreeSet(this.fileStore.getAllOpenSessionIds()).descendingSet();
}
public long getStartTimestampMillis(String str) {
return this.fileStore.getSessionFile(str, SESSION_START_TIMESTAMP_FILE_NAME).lastModified();
}
public boolean hasFinalizedReports() {
return (this.fileStore.getReports().isEmpty() && this.fileStore.getPriorityReports().isEmpty() && this.fileStore.getNativeReports().isEmpty()) ? false : true;
}
public List<CrashlyticsReportWithSessionId> loadFinalizedReports() {
List<File> allFinalizedReportFiles = getAllFinalizedReportFiles();
ArrayList arrayList = new ArrayList();
for (File file : allFinalizedReportFiles) {
try {
arrayList.add(CrashlyticsReportWithSessionId.create(TRANSFORM.reportFromJson(readTextFile(file)), file.getName(), file));
} catch (IOException e4) {
Logger.getLogger().w("Could not load report file " + file + "; deleting", e4);
file.delete();
}
}
return arrayList;
}
public void persistEvent(CrashlyticsReport.Session.Event event, String str) {
persistEvent(event, str, false);
}
public void persistReport(CrashlyticsReport crashlyticsReport) {
CrashlyticsReport.Session session = crashlyticsReport.getSession();
if (session == null) {
Logger.getLogger().d("Could not get session for report");
return;
}
String identifier = session.getIdentifier();
try {
writeTextFile(this.fileStore.getSessionFile(identifier, REPORT_FILE_NAME), TRANSFORM.reportToJson(crashlyticsReport));
writeTextFile(this.fileStore.getSessionFile(identifier, SESSION_START_TIMESTAMP_FILE_NAME), "", session.getStartedAt());
} catch (IOException e4) {
Logger.getLogger().d("Could not persist report for session " + identifier, e4);
}
}
public void persistEvent(CrashlyticsReport.Session.Event event, String str, boolean z3) {
int i = this.settingsProvider.getSettingsSync().sessionData.maxCustomExceptionEvents;
try {
writeTextFile(this.fileStore.getSessionFile(str, generateEventFilename(this.eventCounter.getAndIncrement(), z3)), TRANSFORM.eventToJson(event));
} catch (IOException e4) {
Logger.getLogger().w("Could not persist event for session " + str, e4);
}
trimEvents(str, i);
}
private static void writeTextFile(File file, String str, long j4) throws IOException {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file), UTF_8);
try {
outputStreamWriter.write(str);
file.setLastModified(convertTimestampFromSecondsToMs(j4));
outputStreamWriter.close();
} catch (Throwable th) {
try {
outputStreamWriter.close();
} catch (Throwable th2) {
th.addSuppressed(th2);
}
throw th;
}
}
}

View File

@@ -0,0 +1,167 @@
package com.google.firebase.crashlytics.internal.persistence;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import com.google.firebase.crashlytics.internal.Logger;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/* loaded from: classes3.dex */
public class FileStore {
private static final String CRASHLYTICS_PATH_V1 = ".com.google.firebase.crashlytics.files.v1";
private static final String CRASHLYTICS_PATH_V2 = ".com.google.firebase.crashlytics.files.v2";
private static final String NATIVE_REPORTS_PATH = "native-reports";
private static final String NATIVE_SESSION_SUBDIR = "native";
private static final String PRIORITY_REPORTS_PATH = "priority-reports";
private static final String REPORTS_PATH = "reports";
private static final String SESSIONS_PATH = "open-sessions";
private final File crashlyticsDir;
private final File filesDir;
private final File nativeReportsDir;
private final File priorityReportsDir;
private final File reportsDir;
private final File sessionsDir;
public FileStore(Context context) {
String str;
File filesDir = context.getFilesDir();
this.filesDir = filesDir;
if (useV2FileSystem()) {
str = CRASHLYTICS_PATH_V2 + File.pathSeparator + sanitizeName(Application.getProcessName());
} else {
str = CRASHLYTICS_PATH_V1;
}
File prepareBaseDir = prepareBaseDir(new File(filesDir, str));
this.crashlyticsDir = prepareBaseDir;
this.sessionsDir = prepareBaseDir(new File(prepareBaseDir, SESSIONS_PATH));
this.reportsDir = prepareBaseDir(new File(prepareBaseDir, REPORTS_PATH));
this.priorityReportsDir = prepareBaseDir(new File(prepareBaseDir, PRIORITY_REPORTS_PATH));
this.nativeReportsDir = prepareBaseDir(new File(prepareBaseDir, NATIVE_REPORTS_PATH));
}
private void cleanupDir(File file) {
if (file.exists() && recursiveDelete(file)) {
Logger.getLogger().d("Deleted previous Crashlytics file system: " + file.getPath());
}
}
private File getSessionDir(String str) {
return prepareDir(new File(this.sessionsDir, str));
}
private static synchronized File prepareBaseDir(File file) {
synchronized (FileStore.class) {
try {
if (file.exists()) {
if (file.isDirectory()) {
return file;
}
Logger.getLogger().d("Unexpected non-directory file: " + file + "; deleting file and creating new directory.");
file.delete();
}
if (!file.mkdirs()) {
Logger.getLogger().e("Could not create Crashlytics-specific directory: " + file);
}
return file;
} catch (Throwable th) {
throw th;
}
}
}
private static File prepareDir(File file) {
file.mkdirs();
return file;
}
public static boolean recursiveDelete(File file) {
File[] listFiles = file.listFiles();
if (listFiles != null) {
for (File file2 : listFiles) {
recursiveDelete(file2);
}
}
return file.delete();
}
private static <T> List<T> safeArrayToList(T[] tArr) {
return tArr == null ? Collections.EMPTY_LIST : Arrays.asList(tArr);
}
public static String sanitizeName(String str) {
return str.replaceAll("[^a-zA-Z0-9.]", "_");
}
@SuppressLint({"AnnotateVersionCheck"})
private static boolean useV2FileSystem() {
return true;
}
public void cleanupPreviousFileSystems() {
cleanupDir(new File(this.filesDir, ".com.google.firebase.crashlytics"));
cleanupDir(new File(this.filesDir, ".com.google.firebase.crashlytics-ndk"));
if (useV2FileSystem()) {
cleanupDir(new File(this.filesDir, CRASHLYTICS_PATH_V1));
}
}
public void deleteAllCrashlyticsFiles() {
recursiveDelete(this.crashlyticsDir);
}
public boolean deleteSessionFiles(String str) {
return recursiveDelete(new File(this.sessionsDir, str));
}
public List<String> getAllOpenSessionIds() {
return safeArrayToList(this.sessionsDir.list());
}
public File getCommonFile(String str) {
return new File(this.crashlyticsDir, str);
}
public List<File> getCommonFiles(FilenameFilter filenameFilter) {
return safeArrayToList(this.crashlyticsDir.listFiles(filenameFilter));
}
public File getNativeReport(String str) {
return new File(this.nativeReportsDir, str);
}
public List<File> getNativeReports() {
return safeArrayToList(this.nativeReportsDir.listFiles());
}
public File getNativeSessionDir(String str) {
return prepareDir(new File(getSessionDir(str), NATIVE_SESSION_SUBDIR));
}
public File getPriorityReport(String str) {
return new File(this.priorityReportsDir, str);
}
public List<File> getPriorityReports() {
return safeArrayToList(this.priorityReportsDir.listFiles());
}
public File getReport(String str) {
return new File(this.reportsDir, str);
}
public List<File> getReports() {
return safeArrayToList(this.reportsDir.listFiles());
}
public File getSessionFile(String str, String str2) {
return new File(getSessionDir(str), str2);
}
public List<File> getSessionFiles(String str, FilenameFilter filenameFilter) {
return safeArrayToList(getSessionDir(str).listFiles(filenameFilter));
}
}