diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ad01ff299..16760b1989 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased: +**Features**: + +- Add `addAttachment` and `clearAttachments` to the NDK `NativeScope` API for managing file and byte attachments via JNI. ([#1584](https://github.com/getsentry/sentry-native/pull/1584)) + **Fixes**: - inproc: only the handling thread cleans up after the crash. ([#1579](https://github.com/getsentry/sentry-native/pull/1579)) @@ -118,7 +122,6 @@ - Add logs flush on `sentry_flush()`. ([#1434](https://github.com/getsentry/sentry-native/pull/1434)) - Add global attributes API. These are added to all `sentry_log_X` calls. ([#1450](https://github.com/getsentry/sentry-native/pull/1450)) - ## 0.12.1 **Fixes**: diff --git a/ndk/lib/api/sentry-native-ndk.api b/ndk/lib/api/sentry-native-ndk.api index 4ab6d7b1aa..4997d04447 100644 --- a/ndk/lib/api/sentry-native-ndk.api +++ b/ndk/lib/api/sentry-native-ndk.api @@ -29,7 +29,10 @@ public final class io/sentry/ndk/DebugImage { } public abstract interface class io/sentry/ndk/INativeScope { + public abstract fun addAttachment (Ljava/lang/String;)V + public abstract fun addAttachmentBytes ([BLjava/lang/String;)V public abstract fun addBreadcrumb (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public abstract fun clearAttachments ()V public abstract fun removeExtra (Ljava/lang/String;)V public abstract fun removeTag (Ljava/lang/String;)V public abstract fun removeUser ()V @@ -49,8 +52,14 @@ public final class io/sentry/ndk/NativeModuleListLoader { public final class io/sentry/ndk/NativeScope : io/sentry/ndk/INativeScope { public fun ()V + public fun addAttachment (Ljava/lang/String;)V + public fun addAttachmentBytes ([BLjava/lang/String;)V public fun addBreadcrumb (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public fun clearAttachments ()V + public static fun nativeAddAttachment (Ljava/lang/String;)V + public static fun nativeAddAttachmentBytes ([BLjava/lang/String;)V public static fun nativeAddBreadcrumb (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public static fun nativeClearAttachments ()V public static fun nativeRemoveExtra (Ljava/lang/String;)V public static fun nativeRemoveTag (Ljava/lang/String;)V public static fun nativeRemoveUser ()V diff --git a/ndk/lib/src/main/java/io/sentry/ndk/INativeScope.java b/ndk/lib/src/main/java/io/sentry/ndk/INativeScope.java index 97124c774b..9f683d12f1 100644 --- a/ndk/lib/src/main/java/io/sentry/ndk/INativeScope.java +++ b/ndk/lib/src/main/java/io/sentry/ndk/INativeScope.java @@ -17,4 +17,10 @@ void addBreadcrumb( String level, String message, String category, String type, String timestamp, String data); void setTrace(String traceId, String parentSpanId); + + void addAttachment(String path); + + void addAttachmentBytes(byte[] data, String filename); + + void clearAttachments(); } diff --git a/ndk/lib/src/main/java/io/sentry/ndk/NativeScope.java b/ndk/lib/src/main/java/io/sentry/ndk/NativeScope.java index a619624dea..96201b0de7 100644 --- a/ndk/lib/src/main/java/io/sentry/ndk/NativeScope.java +++ b/ndk/lib/src/main/java/io/sentry/ndk/NativeScope.java @@ -19,6 +19,12 @@ public static native void nativeAddBreadcrumb( public static native void nativeSetTrace(String traceId, String parentSpanId); + public static native void nativeAddAttachment(String path); + + public static native void nativeAddAttachmentBytes(byte[] data, String filename); + + public static native void nativeClearAttachments(); + @Override public void setTag(String key, String value) { nativeSetTag(key, value); @@ -63,4 +69,19 @@ public void addBreadcrumb( public void setTrace(String traceId, String parentSpanId) { nativeSetTrace(traceId, parentSpanId); } + + @Override + public void addAttachment(String path) { + nativeAddAttachment(path); + } + + @Override + public void addAttachmentBytes(byte[] data, String filename) { + nativeAddAttachmentBytes(data, filename); + } + + @Override + public void clearAttachments() { + nativeClearAttachments(); + } } diff --git a/ndk/lib/src/main/jni/sentry.c b/ndk/lib/src/main/jni/sentry.c index 6be3765c39..eac279959b 100644 --- a/ndk/lib/src/main/jni/sentry.c +++ b/ndk/lib/src/main/jni/sentry.c @@ -227,6 +227,61 @@ Java_io_sentry_ndk_NativeScope_nativeAddBreadcrumb( sentry_add_breadcrumb(crumb); } +JNIEXPORT void JNICALL +Java_io_sentry_ndk_NativeScope_nativeAddAttachment( + JNIEnv *env, + jclass cls, + jstring path) { + if (!path) { + return; + } + const char *charPath = (*env)->GetStringUTFChars(env, path, 0); + if (!charPath) { + return; + } + + // The returned sentry_attachment_t* is intentionally discarded. + // We are not tracking it across the JNI boundary for individual removals. + // Use sentry_clear_attachments() for bulk removal. + sentry_attach_file(charPath); + + (*env)->ReleaseStringUTFChars(env, path, charPath); +} + +JNIEXPORT void JNICALL +Java_io_sentry_ndk_NativeScope_nativeAddAttachmentBytes( + JNIEnv *env, + jclass cls, + jbyteArray data, + jstring filename) { + if (!data || !filename) { + return; + } + jsize bufLen = (*env)->GetArrayLength(env, data); + jbyte *buf = (*env)->GetByteArrayElements(env, data, 0); + if (!buf) { + return; + } + const char *charFilename = (*env)->GetStringUTFChars(env, filename, 0); + if (!charFilename) { + (*env)->ReleaseByteArrayElements(env, data, buf, JNI_ABORT); + return; + } + + // The returned sentry_attachment_t* is intentionally discarded. + // We are not tracking it across the JNI boundary for individual removals. + // Use sentry_clear_attachments() for bulk removal. + sentry_attach_bytes((const char *)buf, (size_t)bufLen, charFilename); + + (*env)->ReleaseStringUTFChars(env, filename, charFilename); + (*env)->ReleaseByteArrayElements(env, data, buf, JNI_ABORT); +} + +JNIEXPORT void JNICALL +Java_io_sentry_ndk_NativeScope_nativeClearAttachments(JNIEnv *env, jclass cls) { + sentry_clear_attachments(); +} + static void send_envelope(sentry_envelope_t *envelope, void *data) { const char *outbox_path = (const char *) data; char envelope_id_str[40];