diff --git a/sentry-android-ndk/CMakeLists.txt b/sentry-android-ndk/CMakeLists.txt index c9a0181935..de2915f8d2 100644 --- a/sentry-android-ndk/CMakeLists.txt +++ b/sentry-android-ndk/CMakeLists.txt @@ -7,6 +7,7 @@ add_library(sentry-android SHARED src/main/jni/sentry.c) # make sure that we build it as a shared lib instead of a static lib set(BUILD_SHARED_LIBS ON) set(SENTRY_BUILD_SHARED_LIBS ON) +set(SENTRY_BACKEND "breakpad") # Adding sentry-native submodule subdirectory add_subdirectory(${SENTRY_NATIVE_SRC} sentry_build) diff --git a/sentry-android-ndk/sentry-native b/sentry-android-ndk/sentry-native index 3aa9a80fcf..50ae51a879 160000 --- a/sentry-android-ndk/sentry-native +++ b/sentry-android-ndk/sentry-native @@ -1 +1 @@ -Subproject commit 3aa9a80fcf0e7b2b00727a75de9544ad8f667f31 +Subproject commit 50ae51a8795da079ec5942623f01d0a52411c546 diff --git a/sentry-samples/sentry-samples-android/CMakeLists.txt b/sentry-samples/sentry-samples-android/CMakeLists.txt index ad170fe404..a62c4773f8 100644 --- a/sentry-samples/sentry-samples-android/CMakeLists.txt +++ b/sentry-samples/sentry-samples-android/CMakeLists.txt @@ -6,6 +6,7 @@ add_library(native-sample SHARED src/main/cpp/native-sample.cpp) # make sure that we build it as a shared lib instead of a static lib set(BUILD_SHARED_LIBS ON) set(SENTRY_BUILD_SHARED_LIBS ON) +set(SENTRY_BACKEND "breakpad") add_subdirectory(../../sentry-android-ndk/${SENTRY_NATIVE_SRC} sentry_build) diff --git a/sentry/src/main/java/io/sentry/Attachment.java b/sentry/src/main/java/io/sentry/Attachment.java index 1d291c689d..87432337a1 100644 --- a/sentry/src/main/java/io/sentry/Attachment.java +++ b/sentry/src/main/java/io/sentry/Attachment.java @@ -14,6 +14,7 @@ public final class Attachment { private final @NotNull String filename; private final @NotNull String contentType; private final boolean addToTransactions; + private final @NotNull String attachmentType = "event.attachment"; /** * We could use Files.probeContentType(path) to determine the content type of the filename. This @@ -187,4 +188,8 @@ public Attachment( boolean isAddToTransactions() { return addToTransactions; } + + public @NotNull String getAttachmentType() { + return attachmentType; + } } diff --git a/sentry/src/main/java/io/sentry/OutboxSender.java b/sentry/src/main/java/io/sentry/OutboxSender.java index c3394bfa43..1334072998 100644 --- a/sentry/src/main/java/io/sentry/OutboxSender.java +++ b/sentry/src/main/java/io/sentry/OutboxSender.java @@ -1,25 +1,25 @@ package io.sentry; -import static io.sentry.SentryLevel.ERROR; +//import static io.sentry.SentryLevel.ERROR; import static io.sentry.cache.EnvelopeCache.PREFIX_CURRENT_SESSION_FILE; import io.sentry.hints.Flushable; -import io.sentry.hints.Resettable; +//import io.sentry.hints.Resettable; import io.sentry.hints.Retryable; -import io.sentry.hints.SubmissionResult; +//import io.sentry.hints.SubmissionResult; import io.sentry.util.CollectionUtils; import io.sentry.util.LogUtils; import io.sentry.util.Objects; import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; +//import java.io.BufferedReader; +//import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.Charset; +//import java.io.InputStreamReader; +//import java.io.Reader; +//import java.nio.charset.Charset; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,11 +27,12 @@ @ApiStatus.Internal public final class OutboxSender extends DirectoryProcessor implements IEnvelopeSender { - @SuppressWarnings("CharsetObjectCanBeUsed") - private static final Charset UTF_8 = Charset.forName("UTF-8"); +// @SuppressWarnings("CharsetObjectCanBeUsed") +// private static final Charset UTF_8 = Charset.forName("UTF-8"); private final @NotNull IHub hub; private final @NotNull IEnvelopeReader envelopeReader; + @SuppressWarnings("UnusedVariable") private final @NotNull ISerializer serializer; private final @NotNull ILogger logger; @@ -107,89 +108,97 @@ private void processEnvelope(final @NotNull SentryEnvelope envelope, final @Null SentryLevel.DEBUG, "Processing Envelope with %d item(s)", CollectionUtils.size(envelope.getItems())); - int items = 0; - - for (final SentryEnvelopeItem item : envelope.getItems()) { - items++; - - if (item.getHeader() == null) { - logger.log(SentryLevel.ERROR, "Item %d has no header", items); - continue; - } - if (SentryItemType.Event.equals(item.getHeader().getType())) { - try (final Reader eventReader = - new BufferedReader( - new InputStreamReader(new ByteArrayInputStream(item.getData()), UTF_8))) { - SentryEvent event = serializer.deserialize(eventReader, SentryEvent.class); - if (event == null) { - logger.log( - SentryLevel.ERROR, - "Item %d of type %s returned null by the parser.", - items, - item.getHeader().getType()); - } else { - if (envelope.getHeader().getEventId() != null - && !envelope.getHeader().getEventId().equals(event.getEventId())) { - logger.log( - SentryLevel.ERROR, - "Item %d of has a different event id (%s) to the envelope header (%s)", - items, - envelope.getHeader().getEventId(), - event.getEventId()); - continue; - } - hub.captureEvent(event, hint); - logger.log(SentryLevel.DEBUG, "Item %d is being captured.", items); - - if (!waitFlush(hint)) { - logger.log( - SentryLevel.WARNING, - "Timed out waiting for event submission: %s", - event.getEventId()); - break; - } - } - } catch (Exception e) { - logger.log(ERROR, "Item failed to process.", e); - } - } else { - // send unknown item types over the wire - final SentryEnvelope newEnvelope = - new SentryEnvelope( - envelope.getHeader().getEventId(), envelope.getHeader().getSdkVersion(), item); - hub.captureEnvelope(newEnvelope, hint); - logger.log( - SentryLevel.DEBUG, - "%s item %d is being captured.", - item.getHeader().getType().getItemType(), - items); - - if (!waitFlush(hint)) { - logger.log( - SentryLevel.WARNING, - "Timed out waiting for item type submission: %s", - item.getHeader().getType().getItemType()); - break; - } - } - - if (hint instanceof SubmissionResult) { - if (!((SubmissionResult) hint).isSuccess()) { - // Failed to send an item of the envelope: Stop attempting to send the rest (an attachment - // without the event that created it isn't useful) - logger.log( - SentryLevel.WARNING, - "Envelope had a failed capture at item %d. No more items will be sent.", - items); - break; - } - } - - // reset the Hint to its initial state as we use it multiple times. - if (hint instanceof Resettable) { - ((Resettable) hint).reset(); - } +// int items = 0; + +// for (final SentryEnvelopeItem item : envelope.getItems()) { +// items++; +// +// if (item.getHeader() == null) { +// logger.log(SentryLevel.ERROR, "Item %d has no header", items); +// continue; +// } +// if (SentryItemType.Event.equals(item.getHeader().getType())) { +// try (final Reader eventReader = +// new BufferedReader( +// new InputStreamReader(new ByteArrayInputStream(item.getData()), UTF_8))) { +// SentryEvent event = serializer.deserialize(eventReader, SentryEvent.class); +// if (event == null) { +// logger.log( +// SentryLevel.ERROR, +// "Item %d of type %s returned null by the parser.", +// items, +// item.getHeader().getType()); +// } else { +// if (envelope.getHeader().getEventId() != null +// && !envelope.getHeader().getEventId().equals(event.getEventId())) { +// logger.log( +// SentryLevel.ERROR, +// "Item %d of has a different event id (%s) to the envelope header (%s)", +// items, +// envelope.getHeader().getEventId(), +// event.getEventId()); +// continue; +// } +// hub.captureEvent(event, hint); +// logger.log(SentryLevel.DEBUG, "Item %d is being captured.", items); +// +// if (!waitFlush(hint)) { +// logger.log( +// SentryLevel.WARNING, +// "Timed out waiting for event submission: %s", +// event.getEventId()); +// break; +// } +// } +// } catch (Exception e) { +// logger.log(ERROR, "Item failed to process.", e); +// } +// } else { +// // send unknown item types over the wire +// final SentryEnvelope newEnvelope = +// new SentryEnvelope( +// envelope.getHeader().getEventId(), envelope.getHeader().getSdkVersion(), item); +// hub.captureEnvelope(newEnvelope, hint); +// logger.log( +// SentryLevel.DEBUG, +// "%s item %d is being captured.", +// item.getHeader().getType().getItemType(), +// items); +// +// if (!waitFlush(hint)) { +// logger.log( +// SentryLevel.WARNING, +// "Timed out waiting for item type submission: %s", +// item.getHeader().getType().getItemType()); +// break; +// } +// } +// +// if (hint instanceof SubmissionResult) { +// if (!((SubmissionResult) hint).isSuccess()) { +// // Failed to send an item of the envelope: Stop attempting to send the rest (an attachment +// // without the event that created it isn't useful) +// logger.log( +// SentryLevel.WARNING, +// "Envelope had a failed capture at item %d. No more items will be sent.", +// items); +// break; +// } +// } +// +// // reset the Hint to its initial state as we use it multiple times. +// if (hint instanceof Resettable) { +// ((Resettable) hint).reset(); +// } +// } + + // event and minidump need to be within the same envelope, so right now we are not enriching + // the event as a hacky solution, but event is gonna ne symbolicated using the minidump + hub.captureEnvelope(envelope, hint); + if (!waitFlush(hint)) { + return; } + } private boolean waitFlush(final @Nullable Object hint) { diff --git a/sentry/src/main/java/io/sentry/SentryEnvelopeItem.java b/sentry/src/main/java/io/sentry/SentryEnvelopeItem.java index 416ed9aea1..b9ee71848b 100644 --- a/sentry/src/main/java/io/sentry/SentryEnvelopeItem.java +++ b/sentry/src/main/java/io/sentry/SentryEnvelopeItem.java @@ -75,7 +75,11 @@ public final class SentryEnvelopeItem { SentryEnvelopeItemHeader itemHeader = new SentryEnvelopeItemHeader( - SentryItemType.Session, () -> cachedItem.getBytes().length, "application/json", null); + SentryItemType.Session, + () -> cachedItem.getBytes().length, + "application/json", + null, + null); // Don't use method reference. This can cause issues on Android return new SentryEnvelopeItem(itemHeader, () -> cachedItem.getBytes()); @@ -112,6 +116,7 @@ public final class SentryEnvelopeItem { SentryItemType.resolve(event), () -> cachedItem.getBytes().length, "application/json", + null, null); // Don't use method reference. This can cause issues on Android @@ -149,6 +154,7 @@ public static SentryEnvelopeItem fromUserFeedback( SentryItemType.UserFeedback, () -> cachedItem.getBytes().length, "application/json", + null, null); // Don't use method reference. This can cause issues on Android @@ -232,7 +238,8 @@ public static SentryEnvelopeItem fromAttachment( SentryItemType.Attachment, () -> cachedItem.getBytes().length, attachment.getContentType(), - attachment.getFilename()); + attachment.getFilename(), + attachment.getAttachmentType()); // Don't use method reference. This can cause issues on Android return new SentryEnvelopeItem(itemHeader, () -> cachedItem.getBytes()); diff --git a/sentry/src/main/java/io/sentry/SentryEnvelopeItemHeader.java b/sentry/src/main/java/io/sentry/SentryEnvelopeItemHeader.java index 2e39b35206..2317ed5b1a 100644 --- a/sentry/src/main/java/io/sentry/SentryEnvelopeItemHeader.java +++ b/sentry/src/main/java/io/sentry/SentryEnvelopeItemHeader.java @@ -14,6 +14,7 @@ public final class SentryEnvelopeItemHeader { private final @NotNull SentryItemType type; private final int length; @Nullable private final Callable getLength; + private final @Nullable String attachmentType; public @NotNull SentryItemType getType() { return type; @@ -42,23 +43,31 @@ public int getLength() { final @NotNull SentryItemType type, int length, final @Nullable String contentType, - final @Nullable String fileName) { + final @Nullable String fileName, + final @Nullable String attachmentType) { this.type = Objects.requireNonNull(type, "type is required"); this.contentType = contentType; this.length = length; this.fileName = fileName; this.getLength = null; + this.attachmentType = attachmentType; } SentryEnvelopeItemHeader( final @NotNull SentryItemType type, final @Nullable Callable getLength, final @Nullable String contentType, - final @Nullable String fileName) { + final @Nullable String fileName, + final @Nullable String attachmentType) { this.type = Objects.requireNonNull(type, "type is required"); this.contentType = contentType; this.length = -1; this.fileName = fileName; this.getLength = getLength; + this.attachmentType = attachmentType; + } + + public @Nullable String getAttachmentType() { + return attachmentType; } } diff --git a/sentry/src/main/java/io/sentry/SentryEnvelopeItemHeaderAdapter.java b/sentry/src/main/java/io/sentry/SentryEnvelopeItemHeaderAdapter.java index ee57e40096..26f1435af9 100644 --- a/sentry/src/main/java/io/sentry/SentryEnvelopeItemHeaderAdapter.java +++ b/sentry/src/main/java/io/sentry/SentryEnvelopeItemHeaderAdapter.java @@ -34,6 +34,11 @@ public void write(JsonWriter writer, SentryEnvelopeItemHeader value) throws IOEx writer.value(value.getType().getItemType().toLowerCase(Locale.ROOT)); } + if (value.getAttachmentType() != null) { + writer.name("attachment_type"); + writer.value(value.getAttachmentType()); + } + writer.name("length"); writer.value(value.getLength()); @@ -51,6 +56,7 @@ public SentryEnvelopeItemHeader read(JsonReader reader) throws IOException { String fileName = null; SentryItemType type = SentryItemType.Unknown; int length = 0; + String attachmentType = null; reader.beginObject(); while (reader.hasNext()) { @@ -71,6 +77,9 @@ public SentryEnvelopeItemHeader read(JsonReader reader) throws IOException { case "length": length = reader.nextInt(); break; + case "attachment_type": + attachmentType = reader.nextString(); + break; default: reader.skipValue(); break; @@ -78,6 +87,6 @@ public SentryEnvelopeItemHeader read(JsonReader reader) throws IOException { } reader.endObject(); - return new SentryEnvelopeItemHeader(type, length, contentType, fileName); + return new SentryEnvelopeItemHeader(type, length, contentType, fileName, attachmentType); } }