diff --git a/CHANGELOG.md b/CHANGELOG.md index 4db29307..eeb8e8a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Features + +- Add API allowing to get/set event fingerprint ([#920](https://github.com/getsentry/sentry-unreal/pull/920)) + ### Dependencies - Bump Java SDK (Android) from v8.11.1 to v8.12.0 ([#911](https://github.com/getsentry/sentry-unreal/pull/911)) diff --git a/plugin-dev/Source/Sentry/Private/Android/AndroidSentryEvent.cpp b/plugin-dev/Source/Sentry/Private/Android/AndroidSentryEvent.cpp index c26cb8d8..9c5da6bf 100644 --- a/plugin-dev/Source/Sentry/Private/Android/AndroidSentryEvent.cpp +++ b/plugin-dev/Source/Sentry/Private/Android/AndroidSentryEvent.cpp @@ -26,6 +26,8 @@ void FAndroidSentryEvent::SetupClassMethods() GetMessageMethod = GetMethod("getMessage", "()Lio/sentry/protocol/Message;"); SetLevelMethod = GetMethod("setLevel", "(Lio/sentry/SentryLevel;)V"); GetLevelMethod = GetMethod("getLevel", "()Lio/sentry/SentryLevel;"); + SetFingerprintMethod = GetMethod("setFingerprints", "(Ljava/util/List;)V"); + GetFingerprintMethod = GetMethod("getFingerprints()", "()Ljava/util/List;"); IsCrashMethod = GetMethod("isCrashed", "()Z"); } @@ -57,6 +59,17 @@ ESentryLevel FAndroidSentryEvent::GetLevel() const return FAndroidSentryConverters::SentryLevelToUnreal(*level); } +void FAndroidSentryEvent::SetFingerprint(const TArray& fingerprint) +{ + CallMethod(SetFingerprintMethod, FAndroidSentryConverters::StringArrayToNative(fingerprint)->GetJObject()); +} + +TArray FAndroidSentryEvent::GetFingerprint() +{ + auto fingerprint = CallObjectMethod(GetFingerprintMethod); + return FAndroidSentryConverters::StringListToUnreal(*fingerprint); +} + bool FAndroidSentryEvent::IsCrash() const { return CallMethod(IsCrashMethod); diff --git a/plugin-dev/Source/Sentry/Private/Android/AndroidSentryEvent.h b/plugin-dev/Source/Sentry/Private/Android/AndroidSentryEvent.h index af92581c..2a442ac2 100644 --- a/plugin-dev/Source/Sentry/Private/Android/AndroidSentryEvent.h +++ b/plugin-dev/Source/Sentry/Private/Android/AndroidSentryEvent.h @@ -19,6 +19,8 @@ class FAndroidSentryEvent : public ISentryEvent, public FSentryJavaObjectWrapper virtual FString GetMessage() const override; virtual void SetLevel(ESentryLevel level) override; virtual ESentryLevel GetLevel() const override; + virtual void SetFingerprint(const TArray& fingerprint) override; + virtual TArray GetFingerprint() override; virtual bool IsCrash() const override; virtual bool IsAnr() const override; @@ -28,6 +30,8 @@ class FAndroidSentryEvent : public ISentryEvent, public FSentryJavaObjectWrapper FSentryJavaMethod GetMessageMethod; FSentryJavaMethod SetLevelMethod; FSentryJavaMethod GetLevelMethod; + FSentryJavaMethod SetFingerprintMethod; + FSentryJavaMethod GetFingerprintMethod; FSentryJavaMethod IsCrashMethod; }; diff --git a/plugin-dev/Source/Sentry/Private/Apple/AppleSentryEvent.cpp b/plugin-dev/Source/Sentry/Private/Apple/AppleSentryEvent.cpp index 72bd8a83..4f6daea5 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/AppleSentryEvent.cpp +++ b/plugin-dev/Source/Sentry/Private/Apple/AppleSentryEvent.cpp @@ -56,6 +56,16 @@ ESentryLevel FAppleSentryEvent::GetLevel() const return FAppleSentryConverters::SentryLevelToUnreal(EventApple.level); } +void FAppleSentryEvent::SetFingerprint(const TArray& fingerprint) +{ + EventApple.fingerprint = FAppleSentryConverters::StringArrayToNative(fingerprint); +} + +TArray FAppleSentryEvent::GetFingerprint() +{ + return FAppleSentryConverters::StringArrayToUnreal(EventApple.fingerprint); +} + bool FAppleSentryEvent::IsCrash() const { return EventApple.error != nullptr; diff --git a/plugin-dev/Source/Sentry/Private/Apple/AppleSentryEvent.h b/plugin-dev/Source/Sentry/Private/Apple/AppleSentryEvent.h index 209535c5..62581409 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/AppleSentryEvent.h +++ b/plugin-dev/Source/Sentry/Private/Apple/AppleSentryEvent.h @@ -20,6 +20,8 @@ class FAppleSentryEvent : public ISentryEvent virtual FString GetMessage() const override; virtual void SetLevel(ESentryLevel level) override; virtual ESentryLevel GetLevel() const override; + virtual void SetFingerprint(const TArray& fingerprint) override; + virtual TArray GetFingerprint() override; virtual bool IsCrash() const override; virtual bool IsAnr() const override; diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.cpp index 95a0848c..613fa34d 100644 --- a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.cpp +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.cpp @@ -64,6 +64,17 @@ ESentryLevel FGenericPlatformSentryEvent::GetLevel() const return FGenericPlatformSentryConverters::SentryLevelToUnreal(level); } +void FGenericPlatformSentryEvent::SetFingerprint(const TArray& fingerprint) +{ + sentry_value_set_by_key(Event, "fingerprint", FGenericPlatformSentryConverters::StringArrayToNative(fingerprint)); +} + +TArray FGenericPlatformSentryEvent::GetFingerprint() +{ + sentry_value_t fingerprint = sentry_value_get_by_key(Event, "fingerprint"); + return FGenericPlatformSentryConverters::StringArrayToUnreal(fingerprint); +} + bool FGenericPlatformSentryEvent::IsCrash() const { return IsCrashEvent; diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.h index 31db6904..912a0a5c 100644 --- a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.h @@ -22,6 +22,8 @@ class FGenericPlatformSentryEvent : public ISentryEvent virtual FString GetMessage() const override; virtual void SetLevel(ESentryLevel level) override; virtual ESentryLevel GetLevel() const override; + virtual void SetFingerprint(const TArray& fingerprint) override; + virtual TArray GetFingerprint() override; virtual bool IsCrash() const override; virtual bool IsAnr() const override; diff --git a/plugin-dev/Source/Sentry/Private/Interface/SentryEventInterface.h b/plugin-dev/Source/Sentry/Private/Interface/SentryEventInterface.h index db231d20..f18c9a88 100644 --- a/plugin-dev/Source/Sentry/Private/Interface/SentryEventInterface.h +++ b/plugin-dev/Source/Sentry/Private/Interface/SentryEventInterface.h @@ -18,6 +18,8 @@ class ISentryEvent virtual FString GetMessage() const = 0; virtual void SetLevel(ESentryLevel level) = 0; virtual ESentryLevel GetLevel() const = 0; + virtual void SetFingerprint(const TArray& fingerprint) = 0; + virtual TArray GetFingerprint() = 0; virtual bool IsCrash() const = 0; virtual bool IsAnr() const = 0; }; diff --git a/plugin-dev/Source/Sentry/Private/SentryEvent.cpp b/plugin-dev/Source/Sentry/Private/SentryEvent.cpp index 289b3c59..8ab9b6b2 100644 --- a/plugin-dev/Source/Sentry/Private/SentryEvent.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryEvent.cpp @@ -2,6 +2,7 @@ #include "SentryEvent.h" +#include "Algo/Find.h" #include "HAL/PlatformSentryEvent.h" #include "Interface/SentryIdInterface.h" @@ -54,6 +55,22 @@ ESentryLevel USentryEvent::GetLevel() const return NativeImpl->GetLevel(); } +void USentryEvent::SetFingerprint(const TArray& Fingerprint) +{ + if (!NativeImpl) + return; + + return NativeImpl->SetFingerprint(Fingerprint); +} + +TArray USentryEvent::GetFingerprint() const +{ + if (!NativeImpl) + return TArray(); + + return NativeImpl->GetFingerprint(); +} + bool USentryEvent::IsCrash() const { if (!NativeImpl) diff --git a/plugin-dev/Source/Sentry/Private/Tests/SentryEvent.spec.cpp b/plugin-dev/Source/Sentry/Private/Tests/SentryEvent.spec.cpp index a59dcfb4..8b6e0a1c 100644 --- a/plugin-dev/Source/Sentry/Private/Tests/SentryEvent.spec.cpp +++ b/plugin-dev/Source/Sentry/Private/Tests/SentryEvent.spec.cpp @@ -34,6 +34,33 @@ void SentryEventSpec::Define() TestFalse("Event ID is non-empty", SentryEvent->GetId().IsEmpty()); }); }); + + Describe("Event fingerprint", [this]() + { + It("should persist its value", [this]() + { + TArray InFingerprint = { TEXT("F1"), TEXT("F2"), TEXT("F3") }; + + SentryEvent->SetFingerprint(InFingerprint); + TArray OutFingerprint = SentryEvent->GetFingerprint(); + + TestEqual("Fingerprint elements count", OutFingerprint.Num(), InFingerprint.Num()); + TestEqual("Fingerprint first element", OutFingerprint[0], InFingerprint[0]); + TestEqual("Fingerprint second element", OutFingerprint[1], InFingerprint[1]); + TestEqual("Fingerprint third element", OutFingerprint[2], InFingerprint[2]); + }); + + It("can be emptry", [this]() + { + TArray InFingerprint = {}; + + SentryEvent->SetFingerprint(InFingerprint); + TArray OutFingerprint = SentryEvent->GetFingerprint(); + + TestEqual("Fingerprint elements count", OutFingerprint.Num(), InFingerprint.Num()); + TestEqual("Fingerprint is empty", OutFingerprint.Num(), 0); + }); + }); } #endif \ No newline at end of file diff --git a/plugin-dev/Source/Sentry/Private/Utils/SentryScreenshotUtils.cpp b/plugin-dev/Source/Sentry/Private/Utils/SentryScreenshotUtils.cpp index 438179e7..ca4c459d 100644 --- a/plugin-dev/Source/Sentry/Private/Utils/SentryScreenshotUtils.cpp +++ b/plugin-dev/Source/Sentry/Private/Utils/SentryScreenshotUtils.cpp @@ -57,7 +57,7 @@ bool SentryScreenshotUtils::CaptureScreenshot(const FString& ScreenshotSavePath) #if UE_VERSION_OLDER_THAN(5, 0, 0) GetHighResScreenshotConfig().MergeMaskIntoAlpha(*Bitmap); - TArray *CompressedBitmap = new TArray(); + TArray* CompressedBitmap = new TArray(); FImageUtils::CompressImageArray(ViewportSize.X, ViewportSize.Y, *Bitmap, *CompressedBitmap); #else GetHighResScreenshotConfig().MergeMaskIntoAlpha(*Bitmap, FIntRect()); diff --git a/plugin-dev/Source/Sentry/Public/SentryEvent.h b/plugin-dev/Source/Sentry/Public/SentryEvent.h index a364b89f..f416638a 100644 --- a/plugin-dev/Source/Sentry/Public/SentryEvent.h +++ b/plugin-dev/Source/Sentry/Public/SentryEvent.h @@ -43,6 +43,14 @@ class SENTRY_API USentryEvent : public UObject, public TSentryImplWrapper& Fingerprint); + + /** Gets fingerprint of the event. */ + UFUNCTION(BlueprintCallable, Category = "Sentry") + TArray GetFingerprint() const; + /** Gets flag indicating whether the event is a crash. */ UFUNCTION(BlueprintPure, Category = "Sentry") bool IsCrash() const;