diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c5497c29..57d81d31b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,10 +2,16 @@
## Unreleased
+### Features
+
+- Metrics are no longer experimental ([#2592](https://github.com/getsentry/sentry-unity/pull/2592))
+
+## 4.1.2
+
### Fixes
- `CaptureFeedback` now returns a `SentryId` and exposes a `CaptureFeedbackResult` out parameter to indicate whether feedback was captured successfully ([#2589](https://github.com/getsentry/sentry-unity/pull/2579))
-- When exporting a NSP ROM File for Switch the SKD now correctly uploads the debug symbols ([#2580](https://github.com/getsentry/sentry-unity/pull/2580))
+- When exporting a NSP ROM File for Switch the SKD now correctly uploads the debug symbols ([#2580](https://github.com/getsentry/sentry-unity/pull/2580))
- The SDK now also uses `.sentry-native` as a subdirectory for native support on desktop platforms. It now also falls back to `Application.persistentDataPath` instead of the current working directory. Note: `crashedLastRun` may report `false` for the first time after upgrading. ([#2547](https://github.com/getsentry/sentry-unity/pull/2547))
- The currently experimental Metrics are now opt-in by default ([#2546](https://github.com/getsentry/sentry-unity/pull/2546))
- When targeting Android, the SDK now syncs `AppStartTime` and `AppBuildType` to the native layer ([#2557](https://github.com/getsentry/sentry-unity/pull/2557))
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 9375f617a..634a3a3e1 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -221,6 +221,12 @@ Expected to exist:
+
+
+
+
+
+
@@ -246,28 +252,33 @@ Expected to exist:
$([System.IO.File]::ReadAllText("$(RepoRoot)modules/sentry-java/gradle/libs.versions.toml"))
$([System.Text.RegularExpressions.Regex]::Match($(PropertiesContent), 'sentry-native-ndk\s*=\s*\{[^}]*version\s*=\s*"([^"]+)"').Groups[1].Value)
+ $(RepoRoot)modules/sentry-native/ndk/lib/build/outputs/aar/sentry-native-ndk-release.aar
+
+
+
+
-
+
-
+
-
+
diff --git a/modules/sentry-java b/modules/sentry-java
index c40144aa5..6278324e0 160000
--- a/modules/sentry-java
+++ b/modules/sentry-java
@@ -1 +1 @@
-Subproject commit c40144aa5a4f99cf0d72048eb7e870dee8c7f0a4
+Subproject commit 6278324e01bd9ae25c3b8c9c8e95b49a3e27151d
diff --git a/modules/sentry-native b/modules/sentry-native
index 45e4a1d3f..e64536924 160000
--- a/modules/sentry-native
+++ b/modules/sentry-native
@@ -1 +1 @@
-Subproject commit 45e4a1d3f8078043eb23e3d695689a1a1fa24020
+Subproject commit e645369242e6445c2732452677e0388de3692132
diff --git a/src/Sentry.Unity.Android/AndroidJavaScopeObserver.cs b/src/Sentry.Unity.Android/AndroidJavaScopeObserver.cs
index 55e51705f..65936ac79 100644
--- a/src/Sentry.Unity.Android/AndroidJavaScopeObserver.cs
+++ b/src/Sentry.Unity.Android/AndroidJavaScopeObserver.cs
@@ -36,4 +36,13 @@ public override void UnsetUserImpl() =>
public override void SetTraceImpl(SentryId traceId, SpanId spanId) =>
_sentryJava.SetTrace(traceId, spanId);
+
+ public override void AddFileAttachmentImpl(string filePath, string fileName, string? contentType) =>
+ _sentryJava.AddAttachment(filePath, fileName, contentType);
+
+ public override void AddByteAttachmentImpl(byte[] data, string fileName, string? contentType) =>
+ _sentryJava.AddAttachmentBytes(data, fileName, contentType);
+
+ public override void ClearAttachmentsImpl() =>
+ _sentryJava.ClearAttachments();
}
diff --git a/src/Sentry.Unity.Android/SentryJava.cs b/src/Sentry.Unity.Android/SentryJava.cs
index 9a68442aa..918acc746 100644
--- a/src/Sentry.Unity.Android/SentryJava.cs
+++ b/src/Sentry.Unity.Android/SentryJava.cs
@@ -42,6 +42,9 @@ public void WriteScope(
public void SetUser(SentryUser user);
public void UnsetUser();
public void SetTrace(SentryId traceId, SpanId spanId);
+ void AddAttachment(string path, string fileName, string? contentType);
+ void AddAttachmentBytes(byte[] data, string fileName, string? contentType);
+ void ClearAttachments();
}
///
@@ -361,6 +364,44 @@ public void SetTrace(SentryId traceId, SpanId spanId)
});
}
+ public void AddAttachment(string path, string fileName, string? contentType)
+ {
+ RunJniSafe(() =>
+ {
+ using var attachment = contentType is not null
+ ? new AndroidJavaObject("io.sentry.Attachment", path, fileName, contentType)
+ : new AndroidJavaObject("io.sentry.Attachment", path, fileName);
+
+ using var sentry = GetSentryJava();
+ sentry.CallStatic("configureScope", new ScopeCallback(scope =>
+ scope.Call("addAttachment", attachment)));
+ });
+ }
+
+ public void AddAttachmentBytes(byte[] data, string fileName, string? contentType)
+ {
+ RunJniSafe(() =>
+ {
+ using var attachment = contentType is not null
+ ? new AndroidJavaObject("io.sentry.Attachment", data, fileName, contentType)
+ : new AndroidJavaObject("io.sentry.Attachment", data, fileName);
+
+ using var sentry = GetSentryJava();
+ sentry.CallStatic("configureScope", new ScopeCallback(scope =>
+ scope.Call("addAttachment", attachment)));
+ });
+ }
+
+ public void ClearAttachments()
+ {
+ RunJniSafe(() =>
+ {
+ using var sentry = GetSentryJava();
+ sentry.CallStatic("configureScope", new ScopeCallback(scope =>
+ scope.Call("clearAttachments")));
+ });
+ }
+
// https://github.com/getsentry/sentry-java/blob/db4dfc92f202b1cefc48d019fdabe24d487db923/sentry/src/main/java/io/sentry/SentryLevel.java#L4-L9
internal static string GetLevelString(SentryLevel level) => level switch
{
diff --git a/src/Sentry.Unity.Native/CFunctions.cs b/src/Sentry.Unity.Native/CFunctions.cs
index 4a644e70c..212fc0ed7 100644
--- a/src/Sentry.Unity.Native/CFunctions.cs
+++ b/src/Sentry.Unity.Native/CFunctions.cs
@@ -165,6 +165,15 @@ internal static void SetValueIfNotNull(sentry_value_t obj, string key, long? val
[DllImport(SentryLib)]
internal static extern void sentry_set_trace(string traceId, string parentSpanId);
+ [DllImport(SentryLib)]
+ internal static extern IntPtr sentry_attach_file(string path);
+
+ [DllImport(SentryLib)]
+ internal static extern IntPtr sentry_attach_bytes(byte[] buf, UIntPtr buf_len, string filename);
+
+ [DllImport(SentryLib)]
+ internal static extern void sentry_clear_attachments();
+
internal static readonly Lazy> DebugImages = new(LoadDebugImages);
private static IEnumerable LoadDebugImages()
diff --git a/src/Sentry.Unity.Native/NativeScopeObserver.cs b/src/Sentry.Unity.Native/NativeScopeObserver.cs
index bebeae55c..c99e11641 100644
--- a/src/Sentry.Unity.Native/NativeScopeObserver.cs
+++ b/src/Sentry.Unity.Native/NativeScopeObserver.cs
@@ -43,6 +43,15 @@ public override void SetUserImpl(SentryUser user)
public override void SetTraceImpl(SentryId traceId, SpanId spanId) =>
C.sentry_set_trace(traceId.ToString(), spanId.ToString());
+ public override void AddFileAttachmentImpl(string filePath, string fileName, string? contentType) =>
+ C.sentry_attach_file(filePath);
+
+ public override void AddByteAttachmentImpl(byte[] data, string fileName, string? contentType) =>
+ C.sentry_attach_bytes(data, (UIntPtr)data.Length, fileName);
+
+ public override void ClearAttachmentsImpl() =>
+ C.sentry_clear_attachments();
+
private static string GetTimestamp(DateTimeOffset timestamp) =>
// "o": Using ISO 8601 to make sure the timestamp makes it to the bridge correctly.
// https://docs.microsoft.com/en-gb/dotnet/standard/base-types/standard-date-and-time-format-strings#Roundtrip
diff --git a/src/Sentry.Unity.iOS/NativeScopeObserver.cs b/src/Sentry.Unity.iOS/NativeScopeObserver.cs
index 8c8637eb4..0358d6086 100644
--- a/src/Sentry.Unity.iOS/NativeScopeObserver.cs
+++ b/src/Sentry.Unity.iOS/NativeScopeObserver.cs
@@ -29,6 +29,21 @@ public override void SetUserImpl(SentryUser user) =>
public override void SetTraceImpl(SentryId traceId, SpanId spanId) =>
SentryCocoaBridgeProxy.SetTrace(traceId.ToString(), spanId.ToString());
+ public override void AddFileAttachmentImpl(string filePath, string fileName, string? contentType)
+ {
+ // iOS/macOS attachment sync to sentry-cocoa is not yet supported.
+ }
+
+ public override void AddByteAttachmentImpl(byte[] data, string fileName, string? contentType)
+ {
+ // iOS/macOS attachment sync to sentry-cocoa is not yet supported.
+ }
+
+ public override void ClearAttachmentsImpl()
+ {
+ // iOS/macOS attachment sync to sentry-cocoa is not yet supported.
+ }
+
internal static string GetTimestamp(DateTimeOffset timestamp) =>
// "o": Using ISO 8601 to make sure the timestamp makes it to the bridge correctly.
// https://docs.microsoft.com/en-gb/dotnet/standard/base-types/standard-date-and-time-format-strings#Roundtrip
diff --git a/src/Sentry.Unity/ScopeObserver.cs b/src/Sentry.Unity/ScopeObserver.cs
index 556a83da4..3ae361163 100644
--- a/src/Sentry.Unity/ScopeObserver.cs
+++ b/src/Sentry.Unity/ScopeObserver.cs
@@ -86,4 +86,34 @@ public void SetTrace(SentryId traceId, SpanId spanId)
}
public abstract void SetTraceImpl(SentryId traceId, SpanId spanId);
+
+ public void AddAttachment(SentryAttachment attachment)
+ {
+ if (attachment.Content is FileAttachmentContent fileContent)
+ {
+ _options.LogDebug("{0} Scope Sync - Adding file attachment \"{1}\"", _name, fileContent.FilePath);
+ AddFileAttachmentImpl(fileContent.FilePath, attachment.FileName, attachment.ContentType);
+ }
+ else if (attachment.Content is ByteAttachmentContent byteContent)
+ {
+ _options.LogDebug("{0} Scope Sync - Adding byte attachment \"{1}\" ({2} bytes)", _name, attachment.FileName, byteContent.Bytes.Length);
+ AddByteAttachmentImpl(byteContent.Bytes, attachment.FileName, attachment.ContentType);
+ }
+ else
+ {
+ _options.LogDebug("{0} Scope Sync - Skipping attachment \"{1}\" (unsupported content type for native sync)", _name, attachment.FileName);
+ }
+ }
+
+ public abstract void AddFileAttachmentImpl(string filePath, string fileName, string? contentType);
+
+ public abstract void AddByteAttachmentImpl(byte[] data, string fileName, string? contentType);
+
+ public void ClearAttachments()
+ {
+ _options.LogDebug("{0} Scope Sync - Clearing attachments", _name);
+ ClearAttachmentsImpl();
+ }
+
+ public abstract void ClearAttachmentsImpl();
}
diff --git a/src/sentry-dotnet b/src/sentry-dotnet
index 248f45541..2f133179a 160000
--- a/src/sentry-dotnet
+++ b/src/sentry-dotnet
@@ -1 +1 @@
-Subproject commit 248f45541c5e23e7fe425cdeb98c187389de0aa8
+Subproject commit 2f133179a6f7e3a1f946ac7dc93dd497b0514517
diff --git a/test/Sentry.Unity.Android.Tests/TestSentryJava.cs b/test/Sentry.Unity.Android.Tests/TestSentryJava.cs
index 08dbe299c..195d94221 100644
--- a/test/Sentry.Unity.Android.Tests/TestSentryJava.cs
+++ b/test/Sentry.Unity.Android.Tests/TestSentryJava.cs
@@ -54,4 +54,10 @@ public void SetUser(SentryUser user) { }
public void UnsetUser() { }
public void SetTrace(SentryId traceId, SpanId spanId) { }
+
+ public void AddAttachment(string path, string fileName, string? contentType) { }
+
+ public void AddAttachmentBytes(byte[] data, string fileName, string? contentType) { }
+
+ public void ClearAttachments() { }
}