Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Fixes

- The SDK now correctly sets the currently active scene's name on the event ([#2400](https://github.com/getsentry/sentry-unity/pull/2400))
- Fixed an issue where screenshot capture triggered on a burst job would crash the game. The SDK can now also capture screenshots on events that occur outside of the main thread ([#2392](https://github.com/getsentry/sentry-unity/pull/2392))
- Structured logs now have the `origin` and `sdk` attributes correctly set ([#2390](https://github.com/getsentry/sentry-unity/pull/2390))
- Resolved possible startup crashes on Android VR platforms like the Oculus Quest. The SDK no longer natively subscribes to interaction hooks for automatic tracing and breadcrumb creation. ([#2393](https://github.com/getsentry/sentry-unity/pull/2393))
Expand Down
18 changes: 3 additions & 15 deletions src/Sentry.Unity/Integrations/UnityScopeIntegration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,15 @@ internal static class UnitySdkInfo
internal class UnityScopeIntegration : ISdkIntegration
{
private readonly IApplication _application;
private readonly ISentryUnityInfo? _unityInfo;

public UnityScopeIntegration(IApplication application, ISentryUnityInfo? unityInfo)
public UnityScopeIntegration(IApplication application)
{
_application = application;
_unityInfo = unityInfo;
}

public void Register(IHub hub, SentryOptions options)
{
var scopeUpdater = new UnityScopeUpdater((SentryUnityOptions)options, _application, _unityInfo);
var scopeUpdater = new UnityScopeUpdater((SentryUnityOptions)options, _application);
hub.ConfigureScope(scopeUpdater.ConfigureScope);
}
}
Expand All @@ -39,15 +37,11 @@ internal class UnityScopeUpdater
{
private readonly SentryUnityOptions _options;
private readonly IApplication _application;
private readonly ISentryUnityInfo? _unityInfo;
private readonly ISceneManager _sceneManager;

public UnityScopeUpdater(SentryUnityOptions options, IApplication application, ISentryUnityInfo? unityInfo = null, ISceneManager? sceneManager = null)
public UnityScopeUpdater(SentryUnityOptions options, IApplication application)
{
_options = options;
_application = application;
_unityInfo = unityInfo;
_sceneManager = sceneManager ?? SceneManagerAdapter.Instance;
}

public void ConfigureScope(Scope scope)
Expand Down Expand Up @@ -158,12 +152,6 @@ private void PopulateUnity(Protocol.Unity unity)
unity.TargetFrameRate = MainThreadData.TargetFrameRate;
unity.CopyTextureSupport = MainThreadData.CopyTextureSupport;
unity.RenderingThreadingMode = MainThreadData.RenderingThreadingMode;

if (_unityInfo?.IL2CPP is true)
{
// Currently an IL2CPP only feature: see https://github.com/getsentry/sentry-unity/issues/2181
unity.ActiveSceneName = _sceneManager.GetActiveScene().Name;
}
}

private void PopulateTags(Action<string, string> setTag)
Expand Down
4 changes: 2 additions & 2 deletions src/Sentry.Unity/SentryUnityOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ internal SentryUnityOptions(IApplication? application = null,
AddInAppExclude("Cysharp");
AddInAppExclude("DG.Tweening");

var processor = new UnityEventProcessor(this);
var processor = new UnityEventProcessor(this, UnityInfo);
AddEventProcessor(processor);
AddTransactionProcessor(processor);

Expand All @@ -353,7 +353,7 @@ internal SentryUnityOptions(IApplication? application = null,

AddIntegration(new StartupTracingIntegration());
AddIntegration(new AnrIntegration(behaviour));
AddIntegration(new UnityScopeIntegration(application, unityInfo));
AddIntegration(new UnityScopeIntegration(application));
AddIntegration(new UnityBeforeSceneLoadIntegration());
AddIntegration(new SceneManagerIntegration());
AddIntegration(new SceneManagerTracingIntegration());
Expand Down
36 changes: 34 additions & 2 deletions src/Sentry.Unity/UnityEventProcessor.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using Sentry.Extensibility;
using Sentry.Protocol;
using Sentry.Unity.Integrations;
using UnityEngine;
using DeviceOrientation = Sentry.Protocol.DeviceOrientation;

Expand All @@ -11,13 +12,19 @@ internal class UnityEventProcessor :
ISentryTransactionProcessor
{
private readonly SentryUnityOptions _sentryOptions;
private readonly ISentryUnityInfo _unityInfo;
private readonly ISceneManager _sceneManager;
private readonly IApplication _application;

public UnityEventProcessor(SentryUnityOptions sentryOptions)
public UnityEventProcessor(SentryUnityOptions sentryOptions, ISentryUnityInfo unityInfo, IApplication? application = null, ISceneManager? sceneManager = null)
{
_sentryOptions = sentryOptions;
_unityInfo = unityInfo;
_application = application ?? ApplicationAdapter.Instance;
_sceneManager = sceneManager ?? SceneManagerAdapter.Instance;
}

public SentryTransaction? Process(SentryTransaction transaction)
public SentryTransaction Process(SentryTransaction transaction)
{
SetEventContext(transaction);
return transaction;
Expand All @@ -37,6 +44,17 @@ private void SetEventContext(IEventLike sentryEvent)
try
{
PopulateDevice(sentryEvent.Contexts.Device);

// The Unity context should get set in the UnityScopeIntegration automatically sets it when it gets registered
sentryEvent.Contexts.TryGetValue(Protocol.Unity.Type, out var contextObject);
if (contextObject is not Protocol.Unity unityContext)
{
unityContext = new Protocol.Unity();
sentryEvent.Contexts.Add(Protocol.Unity.Type, unityContext);
}

PopulateUnity(unityContext);

// Populating the SDK Integrations here (for now) instead of UnityScopeIntegration because it cannot be guaranteed
// that it got added last or that there was not an integration added at a later point
PopulateSdkIntegrations(sentryEvent.Sdk);
Expand Down Expand Up @@ -81,6 +99,20 @@ private void PopulateDevice(Device device)
}
}

private void PopulateUnity(Protocol.Unity unity)
{
if (!MainThreadData.IsMainThread())
{
return;
}

if (_application.IsEditor || _unityInfo.IL2CPP)
{
// Currently an IL2CPP only feature: see https://github.com/getsentry/sentry-unity/issues/2181
unity.ActiveSceneName = _sceneManager.GetActiveScene().Name;
}
}

private void PopulateSdkIntegrations(SdkVersion sdkVersion)
{
foreach (var integrationName in _sentryOptions.SdkIntegrationNames)
Expand Down
1 change: 1 addition & 0 deletions test/Scripts.Integration.Test/Scripts/SmokeTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ private IEnumerator SmokeTestCoroutine()
t.ExpectMessage(currentMessage, "'type':'os',");
t.ExpectMessage(currentMessage, "'type':'runtime',");
t.ExpectMessage(currentMessage, "'type':'unity',");
t.ExpectMessage(currentMessage, "'active_scene_name':'"); // active scene name
// User
t.ExpectMessage(currentMessage, "'user':{'id':'"); // non-null automatic ID
t.ExpectMessageNot(currentMessage, "'length':0");
Expand Down
31 changes: 26 additions & 5 deletions test/Sentry.Unity.Tests/UnityEventScopeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public void SentrySdkCaptureEvent(bool captureOnUiThread)
Assert.AreEqual(systemInfo.TargetFrameRate!.Value, unityContext!.TargetFrameRate);
Assert.AreEqual(systemInfo.CopyTextureSupport!.Value, unityContext.CopyTextureSupport);
Assert.AreEqual(systemInfo.RenderingThreadingMode!.Value, unityContext.RenderingThreadingMode);
Assert.AreEqual(SceneManager.GetActiveScene().name, unityContext.ActiveSceneName);
Assert.AreEqual(captureOnUiThread ? SceneManager.GetActiveScene().name : null, unityContext.ActiveSceneName);

Assert.IsNull(@event.ServerName);
}
Expand Down Expand Up @@ -338,7 +338,8 @@ public void Tags_Set()

var sentryOptions = new SentryUnityOptions { SendDefaultPii = true };
var scopeUpdater = new UnityScopeUpdater(sentryOptions, _testApplication);
var unityEventProcessor = new UnityEventProcessor(sentryOptions);
var unityInfo = new TestUnityInfo { IL2CPP = true };
var unityEventProcessor = new UnityEventProcessor(sentryOptions, unityInfo);
var scope = new Scope(sentryOptions);
var sentryEvent = new SentryEvent();
var transaction = new SentryTransaction("name", "operation");
Expand Down Expand Up @@ -438,7 +439,6 @@ public void DeviceProtocol_Assigned()
[TestCase(false)]
public void UnityProtocol_Assigned(bool isIL2CPP)
{
var sceneManager = new SceneManagerIntegrationTests.FakeSceneManager { ActiveSceneName = "TestScene" };
var systemInfo = new TestSentrySystemInfo
{
EditorVersion = "TestEditorVersion2022.3.2f1",
Expand All @@ -450,7 +450,7 @@ public void UnityProtocol_Assigned(bool isIL2CPP)
MainThreadData.SentrySystemInfo = systemInfo;
MainThreadData.CollectData();

var sut = new UnityScopeUpdater(_sentryOptions, _testApplication, new TestUnityInfo { IL2CPP = isIL2CPP }, sceneManager);
var sut = new UnityScopeUpdater(_sentryOptions, _testApplication);
var scope = new Scope(_sentryOptions);

// act
Expand All @@ -465,7 +465,6 @@ public void UnityProtocol_Assigned(bool isIL2CPP)
Assert.AreEqual(systemInfo.TargetFrameRate!.Value, unityProtocol.TargetFrameRate);
Assert.AreEqual(systemInfo.CopyTextureSupport!.Value, unityProtocol.CopyTextureSupport);
Assert.AreEqual(systemInfo.RenderingThreadingMode!.Value, unityProtocol.RenderingThreadingMode);
Assert.AreEqual(isIL2CPP ? sceneManager.GetActiveScene().Name : null, unityProtocol.ActiveSceneName);
}

[Test]
Expand Down Expand Up @@ -565,6 +564,28 @@ public void GpuProtocolGraphicsShaderLevelMinusOne_Ignored()
// assert
Assert.IsNull(scope.Contexts.Gpu.GraphicsShaderLevel);
}

[Test]
[TestCase(true, true)]
[TestCase(false, true)]
[TestCase(true, false)]
[TestCase(false, false)]
public void Process_SetsActiveSceneName(bool isEditor, bool isIL2CPP)
{
var sentryOptions = new SentryUnityOptions();
var application = new TestApplication { IsEditor = isEditor };
var unityInfo = new TestUnityInfo { IL2CPP = isIL2CPP };
var sceneManager = new SceneManagerIntegrationTests.FakeSceneManager { ActiveSceneName = "TestScene" };
var sut = new UnityEventProcessor(sentryOptions, unityInfo, application, sceneManager);
var sentryEvent = new SentryEvent();

sut.Process(sentryEvent);

sentryEvent.Contexts.TryGetValue(Unity.Protocol.Unity.Type, out var unityProtocolObject);
var unityProtocol = unityProtocolObject as Unity.Protocol.Unity;
Assert.NotNull(unityProtocol);
Assert.AreEqual(isEditor || isIL2CPP ? sceneManager.GetActiveScene().Name : null, unityProtocol!.ActiveSceneName);
}
}

internal sealed class TestSentrySystemInfo : ISentrySystemInfo
Expand Down
Loading