From f61cd81cdf7ae7c857724b37ffcf89479fe94501 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Fri, 28 Jan 2022 14:19:39 -0600 Subject: [PATCH] [Microsoft.Android.Sdk.IlLink] preserve methods in Android.Runtime classes (#6675) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: https://github.com/dotnet/maui/issues/2246 Fixes: https://github.com/dotnet/maui/issues/4262 Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1447865 Context: b7a368a27667c69117f64be81050403f2d5c8560 Revert "[One .NET] Do not preserve IO stream adapter/invoker (#5449)" This reverts commit 051cad7972033b1b9c8b9fbea3be1b90c1c23fa9. If you run the `maui-blazor` template in a Release build: dotnet build -t:Run -c Release it crashes at runtime: Android.Runtime.JavaProxyThrowable: Exception_WasThrown, Android.Runtime.JavaProxyThrowable --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- android.runtime.JavaProxyThrowable: System.ArgumentException: Arg_DlgtTargMeth at System.Delegate.CreateDelegate(Type , Type , String , Boolean , Boolean ) at System.Delegate.CreateDelegate(Type , Type , String ) at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType , Type , String ) --- End of stack trace from previous location --- at Java.Interop.JniEnvironment.StaticMethods.CallStaticObjectMethod(JniObjectReference , JniMethodInfo , JniArgumentValue* ) at Android.Runtime.JNIEnv.CallStaticObjectMethod(IntPtr , IntPtr , JValue* ) at Android.Runtime.JNIEnv.CallStaticObjectMethod(IntPtr , IntPtr , JValue[] ) at Android.Runtime.JNIEnv.FindClass(String ) at Android.Runtime.JNIEnv.AllocObject(String ) at Android.Runtime.JNIEnv.StartCreateInstance(String , String , JValue* ) at Android.Runtime.JNIEnv.StartCreateInstance(String , String , JValue[] ) at Android.Runtime.InputStreamAdapter..ctor(Stream ) at Android.Runtime.InputStreamAdapter.ToLocalJniHandle(Stream ) at Android.Webkit.WebResourceResponse..ctor(String , String , Int32 , String , IDictionary`2 , Stream ) at Microsoft.AspNetCore.Components.WebView.Maui.WebKitWebViewClient.ShouldInterceptRequest(WebView view, IWebResourceRequest request) at Android.Webkit.WebViewClient.n_ShouldInterceptRequest_Landroid_webkit_WebView_Landroid_webkit_WebResourceRequest_(IntPtr , IntPtr , IntPtr , IntPtr ) at crc64d693e2d9159537db.WebKitWebViewClient.n_shouldInterceptRequest(Native Method) at crc64d693e2d9159537db.WebKitWebViewClient.shouldInterceptRequest(WebKitWebViewClient.java:39) at Rr.a(chromium-TrichromeWebViewGoogle.apk-stable-410410686:16) at org.chromium.android_webview.AwContentsBackgroundThreadClient.shouldInterceptRequestFromNative(chromium-TrichromeWebViewGoogle.apk-stable-410410686:2) --- End of managed Android.Runtime.JavaProxyThrowable stack trace --- android.runtime.JavaProxyThrowable: System.ArgumentException: Arg_DlgtTargMeth at System.Delegate.CreateDelegate(Type , Type , String , Boolean , Boolean ) at System.Delegate.CreateDelegate(Type , Type , String ) at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType , Type , String ) --- End of stack trace from previous location --- at Java.Interop.JniEnvironment.StaticMethods.CallStaticObjectMethod(JniObjectReference , JniMethodInfo , JniArgumentValue* ) at Android.Runtime.JNIEnv.CallStaticObjectMethod(IntPtr , IntPtr , JValue* ) at Android.Runtime.JNIEnv.CallStaticObjectMethod(IntPtr , IntPtr , JValue[] ) at Android.Runtime.JNIEnv.FindClass(String ) at Android.Runtime.JNIEnv.AllocObject(String ) at Android.Runtime.JNIEnv.StartCreateInstance(String , String , JValue* ) at Android.Runtime.JNIEnv.StartCreateInstance(String , String , JValue[] ) at Android.Runtime.InputStreamAdapter..ctor(Stream ) at Android.Runtime.InputStreamAdapter.ToLocalJniHandle(Stream ) at Android.Webkit.WebResourceResponse..ctor(String , String , Int32 , String , IDictionary`2 , Stream ) at Microsoft.AspNetCore.Components.WebView.Maui.WebKitWebViewClient.ShouldInterceptRequest(WebView view, IWebResourceRequest request) at Android.Webkit.WebViewClient.n_ShouldInterceptRequest_Landroid_webkit_WebView_Landroid_webkit_WebResourceRequest_(IntPtr , IntPtr , IntPtr , IntPtr ) at crc64d693e2d9159537db.WebKitWebViewClient.n_shouldInterceptRequest(Native Method) at crc64d693e2d9159537db.WebKitWebViewClient.shouldInterceptRequest(WebKitWebViewClient.java:39) at Rr.a(chromium-TrichromeWebViewGoogle.apk-stable-410410686:16) at org.chromium.android_webview.AwContentsBackgroundThreadClient.shouldInterceptRequestFromNative(chromium-TrichromeWebViewGoogle.apk-stable-410410686:2) It turns out that `Java.IO.InputStream.GetReadHandler()` was linked away. So we need to preserve: Long-term, we should consider reworking `mono.android.jar`, so that the linker *knows* about any C# methods called from Java from this library, or *drop* `mono.android.jar` & `mono.android.dex` and treat `Mono.Android.dll` as a "normal user assembly"… This regresses `.apk` size by ~16KB: --"PackageSize": 2680724 ++"PackageSize": 2697108 I considered adding: But this regressed app size by too much! 1,141,062 Package size difference 42.57% (of 2,680,724) --- .../PreserveLists/Mono.Android.xml | 4 ++++ .../Base/BuildReleaseArm64SimpleDotNet.apkdesc | 18 +++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveLists/Mono.Android.xml b/src/Microsoft.Android.Sdk.ILLink/PreserveLists/Mono.Android.xml index edb5991510b..368771253da 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveLists/Mono.Android.xml +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveLists/Mono.Android.xml @@ -3,6 +3,8 @@ + + @@ -17,6 +19,8 @@ + + diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc index 679625735c2..3b83618ea09 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc @@ -5,31 +5,31 @@ "Size": 3032 }, "assemblies/Java.Interop.dll": { - "Size": 54720 + "Size": 55086 }, "assemblies/Mono.Android.dll": { - "Size": 78995 + "Size": 83182 }, "assemblies/rc.bin": { "Size": 1045 }, "assemblies/System.Linq.dll": { - "Size": 10152 + "Size": 10157 }, "assemblies/System.Private.CoreLib.dll": { - "Size": 508217 + "Size": 520945 }, "assemblies/System.Runtime.dll": { - "Size": 2404 + "Size": 2410 }, "assemblies/UnnamedProject.dll": { - "Size": 3545 + "Size": 3551 }, "classes.dex": { "Size": 345328 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 382576 + "Size": 382680 }, "lib/arm64-v8a/libmonosgen-2.0.so": { "Size": 3176048 @@ -44,7 +44,7 @@ "Size": 150024 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 12424 + "Size": 12384 }, "META-INF/BNDLTOOL.RSA": { "Size": 1213 @@ -80,5 +80,5 @@ "Size": 1904 } }, - "PackageSize": 2680724 + "PackageSize": 2697108 } \ No newline at end of file