in sdk/appcenter-crashes/src/main/java/com/microsoft/appcenter/crashes/Crashes.java [976:1065]
private synchronized void handleUserConfirmation(@UserConfirmationDef final int userConfirmation) {
post(new Runnable() {
@Override
public void run() {
/* If we don't send. */
if (userConfirmation == DONT_SEND) {
/* Clean up all pending error log and throwable files. */
for (Iterator<UUID> iterator = mUnprocessedErrorReports.keySet().iterator(); iterator.hasNext(); ) {
UUID id = iterator.next();
iterator.remove();
removeAllStoredErrorLogFiles(id);
}
ErrorLogHelper.cleanPendingMinidumps();
}
/* We send the crash. */
else {
/* Always send: we remember. */
if (userConfirmation == ALWAYS_SEND) {
SharedPreferencesManager.putBoolean(PREF_KEY_ALWAYS_SEND, true);
}
/* Send every pending report. */
Iterator<Map.Entry<UUID, ErrorLogReport>> unprocessedIterator = mUnprocessedErrorReports.entrySet().iterator();
while (unprocessedIterator.hasNext()) {
/* If native crash, send dump as attachment and remove the fake stack trace. */
File dumpFile = null;
ErrorAttachmentLog dumpAttachment = null;
Map.Entry<UUID, ErrorLogReport> unprocessedEntry = unprocessedIterator.next();
ErrorLogReport errorLogReport = unprocessedEntry.getValue();
if (errorLogReport.report.getDevice() != null && WRAPPER_SDK_NAME_NDK.equals(errorLogReport.report.getDevice().getWrapperSdkName())) {
/* Get minidump file path. */
Exception exception = errorLogReport.log.getException();
String minidumpFilePath = exception.getMinidumpFilePath();
/* Erase temporary field so that it's not sent to server. */
exception.setMinidumpFilePath(null);
/*
* Before SDK 2.1.0, the JSON was using the stacktrace field to hold file path on file storage.
* Try reading the old field.
*/
if (minidumpFilePath == null) {
minidumpFilePath = exception.getStackTrace();
/* Erase temporary field so that it's not sent to server. */
exception.setStackTrace(null);
}
/* It can be null when NativeException is thrown or there is already invalid stored data. */
if (minidumpFilePath != null) {
dumpFile = new File(minidumpFilePath);
byte[] logfileContents = FileManager.readBytes(dumpFile);
dumpAttachment = ErrorAttachmentLog.attachmentWithBinary(logfileContents, "minidump.dmp", "application/octet-stream");
} else {
AppCenterLog.warn(LOG_TAG, "NativeException found without minidump.");
}
}
/* Send report. */
mChannel.enqueue(errorLogReport.log, ERROR_GROUP, Flags.CRITICAL);
/* Send dump attachment and remove file. */
if (dumpAttachment != null) {
sendErrorAttachment(errorLogReport.log.getId(), Collections.singleton(dumpAttachment));
//noinspection ResultOfMethodCallIgnored
dumpFile.delete();
}
/* Get attachments from callback in automatic processing. */
if (mAutomaticProcessing) {
Iterable<ErrorAttachmentLog> attachments = mCrashesListener.getErrorAttachments(errorLogReport.report);
sendErrorAttachment(errorLogReport.log.getId(), attachments);
}
/* Clean up an error log file and map entry. */
unprocessedIterator.remove();
ErrorLogHelper.removeStoredErrorLogFile(unprocessedEntry.getKey());
}
}
}
});
}