diff --git a/src/Sentry.Unity/ScreenshotEventProcessor.cs b/src/Sentry.Unity/ScreenshotEventProcessor.cs index a8b8e3584..707c0351a 100644 --- a/src/Sentry.Unity/ScreenshotEventProcessor.cs +++ b/src/Sentry.Unity/ScreenshotEventProcessor.cs @@ -4,61 +4,22 @@ namespace Sentry.Unity; -public class ScreenshotEventProcessor : ISentryEventProcessorWithHint +public class ScreenshotEventProcessor : ISentryEventProcessor { private readonly SentryUnityOptions _options; - private readonly IApplication _application; - public ScreenshotEventProcessor(SentryUnityOptions sentryOptions) : this(sentryOptions, null) { } + private readonly SentryMonoBehaviour _sentryMonoBehaviour; - internal ScreenshotEventProcessor(SentryUnityOptions sentryOptions, IApplication? application) - { - _options = sentryOptions; - _application = application ?? ApplicationAdapter.Instance; - } + public ScreenshotEventProcessor(SentryUnityOptions sentryOptions) : this(sentryOptions, SentryMonoBehaviour.Instance) { } - public SentryEvent? Process(SentryEvent @event) + internal ScreenshotEventProcessor(SentryUnityOptions sentryOptions, SentryMonoBehaviour? sentryMonoBehaviour) { - return @event; + _options = sentryOptions; + _sentryMonoBehaviour = sentryMonoBehaviour ?? SentryMonoBehaviour.Instance; } - public SentryEvent? Process(SentryEvent @event, SentryHint hint) + public SentryEvent Process(SentryEvent @event) { - // save event id - // wait for end of frame - // check if last id is event it - // send screenshot - - // add workitem: screentshot for ID xxx - // sdk integration checking for work: if ID got sent, follow up with screenshot - - if (!MainThreadData.IsMainThread()) - { - _options.DiagnosticLogger?.LogDebug("Screenshot capture skipped. Can't capture screenshots on other than the main thread."); - return @event; - } - - if (_options.BeforeCaptureScreenshotInternal?.Invoke() is not false) - { - if (_application.IsEditor) - { - _options.DiagnosticLogger?.LogInfo("Screenshot capture skipped. Capturing screenshots it not supported in the Editor"); - return @event; - } - - if (Screen.width == 0 || Screen.height == 0) - { - _options.DiagnosticLogger?.LogWarning("Can't capture screenshots on a screen with a resolution of '{0}x{1}'.", Screen.width, Screen.height); - } - else - { - hint.AddAttachment(SentryScreenshot.Capture(_options), "screenshot.jpg", contentType: "image/jpeg"); - } - } - else - { - _options.DiagnosticLogger?.LogInfo("Screenshot capture skipped by BeforeAttachScreenshot callback."); - } - + _sentryMonoBehaviour.CaptureScreenshotForEvent(_options, @event.EventId); return @event; } } diff --git a/src/Sentry.Unity/SentryMonoBehaviour.cs b/src/Sentry.Unity/SentryMonoBehaviour.cs index 0945d3e72..a36c1fa99 100644 --- a/src/Sentry.Unity/SentryMonoBehaviour.cs +++ b/src/Sentry.Unity/SentryMonoBehaviour.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using Sentry.Unity.Integrations; using UnityEngine; @@ -112,3 +113,26 @@ private void Awake() DontDestroyOnLoad(gameObject); } } + +/// +/// A MonoBehaviour that captures screenshots +/// +public partial class SentryMonoBehaviour +{ + // Todo: keep track of event ID to not capture double/more than once per frame + + public void CaptureScreenshotForEvent(SentryUnityOptions options, SentryId eventId) + { + StartCoroutine(CaptureScreenshot(options, eventId)); + } + + private IEnumerator CaptureScreenshot(SentryUnityOptions options, SentryId eventId) + { + yield return new WaitForEndOfFrame(); + + SentryScreenshot.Capture(options); + + // Todo: figure out how to capture an event with a screenshot attachment from out here + var sentryEvent = new SentryEvent(eventId: eventId); + } +} diff --git a/test/Sentry.Unity.Tests/ScreenshotEventProcessorTests.cs b/test/Sentry.Unity.Tests/ScreenshotEventProcessorTests.cs index fcad4a82a..62796ace2 100644 --- a/test/Sentry.Unity.Tests/ScreenshotEventProcessorTests.cs +++ b/test/Sentry.Unity.Tests/ScreenshotEventProcessorTests.cs @@ -11,7 +11,7 @@ private class Fixture public SentryUnityOptions Options = new() { AttachScreenshot = true }; public TestApplication TestApplication = new(); - public ScreenshotEventProcessor GetSut() => new(Options, TestApplication); + public ScreenshotEventProcessor GetSut() => new(Options); } private Fixture _fixture = null!; @@ -28,66 +28,5 @@ public void TearDown() } } - [Test] - public void Process_IsMainThread_AddsScreenshotToHint() - { - _fixture.TestApplication.IsEditor = false; - var sut = _fixture.GetSut(); - var sentryEvent = new SentryEvent(); - var hint = new SentryHint(); - - sut.Process(sentryEvent, hint); - - Assert.AreEqual(1, hint.Attachments.Count); - } - - [Test] - public void Process_IsNonMainThread_DoesNotAddScreenshotToHint() - { - var sut = _fixture.GetSut(); - var sentryEvent = new SentryEvent(); - var hint = new SentryHint(); - - new Thread(() => - { - Thread.CurrentThread.IsBackground = true; - var stream = sut.Process(sentryEvent, hint); - - Assert.AreEqual(0, hint.Attachments.Count); - }).Start(); - } - - [Test] - [TestCase(true)] - [TestCase(false)] - public void Process_BeforeCaptureScreenshotCallbackProvided_RespectsScreenshotCaptureDecision(bool captureScreenshot) - { - _fixture.TestApplication.IsEditor = false; - _fixture.Options.SetBeforeCaptureScreenshot(() => captureScreenshot); - var sut = _fixture.GetSut(); - var sentryEvent = new SentryEvent(); - var hint = new SentryHint(); - - sut.Process(sentryEvent, hint); - - Assert.AreEqual(captureScreenshot ? 1 : 0, hint.Attachments.Count); - } - - [Test] - [TestCase(true, 0)] - [TestCase(false, 1)] - public void Process_InEditorEnvironment_DoesNotCaptureScreenshot(bool isEditor, int expectedAttachmentCount) - { - // Arrange - _fixture.TestApplication.IsEditor = isEditor; - var sut = _fixture.GetSut(); - var sentryEvent = new SentryEvent(); - var hint = new SentryHint(); - - // Act - sut.Process(sentryEvent, hint); - - // Assert - Assert.AreEqual(expectedAttachmentCount, hint.Attachments.Count); - } + // Todo: Add tests that verify passing the capture on to the MonoBehaviour }