From d9e440710574e3d261faa4514eb1a46091bca9b9 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 25 Jul 2023 15:26:07 -0500 Subject: [PATCH 1/2] [Mono.Android] Fix Context.RegisterReceiver() enumification (#7735) Fixes: https://github.com/xamarin/xamarin-android/issues/7503 Context: e33eb53407bc85f0b9a0f6c41d9ec009371eedcc Context: df6c716e4168d14fe4d02cf955de5b6b081b9416 Context: 76ab8b2ca208a73834c70453193e5ec7ef1f7304 The bindings for [`Context.registerReceiver(BroadcastReceiver, IntentFilter, int)`][0] and related overloads incorrectly enumified the `int` parameter as the `Android.Content.ActivityFlags` enum (e33eb534), when it should have been `Android.Content.ReceiverFlags` (df6c716e). Unfortunately we can't directly fix this, as the bound `Context.RegisterReceiver(BroadcastReceiver, IntentFilter, ActivityFlags)` method is *`abstract`*, and thus changing it would break compatibility. Fix this without breaking API by: 1. Creating new overload methods which chain to the existing methods 2. Mark the existing methods and method overrides as `[Obsolete]`. a'la: partial class Context { [Obsolete ("This method has an incorrect enumeration type. Use the overload that takes ReceiverFlags instead.")] public abstract Intent? RegisterReceiver (BroadcastReceiver? receiver, IntentFilter? filter, [GeneratedEnum] ActivityFlags flags); public Intent? RegisterReceiver (BroadcastReceiver? receiver, IntentFilter? filter, ReceiverFlags flags) => RegisterReceiver (receiver, filter, (ActivityFlags)flags); } A concern with this approach is that it means that a public `abstract` method is now `[Obsolete]`, which would make it "weird" to override. However, this is a method that should *never* be overridden by user code, so we think this is an acceptable compromise. Additionally, it was noticed that the public API tracking added in 76ab8b2c did not flag this change as an error, only a warning. Convert the RS0016 and RS0017 warnings into errors to ensure that any new public API is accounted for. [0]: https://developer.android.com/reference/android/content/Context#registerReceiver(android.content.BroadcastReceiver,%20android.content.IntentFilter,%20int) --- src/Mono.Android/Android.Content/Context.cs | 10 ++++++++++ src/Mono.Android/Mono.Android.csproj | 5 +++++ .../PublicAPI/API-34/PublicAPI.Unshipped.txt | 2 ++ src/Mono.Android/metadata | 8 ++++++++ 4 files changed, 25 insertions(+) diff --git a/src/Mono.Android/Android.Content/Context.cs b/src/Mono.Android/Android.Content/Context.cs index d397c171207..62896ab8dd9 100644 --- a/src/Mono.Android/Android.Content/Context.cs +++ b/src/Mono.Android/Android.Content/Context.cs @@ -1,4 +1,5 @@ using System; +using Android.OS; using Android.Runtime; namespace Android.Content { @@ -16,5 +17,14 @@ public void StartActivity (Type type) [Obsolete ("This constant will be removed in the future version. Use Android.Content.ReceiverFlags enum directly instead of this field.")] public const int ReceiverVisibleToInstantApps = 1; #endif + +#if ANDROID_34 + // Add correctly enumified overloads + public Intent? RegisterReceiver (BroadcastReceiver? receiver, IntentFilter? filter, ReceiverFlags flags) + => RegisterReceiver (receiver, filter, (ActivityFlags)flags); + + public Intent? RegisterReceiver (BroadcastReceiver? receiver, IntentFilter? filter, string? broadcastPermission, Handler? scheduler, ReceiverFlags flags) + => RegisterReceiver (receiver, filter, broadcastPermission, scheduler, (ActivityFlags)flags); +#endif } } diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index b4444de2a54..71da67f2a0c 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -27,7 +27,12 @@ $(DefineConstants);ANDROID_UNSTABLE $(_MonoAndroidNETDefaultOutDir) + + false + + + $(WarningsAsErrors);RS0016,RS0017 diff --git a/src/Mono.Android/PublicAPI/API-34/PublicAPI.Unshipped.txt b/src/Mono.Android/PublicAPI/API-34/PublicAPI.Unshipped.txt index 4b0aea8a008..cdec2d9529d 100644 --- a/src/Mono.Android/PublicAPI/API-34/PublicAPI.Unshipped.txt +++ b/src/Mono.Android/PublicAPI/API-34/PublicAPI.Unshipped.txt @@ -8448,6 +8448,8 @@ Android.Content.Context.ObtainStyledAttributes(Android.Util.IAttributeSet? set, Android.Content.Context.ObtainStyledAttributes(Android.Util.IAttributeSet? set, int[]! attrs, int defStyleAttr, int defStyleRes) -> Android.Content.Res.TypedArray! Android.Content.Context.ObtainStyledAttributes(int resid, int[]! attrs) -> Android.Content.Res.TypedArray! Android.Content.Context.ObtainStyledAttributes(int[]! attrs) -> Android.Content.Res.TypedArray! +Android.Content.Context.RegisterReceiver(Android.Content.BroadcastReceiver? receiver, Android.Content.IntentFilter? filter, Android.Content.ReceiverFlags flags) -> Android.Content.Intent? +Android.Content.Context.RegisterReceiver(Android.Content.BroadcastReceiver? receiver, Android.Content.IntentFilter? filter, string? broadcastPermission, Android.OS.Handler? scheduler, Android.Content.ReceiverFlags flags) -> Android.Content.Intent? Android.Content.Context.StartActivity(System.Type! type) -> void Android.Content.ContextParams Android.Content.ContextParams.AttributionTag.get -> string? diff --git a/src/Mono.Android/metadata b/src/Mono.Android/metadata index 31c85dc9e61..0ca93013863 100644 --- a/src/Mono.Android/metadata +++ b/src/Mono.Android/metadata @@ -1809,6 +1809,14 @@ ModelDownloadErrorEventArgs + + + This method has an incorrect enumeration type. Use the overload that takes ReceiverFlags instead. + This method has an incorrect enumeration type. Use the overload that takes ReceiverFlags instead. + This method has an incorrect enumeration type. Use the overload that takes ReceiverFlags instead. + This method has an incorrect enumeration type. Use the overload that takes ReceiverFlags instead. + This method has an incorrect enumeration type. Use the overload that takes ReceiverFlags instead. + This method has an incorrect enumeration type. Use the overload that takes ReceiverFlags instead. - 8.0.100-preview.7.23364.32 - 8.0.0-preview.7.23364.3 - 8.0.0-preview.7.23364.3 + 8.0.100-rc.1.23373.1 + 8.0.0-rc.1.23371.3 + 8.0.0-rc.1.23371.3 7.0.0-beta.22103.1 7.0.0-beta.22103.1 - 8.0.0-preview.7.23361.2 + 8.0.0-rc.1.23368.3 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100TransportVersion) 7.0.100-rc.1.22410.7 0.11.4-alpha.23360.2 diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs index 134fff471ef..8798d7e7ffa 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs @@ -279,7 +279,7 @@ protected bool BuildInternal (string projectOrSolution, string target, string [] } if (Builder.UseDotNet) { psi.SetEnvironmentVariable ("DOTNET_MULTILEVEL_LOOKUP", "0"); - psi.SetEnvironmentVariable ("DOTNET_ROOT", TestEnvironment.DotNetPreviewDirectory); + psi.SetEnvironmentVariable ("PATH", TestEnvironment.DotNetPreviewDirectory + Path.PathSeparator + Environment.GetEnvironmentVariable ("PATH")); } psi.Arguments = args.ToString (); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetCLI.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetCLI.cs index d3da05577a1..d049bcc61ee 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetCLI.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/DotNetCLI.cs @@ -47,7 +47,7 @@ protected bool Execute (params string [] args) p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.SetEnvironmentVariable ("DOTNET_MULTILEVEL_LOOKUP", "0"); - p.StartInfo.SetEnvironmentVariable ("DOTNET_ROOT", TestEnvironment.DotNetPreviewDirectory); + p.StartInfo.SetEnvironmentVariable ("PATH", TestEnvironment.DotNetPreviewDirectory + Path.PathSeparator + Environment.GetEnvironmentVariable ("PATH")); if (TestEnvironment.UseLocalBuildOutput) { p.StartInfo.SetEnvironmentVariable ("DOTNETSDK_WORKLOAD_MANIFEST_ROOTS", TestEnvironment.WorkloadManifestOverridePath); p.StartInfo.SetEnvironmentVariable ("DOTNETSDK_WORKLOAD_PACK_ROOTS", TestEnvironment.WorkloadPackOverridePath);