Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
228deef
Create MauiGestureRecognizerEventsBinder.cs
aritchie Apr 17, 2025
e66308c
Wireup
aritchie Apr 17, 2025
d2cb84f
Format code
getsentry-bot Apr 17, 2025
24248da
Cleanup and fix code due stupid bot
aritchie Apr 17, 2025
98a9789
I'm not an animal - I can save mem
aritchie Apr 17, 2025
35e769c
Format code
getsentry-bot Apr 17, 2025
6586050
Update MauiGestureRecognizerEventsBinder.cs
aritchie Apr 30, 2025
d1d5089
Create MauiEventsBinderTests.GestureRecognizers.cs
aritchie Apr 30, 2025
efcd673
Update MauiEventsBinderTests.GestureRecognizers.cs
aritchie Apr 30, 2025
08a82bc
Merge branch 'main' into maui_gestures_breadcrumbs
aritchie Apr 30, 2025
054041f
Merge branch 'main' into maui_gestures_breadcrumbs
aritchie May 1, 2025
1fba474
Update MauiEventsBinderTests.cs
aritchie May 1, 2025
8ef9aca
Update CHANGELOG.md
aritchie May 1, 2025
559c8e0
Format code
getsentry-bot May 1, 2025
a71375a
WIP
aritchie May 1, 2025
ba54096
Merge branch 'maui_gestures_breadcrumbs' of https://github.com/getsen…
aritchie May 1, 2025
e14e5c2
Merge branch 'main' into maui_gestures_breadcrumbs
aritchie May 2, 2025
66adf29
Update CHANGELOG.md
aritchie May 2, 2025
e7a5a9b
Merge branch 'main' into maui_gestures_breadcrumbs
aritchie May 9, 2025
d0c58f4
Bring over device tests to improve setup, fix gesture tests
aritchie May 9, 2025
56e6d12
These run every time in the visual runner
aritchie May 9, 2025
ed4bb20
If working strictly from slnf - these don't get built and are depende…
aritchie May 9, 2025
a79dc8f
Finally got these to generate
aritchie May 9, 2025
ff6c52b
Format code
getsentry-bot May 9, 2025
c8d545c
Update MauiEventsBinderTests.GestureRecognizers.cs
aritchie May 9, 2025
b4f77b1
Merge branch 'maui_gestures_breadcrumbs' of https://github.com/getsen…
aritchie May 9, 2025
c10f2f0
Improve testing setup
aritchie May 9, 2025
28a4993
Update src/Sentry.Maui/Internal/MauiGestureRecognizerEventsBinder.cs
aritchie May 10, 2025
8e32be7
Merge branch 'main' into maui_gestures_breadcrumbs
aritchie May 10, 2025
28c2205
Update MauiGestureRecognizerEventsBinder.cs
aritchie May 10, 2025
09c6df9
Simplified conditional compilation of visual tests
jamescrosswell May 11, 2025
501ae1f
Simplified TFMs in Maui.Device.TestApp
jamescrosswell May 12, 2025
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
4 changes: 4 additions & 0 deletions .generated.NoMobile.sln
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry", "src\Sentry\Sentry.csproj", "{5F253D7F-BF27-46F5-9382-73A66EC247BF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{6987A1CC-608E-4868-A02C-09D30C8B7B2D}"
ProjectSection(SolutionItems) = preProject
test\Directory.Build.props = test\Directory.Build.props
test\Directory.Build.targets = test\Directory.Build.targets
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidTestApp", "test\AndroidTestApp\AndroidTestApp.csproj", "{99E2D1A4-1853-49F9-96B6-59C70FA3DE3A}"
EndProject
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
- Redact Authorization headers before sending events to Sentry ([#4164](https://github.com/getsentry/sentry-dotnet/pull/4164))
- Remove Strong Naming from Sentry.Hangfire ([#4099](https://github.com/getsentry/sentry-dotnet/pull/4099))

### Features
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Two Features section.


- New source generator allows Sentry to see true build variables like PublishAot and PublishTrimmed to properly adapt checks in the Sentry SDK ([#4101](https://github.com/getsentry/sentry-dotnet/pull/4101))
- Auto breadcrumbs now include all .NET MAUI gesture recognizer events ([#4124](https://github.com/getsentry/sentry-dotnet/pull/4124))

### Dependencies

- Bump CLI from v2.43.1 to v2.45.0 ([#4169](https://github.com/getsentry/sentry-dotnet/pull/4169), [#4179](https://github.com/getsentry/sentry-dotnet/pull/4179))
Expand Down
5 changes: 5 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,9 @@
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" PublicKey="0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" />
</ItemGroup>

<!-- Helpful properties used elsewhere -->
<PropertyGroup>
<TargetFrameworkVersion>$([MSBuild]::GetTargetFrameworkVersion($(TargetFramework)))</TargetFrameworkVersion>
<TargetFrameworkIsNet9OrGreater Condition="$([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), 9.0))">true</TargetFrameworkIsNet9OrGreater>
</PropertyGroup>
</Project>
4 changes: 4 additions & 0 deletions Sentry.sln
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry", "src\Sentry\Sentry.csproj", "{5F253D7F-BF27-46F5-9382-73A66EC247BF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{6987A1CC-608E-4868-A02C-09D30C8B7B2D}"
ProjectSection(SolutionItems) = preProject
test\Directory.Build.props = test\Directory.Build.props
test\Directory.Build.targets = test\Directory.Build.targets
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidTestApp", "test\AndroidTestApp\AndroidTestApp.csproj", "{99E2D1A4-1853-49F9-96B6-59C70FA3DE3A}"
EndProject
Expand Down
2 changes: 2 additions & 0 deletions SentryMobile.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
"src\\Sentry.Bindings.Cocoa\\Sentry.Bindings.Cocoa.csproj",
"src\\Sentry.Extensions.Logging\\Sentry.Extensions.Logging.csproj",
"src\\Sentry.Maui\\Sentry.Maui.csproj",
"src\\Sentry.SourceGenerators\\Sentry.SourceGenerators.csproj",
"src\\Sentry\\Sentry.csproj",
"test\\Sentry.Android.AssemblyReader.Tests\\Sentry.Android.AssemblyReader.Tests.csproj",
"test\\Sentry.Extensions.Logging.Tests\\Sentry.Extensions.Logging.Tests.csproj",
"test\\Sentry.Maui.Device.TestApp\\Sentry.Maui.Device.TestApp.csproj",
"test\\Sentry.Maui.Tests\\Sentry.Maui.Tests.csproj",
"test\\Sentry.Testing.CrashableApp\\Sentry.Testing.CrashableApp.csproj",
"test\\Sentry.Testing\\Sentry.Testing.csproj",
"test\\Sentry.Tests\\Sentry.Tests.csproj"
]
Expand Down
6 changes: 5 additions & 1 deletion samples/Sentry.Samples.Maui/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
sentry:SessionReplay.Mask="Unmask"
SemanticProperties.Description="Cute dot net bot waving hi to you!"
HeightRequest="200"
HorizontalOptions="Center" />
HorizontalOptions="Center">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_OnTapped" />
</Image.GestureRecognizers>
</Image>

<Label
Text="Hello, World!"
Expand Down
4 changes: 4 additions & 0 deletions samples/Sentry.Samples.Maui/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,8 @@ private async void OnFeedbackClicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new SubmitFeedback());
}

private void TapGestureRecognizer_OnTapped(object sender, TappedEventArgs e)
{
}
}
2 changes: 2 additions & 0 deletions scripts/generate-solution-filters-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,13 @@ filterConfigs:
- "samples/**/*Maui.csproj"
- "src/**/Sentry.csproj"
- "src/**/Sentry.Analyzers.csproj"
- "src/**/Sentry.SourceGenerators.csproj"
- "src/**/*Android*.csproj"
- "src/**/*Bindings.Android.csproj"
- "src/**/*Bindings.Cocoa.csproj"
- "src/**/Sentry.Extensions.Logging.csproj"
- "src/**/Sentry.Maui.csproj"
- "test/**/Sentry.Testing.CrashableApp.csproj"
- "test/**/Sentry.Android.AssemblyReader.Tests.csproj"
- "test/**/Sentry.Extensions.Logging.Tests.csproj"
- "test/**/Sentry.Maui.Device.TestApp.csproj"
Expand Down
194 changes: 194 additions & 0 deletions src/Sentry.Maui/Internal/MauiGestureRecognizerEventsBinder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
namespace Sentry.Maui.Internal;

/// <summary>
/// Detects and adds breadcrumbs for any gesture recognizers attached to the visual element
/// </summary>
public class MauiGestureRecognizerEventsBinder : IMauiElementEventBinder
{
private static Action<BreadcrumbEvent>? _addBreadcrumb = null!;

/// <summary>
/// Searches VisualElement for gesture recognizers to bind to
/// </summary>
public void Bind(VisualElement element, Action<BreadcrumbEvent> addBreadcrumb)
{
_addBreadcrumb ??= addBreadcrumb; // this is fine... it's the same callback for everyone and it never changes
TryBind(element, true);
}


/// <summary>
/// Searches VisualElement for gesture recognizers to unbind from
/// </summary>
/// <param name="element"></param>
public void UnBind(VisualElement element)
{
_addBreadcrumb = null;
TryBind(element, false);
}

private static void TryBind(VisualElement element, bool bind)
{
if (element is IGestureRecognizers recognizers)
{
foreach (var recognizer in recognizers.GestureRecognizers)
{
SetHooks(recognizer, bind);
}
}
}


private static void SetHooks(IGestureRecognizer recognizer, bool bind)
{
switch (recognizer)
{
case TapGestureRecognizer tap:
tap.Tapped -= OnTapGesture;

if (bind)
{
tap.Tapped += OnTapGesture;
}
break;

case SwipeGestureRecognizer swipe:
swipe.Swiped -= OnSwipeGesture;

if (bind)
{
swipe.Swiped += OnSwipeGesture;
}
break;

case PinchGestureRecognizer pinch:
pinch.PinchUpdated -= OnPinchGesture;

if (bind)
{
pinch.PinchUpdated += OnPinchGesture;
}
break;

case DragGestureRecognizer drag:
drag.DragStarting -= OnDragStartingGesture;
drag.DropCompleted -= OnDropCompletedGesture;

if (bind)
{
drag.DragStarting += OnDragStartingGesture;
drag.DropCompleted += OnDropCompletedGesture;
}
break;

case PanGestureRecognizer pan:
pan.PanUpdated -= OnPanGesture;

if (bind)
{
pan.PanUpdated += OnPanGesture;
}
break;

case PointerGestureRecognizer pointer:
pointer.PointerEntered -= OnPointerEnteredGesture;
pointer.PointerExited -= OnPointerExitedGesture;
pointer.PointerMoved -= OnPointerMovedGesture;
pointer.PointerPressed -= OnPointerPressedGesture;
pointer.PointerReleased -= OnPointerReleasedGesture;

if (bind)
{
pointer.PointerEntered += OnPointerEnteredGesture;
pointer.PointerExited += OnPointerExitedGesture;
pointer.PointerMoved += OnPointerMovedGesture;
pointer.PointerPressed += OnPointerPressedGesture;
pointer.PointerReleased += OnPointerReleasedGesture;
}
break;
}
}

private static void OnPointerReleasedGesture(object? sender, PointerEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(PointerGestureRecognizer.PointerReleased),
ToPointerData(e)
));

private static void OnPointerPressedGesture(object? sender, PointerEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(PointerGestureRecognizer.PointerPressed),
ToPointerData(e)
));

private static void OnPointerMovedGesture(object? sender, PointerEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(PointerGestureRecognizer.PointerMoved),
ToPointerData(e)
));

private static void OnPointerExitedGesture(object? sender, PointerEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(PointerGestureRecognizer.PointerExited),
ToPointerData(e)
));

private static void OnPointerEnteredGesture(object? sender, PointerEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(PointerGestureRecognizer.PointerEntered),
ToPointerData(e)
));

private static IEnumerable<(string Key, string Value)> ToPointerData(PointerEventArgs e) =>
[
#if ANDROID
("MotionEventAction", e.PlatformArgs?.MotionEvent.Action.ToString() ?? string.Empty)
#elif IOS
("State", e.PlatformArgs?.GestureRecognizer.State.ToString() ?? string.Empty)
#endif
];

private static void OnPanGesture(object? sender, PanUpdatedEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(PanGestureRecognizer.PanUpdated),
[
("GestureId", e.GestureId.ToString()),
("StatusType", e.StatusType.ToString()),
("TotalX", e.TotalX.ToString()),
("TotalY", e.TotalY.ToString())
]
));

private static void OnDropCompletedGesture(object? sender, DropCompletedEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(DragGestureRecognizer.DropCompleted)
));

private static void OnDragStartingGesture(object? sender, DragStartingEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(DragGestureRecognizer.DragStarting)
));


private static void OnPinchGesture(object? sender, PinchGestureUpdatedEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(PinchGestureRecognizer.PinchUpdated),
[
("GestureStatus", e.Status.ToString()),
("Scale", e.Scale.ToString()),
("ScaleOrigin", e.ScaleOrigin.ToString())
]
));

