diff --git a/src/Mono.Android/Android.Runtime/JNIEnv.cs b/src/Mono.Android/Android.Runtime/JNIEnv.cs index f720fab843e..4814585bd7c 100644 --- a/src/Mono.Android/Android.Runtime/JNIEnv.cs +++ b/src/Mono.Android/Android.Runtime/JNIEnv.cs @@ -56,7 +56,7 @@ public static partial class JNIEnv { internal static bool PropagateExceptions; internal static bool IsRunningOnDesktop; - internal static bool LogTypemapMissStackTrace; + internal static bool LogAssemblyCategory; static AndroidRuntime? androidRuntime; static BoundExceptionType BoundExceptionType; @@ -67,7 +67,7 @@ public static partial class JNIEnv { internal static AndroidValueManager? AndroidValueManager; [DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)] - extern static void monodroid_log (LogLevel level, LogCategories category, string message); + internal extern static void monodroid_log (LogLevel level, LogCategories category, string message); [DllImport (AndroidRuntime.InternalDllName, CallingConvention = CallingConvention.Cdecl)] internal extern static IntPtr monodroid_timing_start (string? message); @@ -149,7 +149,7 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args) partial_timing_sequence = monodroid_timing_start (null); } - LogTypemapMissStackTrace = (args->logCategories & (uint)LogCategories.Assembly) != 0; + LogAssemblyCategory = (args->logCategories & (uint)LogCategories.Assembly) != 0; gref_gc_threshold = args->grefGcThreshold; @@ -246,6 +246,7 @@ static void ManualJavaObjectDispose (Java.Lang.Object obj) #else // NETCOREAPP internal static Action mono_unhandled_exception = null!; #endif // NETCOREAPP + internal static MethodInfo? mono_unhandled_exception_method = null; #if !NETCOREAPP static Action AppDomain_DoUnhandledException = null!; @@ -254,10 +255,13 @@ static void ManualJavaObjectDispose (Java.Lang.Object obj) static void Initialize () { if (mono_unhandled_exception == null) { - var mono_UnhandledException = typeof (System.Diagnostics.Debugger) + mono_unhandled_exception_method = typeof (System.Diagnostics.Debugger) .GetMethod ("Mono_UnhandledException", BindingFlags.NonPublic | BindingFlags.Static); - if (mono_UnhandledException != null) - mono_unhandled_exception = (Action) Delegate.CreateDelegate (typeof(Action), mono_UnhandledException); + if (mono_unhandled_exception_method != null) + mono_unhandled_exception = (Action) Delegate.CreateDelegate (typeof(Action), mono_unhandled_exception_method); + } + if (mono_unhandled_exception_method == null && mono_unhandled_exception != null) { + mono_unhandled_exception_method = mono_unhandled_exception.Method; } #if !NETCOREAPP @@ -737,7 +741,7 @@ internal static void LogTypemapTrace (StackTrace st) } if (ret == IntPtr.Zero) { - if (LogTypemapMissStackTrace) { + if (LogAssemblyCategory) { monodroid_log (LogLevel.Warn, LogCategories.Default, $"typemap: failed to map managed type to Java type: {type.AssemblyQualifiedName} (Module ID: {type.Module.ModuleVersionId}; Type token: {type.MetadataToken})"); LogTypemapTrace (new StackTrace (true)); } diff --git a/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs b/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs index 88b1e3b110b..90ed5f28ab9 100644 --- a/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs +++ b/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs @@ -5,9 +5,8 @@ using System.Threading; namespace Android.Runtime { - public static class JNINativeWrapper { + public static partial class JNINativeWrapper { - static MethodInfo? mono_unhandled_exception_method; static MethodInfo? exception_handler_method; static MethodInfo? wait_for_bridge_processing_method; @@ -15,15 +14,7 @@ static void get_runtime_types () { if (exception_handler_method != null) return; -#if MONOANDROID1_0 - mono_unhandled_exception_method = typeof (System.Diagnostics.Debugger).GetMethod ( - "Mono_UnhandledException", BindingFlags.NonPublic | BindingFlags.Static); - if (mono_unhandled_exception_method == null) - AndroidEnvironment.FailFast ("Cannot find System.Diagnostics.Debugger.Mono_UnhandledException"); -#endif -#if NETCOREAPP - mono_unhandled_exception_method = JNIEnv.mono_unhandled_exception.Method; -#endif // NETCOREAPP + exception_handler_method = typeof (AndroidEnvironment).GetMethod ( "UnhandledException", BindingFlags.NonPublic | BindingFlags.Static); if (exception_handler_method == null) @@ -45,6 +36,15 @@ public static Delegate CreateDelegate (Delegate dlg) get_runtime_types (); + var delegateType = dlg.GetType (); + var result = CreateBuiltInDelegate (dlg, delegateType); + if (result != null) + return result; + + if (JNIEnv.LogAssemblyCategory) { + JNIEnv.monodroid_log (LogLevel.Warn, LogCategories.Default, $"Falling back to System.Reflection.Emit for delegate type '{delegateType}': {dlg.Method}"); + } + var ret_type = dlg.Method.ReturnType; var parameters = dlg.Method.GetParameters (); var param_types = new Type [parameters.Length]; @@ -73,10 +73,10 @@ public static Delegate CreateDelegate (Delegate dlg) ig.Emit (OpCodes.Leave, label); bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; - if (filter && mono_unhandled_exception_method != null) { + if (filter && JNIEnv.mono_unhandled_exception_method != null) { ig.BeginExceptFilterBlock (); - ig.Emit (OpCodes.Call, mono_unhandled_exception_method); + ig.Emit (OpCodes.Call, JNIEnv.mono_unhandled_exception_method); ig.Emit (OpCodes.Ldc_I4_1); ig.BeginCatchBlock (null!); } else { diff --git a/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs b/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs new file mode 100644 index 00000000000..029441832f5 --- /dev/null +++ b/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs @@ -0,0 +1,377 @@ +using System; +using System.Diagnostics; + +namespace Android.Runtime +{ + public static partial class JNINativeWrapper + { + private static Delegate CreateBuiltInDelegate (Delegate dlg, Type delegateType) + { + switch (delegateType.Name) { + case nameof (_JniMarshal_PP_V): { + _JniMarshal_PP_V callback = (_JniMarshal_PP_V) Delegate.CreateDelegate (typeof (_JniMarshal_PP_V), dlg.Target, dlg.Method); + _JniMarshal_PP_V result = (jnienv, klazz) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPI_V): { + _JniMarshal_PPI_V callback = (_JniMarshal_PPI_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPI_V), dlg.Target, dlg.Method); + _JniMarshal_PPI_V result = (jnienv, klazz, p0) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPL_L): { + _JniMarshal_PPL_L callback = (_JniMarshal_PPL_L) Delegate.CreateDelegate (typeof (_JniMarshal_PPL_L), dlg.Target, dlg.Method); + _JniMarshal_PPL_L result = (jnienv, klazz, p0) => { + JNIEnv.WaitForBridgeProcessing (); + try { + return callback (jnienv, klazz, p0); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + return default; + } + }; + return result; + } + case nameof (_JniMarshal_PPL_V): { + _JniMarshal_PPL_V callback = (_JniMarshal_PPL_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPL_V), dlg.Target, dlg.Method); + _JniMarshal_PPL_V result = (jnienv, klazz, p0) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPL_Z): { + _JniMarshal_PPL_Z callback = (_JniMarshal_PPL_Z) Delegate.CreateDelegate (typeof (_JniMarshal_PPL_Z), dlg.Target, dlg.Method); + _JniMarshal_PPL_Z result = (jnienv, klazz, p0) => { + JNIEnv.WaitForBridgeProcessing (); + try { + return callback (jnienv, klazz, p0); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + return default; + } + }; + return result; + } + case nameof (_JniMarshal_PPII_V): { + _JniMarshal_PPII_V callback = (_JniMarshal_PPII_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPII_V), dlg.Target, dlg.Method); + _JniMarshal_PPII_V result = (jnienv, klazz, p0, p1) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0, p1); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPLI_V): { + _JniMarshal_PPLI_V callback = (_JniMarshal_PPLI_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPLI_V), dlg.Target, dlg.Method); + _JniMarshal_PPLI_V result = (jnienv, klazz, p0, p1) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0, p1); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPLL_V): { + _JniMarshal_PPLL_V callback = (_JniMarshal_PPLL_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPLL_V), dlg.Target, dlg.Method); + _JniMarshal_PPLL_V result = (jnienv, klazz, p0, p1) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0, p1); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPLL_Z): { + _JniMarshal_PPLL_Z callback = (_JniMarshal_PPLL_Z) Delegate.CreateDelegate (typeof (_JniMarshal_PPLL_Z), dlg.Target, dlg.Method); + _JniMarshal_PPLL_Z result = (jnienv, klazz, p0, p1) => { + JNIEnv.WaitForBridgeProcessing (); + try { + return callback (jnienv, klazz, p0, p1); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + return default; + } + }; + return result; + } + case nameof (_JniMarshal_PPIIL_V): { + _JniMarshal_PPIIL_V callback = (_JniMarshal_PPIIL_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPIIL_V), dlg.Target, dlg.Method); + _JniMarshal_PPIIL_V result = (jnienv, klazz, p0, p1, p2) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0, p1, p2); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPILL_V): { + _JniMarshal_PPILL_V callback = (_JniMarshal_PPILL_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPILL_V), dlg.Target, dlg.Method); + _JniMarshal_PPILL_V result = (jnienv, klazz, p0, p1, p2) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0, p1, p2); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPLIL_Z): { + _JniMarshal_PPLIL_Z callback = (_JniMarshal_PPLIL_Z) Delegate.CreateDelegate (typeof (_JniMarshal_PPLIL_Z), dlg.Target, dlg.Method); + _JniMarshal_PPLIL_Z result = (jnienv, klazz, p0, p1, p2) => { + JNIEnv.WaitForBridgeProcessing (); + try { + return callback (jnienv, klazz, p0, p1, p2); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + return default; + } + }; + return result; + } + case nameof (_JniMarshal_PPLLL_L): { + _JniMarshal_PPLLL_L callback = (_JniMarshal_PPLLL_L) Delegate.CreateDelegate (typeof (_JniMarshal_PPLLL_L), dlg.Target, dlg.Method); + _JniMarshal_PPLLL_L result = (jnienv, klazz, p0, p1, p2) => { + JNIEnv.WaitForBridgeProcessing (); + try { + return callback (jnienv, klazz, p0, p1, p2); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + return default; + } + }; + return result; + } + case nameof (_JniMarshal_PPLLL_Z): { + _JniMarshal_PPLLL_Z callback = (_JniMarshal_PPLLL_Z) Delegate.CreateDelegate (typeof (_JniMarshal_PPLLL_Z), dlg.Target, dlg.Method); + _JniMarshal_PPLLL_Z result = (jnienv, klazz, p0, p1, p2) => { + JNIEnv.WaitForBridgeProcessing (); + try { + return callback (jnienv, klazz, p0, p1, p2); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + return default; + } + }; + return result; + } + case nameof (_JniMarshal_PPIIII_V): { + _JniMarshal_PPIIII_V callback = (_JniMarshal_PPIIII_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPIIII_V), dlg.Target, dlg.Method); + _JniMarshal_PPIIII_V result = (jnienv, klazz, p0, p1, p2, p3) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0, p1, p2, p3); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPLLLL_V): { + _JniMarshal_PPLLLL_V callback = (_JniMarshal_PPLLLL_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPLLLL_V), dlg.Target, dlg.Method); + _JniMarshal_PPLLLL_V result = (jnienv, klazz, p0, p1, p2, p3) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0, p1, p2, p3); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPLIIII_V): { + _JniMarshal_PPLIIII_V callback = (_JniMarshal_PPLIIII_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPLIIII_V), dlg.Target, dlg.Method); + _JniMarshal_PPLIIII_V result = (jnienv, klazz, p0, p1, p2, p3, p4) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0, p1, p2, p3, p4); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPZIIII_V): { + _JniMarshal_PPZIIII_V callback = (_JniMarshal_PPZIIII_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPZIIII_V), dlg.Target, dlg.Method); + _JniMarshal_PPZIIII_V result = (jnienv, klazz, p0, p1, p2, p3, p4) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0, p1, p2, p3, p4); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + case nameof (_JniMarshal_PPLIIIIIIII_V): { + _JniMarshal_PPLIIIIIIII_V callback = (_JniMarshal_PPLIIIIIIII_V) Delegate.CreateDelegate (typeof (_JniMarshal_PPLIIIIIIII_V), dlg.Target, dlg.Method); + _JniMarshal_PPLIIIIIIII_V result = (jnienv, klazz, p0, p1, p2, p3, p4, p5, p6, p7, p8) => { + JNIEnv.WaitForBridgeProcessing (); + try { + callback (jnienv, klazz, p0, p1, p2, p3, p4, p5, p6, p7, p8); + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + + } + }; + return result; + } + default: + return null; + } + } + } +} diff --git a/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.tt b/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.tt new file mode 100644 index 00000000000..d8cc765c7c1 --- /dev/null +++ b/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.tt @@ -0,0 +1,68 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# +var delegateTypes = new [] { + new { Type = "_JniMarshal_PP_V", Signature = "(jnienv, klazz)", Return = false }, + new { Type = "_JniMarshal_PPI_V", Signature = "(jnienv, klazz, p0)", Return = false }, + new { Type = "_JniMarshal_PPL_L", Signature = "(jnienv, klazz, p0)", Return = true }, + new { Type = "_JniMarshal_PPL_V", Signature = "(jnienv, klazz, p0)", Return = false }, + new { Type = "_JniMarshal_PPL_Z", Signature = "(jnienv, klazz, p0)", Return = true }, + new { Type = "_JniMarshal_PPII_V", Signature = "(jnienv, klazz, p0, p1)", Return = false }, + new { Type = "_JniMarshal_PPLI_V", Signature = "(jnienv, klazz, p0, p1)", Return = false }, + new { Type = "_JniMarshal_PPLL_V", Signature = "(jnienv, klazz, p0, p1)", Return = false }, + new { Type = "_JniMarshal_PPLL_Z", Signature = "(jnienv, klazz, p0, p1)", Return = true }, + new { Type = "_JniMarshal_PPIIL_V", Signature = "(jnienv, klazz, p0, p1, p2)", Return = false }, + new { Type = "_JniMarshal_PPILL_V", Signature = "(jnienv, klazz, p0, p1, p2)", Return = false }, + new { Type = "_JniMarshal_PPLIL_Z", Signature = "(jnienv, klazz, p0, p1, p2)", Return = true }, + new { Type = "_JniMarshal_PPLLL_L", Signature = "(jnienv, klazz, p0, p1, p2)", Return = true }, + new { Type = "_JniMarshal_PPLLL_Z", Signature = "(jnienv, klazz, p0, p1, p2)", Return = true }, + new { Type = "_JniMarshal_PPIIII_V", Signature = "(jnienv, klazz, p0, p1, p2, p3)", Return = false }, + new { Type = "_JniMarshal_PPLLLL_V", Signature = "(jnienv, klazz, p0, p1, p2, p3)", Return = false }, + new { Type = "_JniMarshal_PPLIIII_V", Signature = "(jnienv, klazz, p0, p1, p2, p3, p4)", Return = false }, + new { Type = "_JniMarshal_PPZIIII_V", Signature = "(jnienv, klazz, p0, p1, p2, p3, p4)", Return = false }, + new { Type = "_JniMarshal_PPLIIIIIIII_V", Signature = "(jnienv, klazz, p0, p1, p2, p3, p4, p5, p6, p7, p8)", Return = false }, +}; +#> +using System; +using System.Diagnostics; + +namespace Android.Runtime +{ + public static partial class JNINativeWrapper + { + private static Delegate CreateBuiltInDelegate (Delegate dlg, Type delegateType) + { + switch (delegateType.Name) { +<# +foreach (var info in delegateTypes) { +#> + case nameof (<#= info.Type #>): { + <#= info.Type #> callback = (<#= info.Type #>) Delegate.CreateDelegate (typeof (<#= info.Type #>), dlg.Target, dlg.Method); + <#= info.Type #> result = <#= info.Signature #> => { + JNIEnv.WaitForBridgeProcessing (); + try { + <#= info.Return ? "return " : "" #>callback <#= info.Signature #>; + } catch (Exception e) { + bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; + if (filter && JNIEnv.mono_unhandled_exception != null) { + JNIEnv.mono_unhandled_exception (e); + } + AndroidEnvironment.UnhandledException (e); + if (filter) + throw; + <#= info.Return ? "return default;" : "" #> + } + }; + return result; + } +<# +} +#> + default: + return null; + } + } + } +} diff --git a/src/Mono.Android/Java.Interop/TypeManager.cs b/src/Mono.Android/Java.Interop/TypeManager.cs index 5476bd15f29..9dbaed1c368 100644 --- a/src/Mono.Android/Java.Interop/TypeManager.cs +++ b/src/Mono.Android/Java.Interop/TypeManager.cs @@ -97,12 +97,11 @@ public int Compare (string x, string y) return mappings [i].Substring (c+1); } - static Action? cb_activate; + static _JniMarshal_PPLLLL_V? cb_activate; internal static Delegate GetActivateHandler () { if (cb_activate == null) - cb_activate = (Action) JNINativeWrapper.CreateDelegate ( - (Action) n_Activate); + cb_activate = (_JniMarshal_PPLLLL_V) JNINativeWrapper.CreateDelegate ((_JniMarshal_PPLLLL_V) n_Activate); return cb_activate; } @@ -220,7 +219,7 @@ static Exception CreateJavaLocationException () if (!JNIEnv.IsRunningOnDesktop) { // Miss message is logged in the native runtime - if (JNIEnv.LogTypemapMissStackTrace) + if (JNIEnv.LogAssemblyCategory) JNIEnv.LogTypemapTrace (new System.Diagnostics.StackTrace (true)); return null; } diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 67be0aac176..41419fc4984 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -125,6 +125,10 @@ + + TextTemplatingFileGenerator + JNINativeWrapper.g.cs + @@ -241,6 +245,11 @@ + + True + True + JNINativeWrapper.g.tt +