From 0f30f6a3f78988e35b15d9ffa78af95a7ad78941 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 25 Apr 2023 12:03:34 -0500 Subject: [PATCH 1/2] [Xamarin.Android.Build.Tasks] Add support for 'AndroidEnableRestrictToAttributes'. --- .../guides/OneDotNetBindingProjects.md | 52 ++++++++++++++++--- .../guides/building-apps/build-properties.md | 27 ++++++++++ .../Xamarin.Android.Bindings.Core.targets | 1 + ...soft.Android.Sdk.DefaultProperties.targets | 1 + .../Tasks/Generator.cs | 4 ++ 5 files changed, 78 insertions(+), 7 deletions(-) diff --git a/Documentation/guides/OneDotNetBindingProjects.md b/Documentation/guides/OneDotNetBindingProjects.md index e27d7c51f3a..9e0829c1bb9 100644 --- a/Documentation/guides/OneDotNetBindingProjects.md +++ b/Documentation/guides/OneDotNetBindingProjects.md @@ -1,11 +1,11 @@ -# .NET 6 - Xamarin.Android Binding Migration +# .NET 6+ - Xamarin.Android Binding Migration ## Consolidation of binding projects -In .NET 6, there is no longer a concept of a [binding +In .NET 6+, there is no longer a concept of a [binding project][binding] as a separate project type. Any of the MSBuild item groups or build actions that currently work in binding projects will -be supported through a .NET 6 Android application or library. +be supported through a .NET 6+ Android application or library. For example, a binding library would be identical to a class library: @@ -26,7 +26,7 @@ libraries, just that the project file will look the same as an application. The following legacy options are no longer supported. The supported alternatives have been available for several years, and the smoothest migration option is to update - and test your current projects with these options **first** before migrating them to .NET 6. + and test your current projects with these options **first** before migrating them to .NET 6+. ### `` @@ -91,6 +91,44 @@ Or exclude *all* files within that folder: [default-items]: https://github.com/xamarin/xamarin-android/blob/main/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props +## Embedded `.jar`./`.aar` + +In Xamarin.Android Classic, the Java `.jar` or `.aar` was often embedded into the binding `.dll` +as an Embedded Resource. + +However, this led to slow builds, as each `.dll` must be opened and scanned for Java code. If +found, it must be extracted to disk to be used. + +In .NET 6+, Java code is no longer embedded in the `.dll`. The application build process will +automatically include any `.jar` or `.aar` files it finds in the same directory as a referenced `.dll`. + +If a project references a binding via `` or `` then everything +just works and no additional considerations are needed. + +However if a project references a binding via ``, the `.jar`/`.aar` must be located next +to the `.dll`. + +That is, for a reference like this: + +```xml + +``` + +A directory like this will not work: + +``` +\lib + - MyBinding.dll +``` + +The directory must contain the native code as well: + +``` +\lib + - MyBinding.dll + - mybinding.jar +``` + ## Migration Considerations There are several new features set by default to help produce new bindings that better match their @@ -173,7 +211,7 @@ Setting it to `true` will result in "un-nesting" any nested types (legacy behavi true ``` -Setting it to `false` will result in nested types remaining nested in the `interface` (.NET 6 behavior): +Setting it to `false` will result in nested types remaining nested in the `interface` (.NET 6+ behavior): ```xml false @@ -234,7 +272,7 @@ This continues to be enabled/disabled using the same mechanism as all .NET proje ``` -As the default for .NET 6 is `disable`, the same applies for Xamarin Android projects. +As the default for .NET 6+ is `disable`, the same applies for Xamarin Android projects. Use `enable` as shown above to enable NRT support. @@ -243,7 +281,7 @@ Use `enable` as shown above to enable NRT support. ### `Resource.designer.cs` In Xamarin.Android, Java binding projects did not support generating a `Resource.designer.cs` file. -Since binding projects are just class libraries in .NET 6, this file will be generated. This could +Since binding projects are just class libraries in .NET 6+, this file will be generated. This could be a breaking change when migrating existing projects. One example of a failure from this change, is if your binding generates a class named `Resource` diff --git a/Documentation/guides/building-apps/build-properties.md b/Documentation/guides/building-apps/build-properties.md index 113c87c3635..ccc14d08636 100644 --- a/Documentation/guides/building-apps/build-properties.md +++ b/Documentation/guides/building-apps/build-properties.md @@ -485,6 +485,33 @@ Support for this property was added in Xamarin.Android 9.4. This property is `False` by default. + +## AndroidEnableRestrictToAttributes + +A boolean property that determines whether types and members marked with +the Java annotation `androidx.annotation.RestrictTo` will be marked with an +`[Obsolete]` attribute in the C# binding. + +This `[Obsolete]` attribute has a descriptive message explaining that the +Java package owner considers the API to be "internal" and warns against its use. + +This attribute also has a custom warning code `XAOBS001` so that it can be suppressed +independently of "normal" obsolete API. + +Adding `[Obsolete]` attributes instead of automatically removing the API was done to +preserve API compatibility with existing packages. If you would instead prefer to +*remove* members that have the `@RestrictTo` annotation *or* are in non-exported +Java packages, you can use [Transform files](https://learn.microsoft.com/xamarin/android/platform/binding-java-library/customizing-bindings/java-bindings-metadata#metadataxml-transform-file) in addition to +this property to prevent these types from being bound: + +```xml + +``` + +Support for this property was added in .NET 8. + +This property is `True` by default. + ## AndroidEnableSGenConcurrent A boolean property that diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets index 1acc3099159..07564b1309e 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets @@ -93,6 +93,7 @@ It is shared between "legacy" binding projects and .NET 5 projects. EnableBindingStaticAndDefaultInterfaceMethods="$(AndroidBoundInterfacesContainStaticAndDefaultInterfaceMethods)" EnableBindingNestedInterfaceTypes="$(AndroidBoundInterfacesContainTypes)" EnableBindingInterfaceConstants="$(AndroidBoundInterfacesContainConstants)" + EnableRestrictToAttributes="$(AndroidEnableRestrictToAttributes)" Nullable="$(Nullable)" UseJavaLegacyResolver="$(_AndroidUseJavaLegacyResolver)" NamespaceTransforms="@(AndroidNamespaceReplacement)" diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets index cf1da6464d5..3e426dd2e1b 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets @@ -36,6 +36,7 @@ true true true + true false diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs index 6d5848b96c6..e011f58c09c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs @@ -51,6 +51,7 @@ public class BindingsGenerator : AndroidDotnetToolTask public bool EnableBindingStaticAndDefaultInterfaceMethods { get; set; } public bool EnableBindingNestedInterfaceTypes { get; set; } public bool EnableBindingInterfaceConstants { get; set; } + public bool EnableRestrictToAttributes { get; set; } public string Nullable { get; set; } public ITaskItem[] TransformFiles { get; set; } @@ -216,6 +217,9 @@ protected override string GenerateCommandLineCommands () if (EnableBindingStaticAndDefaultInterfaceMethods) features.Add ("default-interface-methods"); + if (EnableRestrictToAttributes) + features.Add ("restrict-to-attributes"); + if (string.Equals (Nullable, "enable", StringComparison.OrdinalIgnoreCase)) features.Add ("nullable-reference-types"); From 9e30ada64205ac00171a53511a904769f6d3725a Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 2 May 2023 09:47:39 -0500 Subject: [PATCH 2/2] Change ' AndroidEnableRestrictToAttributes' to enum style for future-proofing. --- .../guides/building-apps/build-properties.md | 13 +++++++++---- .../Microsoft.Android.Sdk.DefaultProperties.targets | 2 +- src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Documentation/guides/building-apps/build-properties.md b/Documentation/guides/building-apps/build-properties.md index ccc14d08636..7743863813b 100644 --- a/Documentation/guides/building-apps/build-properties.md +++ b/Documentation/guides/building-apps/build-properties.md @@ -488,9 +488,11 @@ This property is `False` by default. ## AndroidEnableRestrictToAttributes -A boolean property that determines whether types and members marked with -the Java annotation `androidx.annotation.RestrictTo` will be marked with an -`[Obsolete]` attribute in the C# binding. +An enum-style property with valid values of `obsolete` and `disable`. + +When set to `obsolete`, types and members that are marked with the Java annotation +`androidx.annotation.RestrictTo` *or* are in non-exported Java packages will +be marked with an `[Obsolete]` attribute in the C# binding. This `[Obsolete]` attribute has a descriptive message explaining that the Java package owner considers the API to be "internal" and warns against its use. @@ -498,6 +500,9 @@ Java package owner considers the API to be "internal" and warns against its use. This attribute also has a custom warning code `XAOBS001` so that it can be suppressed independently of "normal" obsolete API. +When set to `disable`, API will be generated as normal with no additional +attributes. (This is the same behavior as before .NET 8.) + Adding `[Obsolete]` attributes instead of automatically removing the API was done to preserve API compatibility with existing packages. If you would instead prefer to *remove* members that have the `@RestrictTo` annotation *or* are in non-exported @@ -510,7 +515,7 @@ this property to prevent these types from being bound: Support for this property was added in .NET 8. -This property is `True` by default. +This property is set to `obsolete` by default. ## AndroidEnableSGenConcurrent diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets index 3e426dd2e1b..8f72ec0b74e 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets @@ -36,7 +36,7 @@ true true true - true + obsolete false diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs index e011f58c09c..33a9cad54cc 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs @@ -51,7 +51,7 @@ public class BindingsGenerator : AndroidDotnetToolTask public bool EnableBindingStaticAndDefaultInterfaceMethods { get; set; } public bool EnableBindingNestedInterfaceTypes { get; set; } public bool EnableBindingInterfaceConstants { get; set; } - public bool EnableRestrictToAttributes { get; set; } + public string EnableRestrictToAttributes { get; set; } public string Nullable { get; set; } public ITaskItem[] TransformFiles { get; set; } @@ -217,7 +217,7 @@ protected override string GenerateCommandLineCommands () if (EnableBindingStaticAndDefaultInterfaceMethods) features.Add ("default-interface-methods"); - if (EnableRestrictToAttributes) + if (string.Equals (EnableRestrictToAttributes, "obsolete", StringComparison.OrdinalIgnoreCase)) features.Add ("restrict-to-attributes"); if (string.Equals (Nullable, "enable", StringComparison.OrdinalIgnoreCase))