private static void OnSwipeGesture(object? sender, SwipedEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(SwipeGestureRecognizer.Swiped),
[("Direction", e.Direction.ToString())]
));

private static void OnTapGesture(object? sender, TappedEventArgs e) => _addBreadcrumb?.Invoke(new(
sender,
nameof(TapGestureRecognizer.Tapped),
[("ButtonMask", e.Buttons.ToString())]
));
}
1 change: 1 addition & 0 deletions src/Sentry.Maui/SentryMauiAppBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static MauiAppBuilder UseSentry(this MauiAppBuilder builder,

services.AddSingleton<IMauiElementEventBinder, MauiButtonEventsBinder>();
services.AddSingleton<IMauiElementEventBinder, MauiImageButtonEventsBinder>();
services.AddSingleton<IMauiElementEventBinder, MauiGestureRecognizerEventsBinder>();
services.AddSingleton<IMauiElementEventBinder, MauiVisualElementEventsBinder>();
services.TryAddSingleton<IMauiEventsBinder, MauiEventsBinder>();

Expand Down
4 changes: 4 additions & 0 deletions test/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
<NoWarn>$(NoWarn);SYSLIB0005;SYSLIB0012</NoWarn>
<!-- Ignore "Naming rule violation: Missing suffix: 'Async'" -->
<NoWarn>$(NoWarn);IDE1006</NoWarn>

<!-- Visual tests need net9.0+ mobile and are flaky when using the headless runner on CI -->
<EnableMauiDeviceTestVisualRunner>false</EnableMauiDeviceTestVisualRunner>
<EnableMauiDeviceTestVisualRunner Condition="'$(TargetFrameworkIsNet9OrGreater)' == 'true' AND '$(PlatformIsMobile)' == 'true' AND '$(ContinuousIntegrationBuild)' != 'true'">true</EnableMauiDeviceTestVisualRunner>
</PropertyGroup>

<!--
Expand Down
27 changes: 16 additions & 11 deletions test/Sentry.Maui.Device.TestApp/Sentry.Maui.Device.TestApp.csproj
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks></TargetFrameworks>
<TargetFrameworks Condition="'$(NO_ANDROID)' == ''">$(TargetFrameworks);net8.0-android;net9.0-android</TargetFrameworks>
<TargetFrameworks Condition="'$(NO_IOS)' == '' And $([MSBuild]::IsOSPlatform('OSX'))">$(TargetFrameworks);net8.0-ios;net9.0-ios</TargetFrameworks>
<!-- Pin target iOS version so that our tests don't break when new versions of Xcode are released.
'net8.0-ios' resolves the latest version of the iOS SDK otherwise. -->
<TargetPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">18</TargetPlatformVersion>
<TargetFrameworks>$(TargetFrameworks);net8.0-android;net9.0-android</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('OSX'))">$(TargetFrameworks);net8.0-ios;net9.0-ios</TargetFrameworks>
<DefineConstants Condition="'$(EnableMauiDeviceTestVisualRunner)' == 'true'">$(DefineConstants);VISUAL_RUNNER</DefineConstants>
</PropertyGroup>

