From a6607e1a7d3325b2c22d3b42079c13fcde3a09cd Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Fri, 26 Oct 2018 13:37:38 +0200 Subject: [PATCH 1/2] [Java.Interop] Additional marshaler lookup Before going to use the proxy object marshaler, try to check the implemented interfaces for custom marshaler. It will be used in XA to marshal IJavaObject based objects, which do not implement IJavaPeerable. That will make it possible to fix with https://github.com/xamarin/java.interop/issues/388 --- .../Java.Interop/JniRuntime.JniValueManager.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index 8c4b27c28..091ea00da 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -527,6 +527,14 @@ public JniValueMarshaler GetValueMarshaler (Type type) if (typeof (IJavaPeerable).GetTypeInfo ().IsAssignableFrom (info)) { return JavaPeerableValueMarshaler.Instance; } + + foreach (var iface in info.ImplementedInterfaces) { + var ifaceInfo = iface.GetTypeInfo (); + marshalerAttr = ifaceInfo.GetCustomAttribute (); + if (marshalerAttr != null) + return (JniValueMarshaler) Activator.CreateInstance (marshalerAttr.MarshalerType); + } + return GetValueMarshalerCore (type); } From cad29997dc356a7b985cc03613e3a74884c00ff8 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Fri, 26 Oct 2018 17:42:51 +0200 Subject: [PATCH 2/2] Do not allow more than one interface custom marshaler per type --- .../Java.Interop/JniRuntime.JniValueManager.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index 091ea00da..6e7b4a7ea 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -528,12 +528,18 @@ public JniValueMarshaler GetValueMarshaler (Type type) return JavaPeerableValueMarshaler.Instance; } + JniValueMarshalerAttribute ifaceAttribute = null; foreach (var iface in info.ImplementedInterfaces) { - var ifaceInfo = iface.GetTypeInfo (); - marshalerAttr = ifaceInfo.GetCustomAttribute (); - if (marshalerAttr != null) - return (JniValueMarshaler) Activator.CreateInstance (marshalerAttr.MarshalerType); + marshalerAttr = iface.GetTypeInfo ().GetCustomAttribute (); + if (marshalerAttr != null) { + if (ifaceAttribute != null) + throw new NotSupportedException ($"There is more than one interface with custom marshaler for type {type}."); + + ifaceAttribute = marshalerAttr; + } } + if (ifaceAttribute != null) + return (JniValueMarshaler) Activator.CreateInstance (ifaceAttribute.MarshalerType); return GetValueMarshalerCore (type); }