Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HybridWebView] fix trimmer warnings on Android #24744

Open
wants to merge 1 commit into
base: net9.0
Choose a base branch
from

Conversation

jonathanpeppers
Copy link
Member

Context: #23769
Context: dotnet/android#9300

026e046 introduced HybridWebView, which unfortunately introduces trimmer warnings in the dotnet new maui project template:

> dotnet new maui
> dotnet build -f net9.0-android -c Release -p:TrimMode=Full
...
hellomaui succeeded with 1 warning(s) (7.9s)
/_/src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Android.cs(53,5):
Trim analysis warning IL2026: Microsoft.Maui.Handlers.HybridWebViewHandler.HybridWebViewJavaScriptInterface.SendMessage(String):
Using member 'Java.Interop.ExportAttribute.ExportAttribute(String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code.
[ExportAttribute] uses dynamic features.

This is due to usage of Java.Interop.ExportAttribute:

private sealed class HybridWebViewJavaScriptInterface : Java.Lang.Object
{
    //...
    [JavascriptInterface]
    [Export("sendMessage")]
    public void SendMessage(string message)

Java.Interop.ExportAttribute makes heavy usage of unbounded System.Reflection, System.Reflection.Emit, etc. for it to be able to work. It brings in an additional assembly Mono.Android.Export.dll as well.

It is inherently trimming unsafe, but how did it get through these tests?

[Test]
[TestCase("maui", DotNetPrevious, "Debug", null)]
[TestCase("maui", DotNetPrevious, "Release", null)]
[TestCase("maui", DotNetCurrent, "Debug", null)]
[TestCase("maui", DotNetCurrent, "Release", null)]
[TestCase("maui", DotNetCurrent, "Release", "full")]
[TestCase("maui-blazor", DotNetPrevious, "Debug", null)]
[TestCase("maui-blazor", DotNetPrevious, "Release", null)]
[TestCase("maui-blazor", DotNetCurrent, "Debug", null)]
[TestCase("maui-blazor", DotNetCurrent, "Release", null)]
[TestCase("maui-blazor", DotNetCurrent, "Release", "full")]
public void RunOnAndroid(string id, string framework, string config, string trimMode)

This slipped through, unfortunately, as we had missed solving all the trimmer warnings in Mono.Android.Export.dll! dotnet/android#9300 aims to fix that.

After dotnet/android#9300, new trimming warnings specific to .NET MAUI will surface such as the one above.

But we can easily replace [Export] by:

  • Define a Java interface & create a binding for it in C#, we already have maui.aar setup for this.

  • We can simply implement the interface in C# and remove [Export].

Lastly, I fixed some of the defaults in Metadata.xml, it didn't look like we were automatically making Java interfaces internal. It looks like we probably made ImageLoaderCallback public by mistake.

Context: dotnet#23769
Context: dotnet/android#9300

026e046 introduced `HybridWebView`, which unfortunately introduces
trimmer warnings in the `dotnet new maui` project template:

    > dotnet new maui
    > dotnet build -f net9.0-android -c Release -p:TrimMode=Full
    ...
    hellomaui succeeded with 1 warning(s) (7.9s)
    /_/src/Core/src/Handlers/HybridWebView/HybridWebViewHandler.Android.cs(53,5):
    Trim analysis warning IL2026: Microsoft.Maui.Handlers.HybridWebViewHandler.HybridWebViewJavaScriptInterface.SendMessage(String):
    Using member 'Java.Interop.ExportAttribute.ExportAttribute(String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code.
    [ExportAttribute] uses dynamic features.

This is due to usage of `Java.Interop.ExportAttribute`:

    private sealed class HybridWebViewJavaScriptInterface : Java.Lang.Object
    {
        //...
        [JavascriptInterface]
        [Export("sendMessage")]
        public void SendMessage(string message)

`Java.Interop.ExportAttribute` makes heavy usage of unbounded
System.Reflection, System.Reflection.Emit, etc. for it to be able to
work. It brings in an additional assembly `Mono.Android.Export.dll` as
well.

It is inherently trimming unsafe, but how did it get through these
tests?

https://github.com/dotnet/maui/blob/08ff1246383ed4fdaef84a40d5b2ae8e6096bb56/src/TestUtils/src/Microsoft.Maui.IntegrationTests/AndroidTemplateTests.cs#L50-L61

This slipped through, unfortunately, as we had missed solving all the
trimmer warnings in `Mono.Android.Export.dll`! dotnet/android#9300
aims to fix that.

After dotnet/android#9300, new trimming warnings specific to .NET MAUI
will surface such as the one above.

But we can easily replace `[Export]` by:

* Define a Java interface & create a binding for it in C#, we already
  have `maui.aar` setup for this.

* We can simply implement the interface in C# and remove `[Export]`.

Lastly, I fixed some of the defaults in `Metadata.xml`, it didn't look
like we were automatically making Java interfaces `internal`. It looks
like we probably made `ImageLoaderCallback` public by mistake.
@jonathanpeppers
Copy link
Member Author

The on-device HybridWebView tests look like they are still working on Android:

image

SendMessage() appears to still be called appropriately. 👍

@jonathanpeppers jonathanpeppers marked this pull request as ready for review September 12, 2024 20:53
@jonathanpeppers jonathanpeppers requested a review from a team as a code owner September 12, 2024 20:53
@jonathanpeppers jonathanpeppers enabled auto-merge (squash) September 12, 2024 21:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-controls-hybridwebview HybridWebView control
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants