Skip to content

Commit

Permalink
[HybridWebView] fix trimmer warnings on Android (#24744)
Browse files Browse the repository at this point in the history
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?

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.
  • Loading branch information
jonathanpeppers authored Sep 20, 2024
1 parent 132b4fe commit 70fbb83
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.microsoft.maui;

import androidx.annotation.NonNull;

public interface HybridJavaScriptInterface {
void sendMessage(@NonNull String message);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ protected override AWebView CreatePlatformView()
return platformView;
}

private sealed class HybridWebViewJavaScriptInterface : Java.Lang.Object
private sealed class HybridWebViewJavaScriptInterface : Java.Lang.Object, IHybridJavaScriptInterface
{
private readonly WeakReference<HybridWebViewHandler> _hybridWebViewHandler;

Expand All @@ -47,7 +47,6 @@ public HybridWebViewJavaScriptInterface(HybridWebViewHandler hybridWebViewHandle
private HybridWebViewHandler? Handler => _hybridWebViewHandler is not null && _hybridWebViewHandler.TryGetTarget(out var h) ? h : null;

[JavascriptInterface]
[Export("sendMessage")]
public void SendMessage(string message)
{
Handler?.VirtualView?.MessageReceived(message);
Expand Down
6 changes: 4 additions & 2 deletions src/Core/src/Transforms/Metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
<!-- Normalize the namespace for .NET -->
<attr path="//package[@name='com.microsoft.maui']" name="managedName">Microsoft.Maui</attr>

<!-- Make all classes internal by default -->
<!-- Make all types internal by default -->
<attr path="//class[@visibility='public']" name="visibility">internal</attr>
<!-- Public classes -->
<attr path="//interface[@visibility='public']" name="visibility">internal</attr>
<!-- Public types -->
<attr path="//class[@name='PlatformAppCompatTextView']" name="visibility">public</attr>
<attr path="//class[@name='PlatformContentViewGroup']" name="visibility">public</attr>
<attr path="//class[@name='PlatformWrapperView']" name="visibility">public</attr>
<attr path="//class[@name='MauiViewGroup']" name="visibility">public</attr>
<attr path="//interface[@name='ImageLoaderCallback']" name="visibility">public</attr>
<!-- Internal methods & constructors -->
<attr path="//class[@name='PlatformAppCompatTextView']/method" name="visibility">internal</attr>
<attr path="//class[@name='PlatformAppCompatTextView']/constructor" name="visibility">internal</attr>
Expand Down
Binary file modified src/Core/src/maui.aar
Binary file not shown.

0 comments on commit 70fbb83

Please # to comment.