<PropertyGroup>
<UseMaui>true</UseMaui>
<!-- Currently broken on .NET 7, see
- https://github.com/dotnet/maui/issues/18573
- https://developercommunity.visualstudio.com/t/MAUI0000:-SystemMissingMethodException:/10505327?sort=newest&ftype=problem
<TargetFrameworks Condition="'$(NO_MACCATALYST)' == '' And $([MSBuild]::IsOSPlatform('OSX'))">$(TargetFrameworks);net7.0-maccatalyst</TargetFrameworks> -->

<OutputType>Exe</OutputType>
<SingleProject>true</SingleProject>
Expand All @@ -36,7 +32,10 @@

<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">13.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>

<!-- Pin target iOS version so that our tests don't break when new versions of Xcode are released.
'net8.0-ios' resolves the latest version of the iOS SDK otherwise. -->
<TargetPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">18</TargetPlatformVersion>

<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>

<!-- Avoid errors of Sentry.Testing not being a self-contained executable, while including it in a self-contained executable (this).
Expand Down Expand Up @@ -88,11 +87,17 @@
<ItemGroup>
<PackageReference Include="DeviceRunners.XHarness.Maui" Version="0.1.0-preview.1"/>
<PackageReference Include="DeviceRunners.XHarness.Xunit" Version="0.1.0-preview.1"/>

<!-- Prevent downgrade of these packages for DeviceRunners.XHarness.Xunit 0.1.0-preview.1 -->
<PackageReference Include="System.Net.Primitives" Version="4.3.0"/>
<PackageReference Include="System.IO.FileSystem" Version="4.3.0"/>
</ItemGroup>

<ItemGroup Condition="'$(EnableMauiDeviceTestVisualRunner)' == 'true'">
<PackageReference Include="DeviceRunners.VisualRunners.Maui" Version="0.1.0-preview.1"/>
<PackageReference Include="DeviceRunners.VisualRunners.Xunit" Version="0.1.0-preview.1"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sentry.Android.AssemblyReader.Tests\Sentry.Android.AssemblyReader.Tests.csproj" Condition="'$(TargetPlatformIdentifier)' == 'android'"/>
<ProjectReference Include="..\Sentry.Tests\Sentry.Tests.csproj"/>
Expand Down
Loading
Loading