Skip to content

Commit e47afe1

Browse files
Copilotgrendellojonathanpeppers
authored
[marshal methods] Make AndroidEnvironmentInternal.UnhandledException public (#10775)
Fixes: #10602 * Make `AndroidEnvironmentInternal.UnhandledException()` public to fix `MethodAccessException` Co-authored-by: Marek Habersack <grendel@twistedcode.net> Co-authored-by: Jonathan Peppers <jonathan.peppers@microsoft.com>
1 parent c5e28d7 commit e47afe1

File tree

2 files changed

+71
-2
lines changed

2 files changed

+71
-2
lines changed

src/Mono.Android.Runtime/Android.Runtime/AndroidEnvironmentInternal.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
using System;
2+
using System.ComponentModel;
23

34
namespace Android.Runtime
45
{
5-
internal static class AndroidEnvironmentInternal
6+
[EditorBrowsable (EditorBrowsableState.Never)]
7+
public static class AndroidEnvironmentInternal
68
{
79
internal static Action<Exception>? UnhandledExceptionHandler;
810

9-
internal static void UnhandledException (Exception e)
11+
[EditorBrowsable (EditorBrowsableState.Never)]
12+
public static void UnhandledException (Exception e)
1013
{
1114
if (UnhandledExceptionHandler == null) {
1215
return;

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,5 +2153,71 @@ public void Plugin_Maui_Audio ([Values] AndroidRuntime runtime)
21532153
const string className = "Lcrc64467b05f37239e7a6/StreamMediaDataSource;";
21542154
Assert.IsTrue (DexUtils.ContainsClass (className, dexFile, AndroidSdkPath), $"`{dexFile}` should include `{className}`!");
21552155
}
2156+
2157+
[Test]
2158+
public void MarshalMethodsUnhandledExceptionRuntimeFixUpWorks ([Values] AndroidRuntime runtime)
2159+
{
2160+
const bool isRelease = true;
2161+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
2162+
return;
2163+
}
2164+
2165+
switch (runtime) {
2166+
case AndroidRuntime.NativeAOT:
2167+
Assert.Ignore ("NativeAOT does not support marshal methods");
2168+
break;
2169+
2170+
case AndroidRuntime.CoreCLR:
2171+
Assert.Ignore ("CoreCLR currently doesn't work due to a bug in Mono.Cecil");
2172+
break;
2173+
}
2174+
2175+
var proj = new XamarinAndroidApplicationProject {
2176+
IsRelease = isRelease,
2177+
EnableMarshalMethods = true,
2178+
};
2179+
proj.SetRuntime (runtime);
2180+
using var builder = CreateApkBuilder ();
2181+
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
2182+
2183+
string monoAndroidRuntimePath = Path.Combine (
2184+
Root,
2185+
builder.ProjectDirectory,
2186+
proj.IntermediateOutputPath,
2187+
"android-arm64",
2188+
"linked",
2189+
"Mono.Android.Runtime.dll"
2190+
);
2191+
FileAssert.Exists (monoAndroidRuntimePath);
2192+
2193+
using var asm = AssemblyDefinition.ReadAssembly (monoAndroidRuntimePath);
2194+
const string TypeName = "Android.Runtime.AndroidEnvironmentInternal";
2195+
TypeDefinition? type = null;
2196+
2197+
foreach (ModuleDefinition module in asm.Modules) {
2198+
foreach (TypeDefinition t in module.Types) {
2199+
if (t.FullName.Equals (TypeName, StringComparison.Ordinal)) {
2200+
type = t;
2201+
break;
2202+
}
2203+
}
2204+
}
2205+
2206+
Assert.NotNull (type, $"Failed to find the '{TypeName}' type in '{monoAndroidRuntimePath}'");
2207+
Assert.IsTrue (type.IsPublic, $"Type '{TypeName}' should be public");
2208+
2209+
// Additionally verify that the UnhandledException method is also public
2210+
const string MethodName = "UnhandledException";
2211+
MethodDefinition? method = null;
2212+
foreach (MethodDefinition m in type.Methods) {
2213+
if (m.Name.Equals (MethodName, StringComparison.Ordinal)) {
2214+
method = m;
2215+
break;
2216+
}
2217+
}
2218+
2219+
Assert.NotNull (method, $"Failed to find the '{MethodName}' method in type '{TypeName}'");
2220+
Assert.IsTrue (method.IsPublic, $"Method '{MethodName}' should be public");
2221+
}
21562222
}
21572223
}

0 commit comments

Comments
 (0)