Skip to content

Commit

Permalink
[Java.Interop] Move JniRuntime type-related methods to JniTypeManager
Browse files Browse the repository at this point in the history
In keeping with the principal of commit 6a42bb8 -- reduce API surface
area, or at least organize into reasonable sections -- move the 5
JniRuntime methods that deal with JNI type signature :: System.Type
mapping and move them into the new (nested) JniRuntime.JniTypeManager
type.

An instance of JniRuntime.JniTypeManager is available from the
new JniRuntime.TypeManager property, permitting use such as:

	JniTypeSignature signature = runtime.TypeManager.GetTypeSignature ("[I");
	Type             type      = runtime.TypeManager.GetType (signature);

Additionally, since type mapping is always "iffy" [0], add additional
JniRuntime.JniTypeManager method overloads which permit returning more
than one possible mapping:

	partial class JniTypeManager {
		public IEnumerable<JniTypeSignature>  GetTypeSignatures (Type type);
		public IEnumerable<Type>              GetTypes (JniTypeSignature typeSignature);
	}

Convenience "overloads" which return a single mapping are also
present, which merely return .FirstOrDefault() on the above methods.

[0]:  How should an `int[]` marshal to Java?
        (a) As an `int[]`, a'la Xamarin.Android
        (b) As a JavaInt32Array
        (c) As a JavaPrimitiveArray<int>
        (d) As a JavaObjectArray<int>
      All of these are plausible, depending on the situation, and
      we should arguably support *all* of them, but means that the
      mapping is inherently ambiguous.
  • Loading branch information
jonpryor committed Oct 29, 2015
1 parent 652dcda commit f60906c
Show file tree
Hide file tree
Showing 19 changed files with 740 additions and 629 deletions.
21 changes: 16 additions & 5 deletions src/Android.Interop/Java.Interop/AndroidVM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public AndroidVMBuilder ()
NewObjectRequired = ((int) Android.OS.Build.VERSION.SdkInt) <= 10;
InvocationPointer = invocationPointer;
ObjectReferenceManager = Java.InteropTests.LoggingJniObjectReferenceManagerDecorator.GetObjectReferenceManager (new JniObjectReferenceManager ());
TypeManager = new AndroidTypeManager ();
}

public AndroidVM CreateAndroidVM ()
Expand All @@ -35,6 +36,18 @@ public AndroidVM CreateAndroidVM ()
}
}

class AndroidTypeManager : JniRuntime.JniTypeManager {

protected override IEnumerable<Type> GetTypesForSimpleReference (string jniSimpleReference)
{
foreach (var t in base.GetTypesForSimpleReference (jniSimpleReference))
yield return t;
Type target = ((AndroidVM) Runtime).GetTypeMapping (jniSimpleReference);
if (target != null)
yield return target;
}
}

public class AndroidVM : JniRuntime {

internal AndroidVM (AndroidVMBuilder builder)
Expand Down Expand Up @@ -69,13 +82,11 @@ public void AddTypeMapping (string jniTypeReference, Type type)
}
}

public override Type GetTypeForJniSimplifiedTypeReference (string jniTypeReference)
internal Type GetTypeMapping (string jniSimpleReference)
{
Type target = base.GetTypeForJniSimplifiedTypeReference (jniTypeReference);
if (target != null)
return target;
Type target;
lock (typeMappings) {
if (typeMappings != null && typeMappings.TryGetValue (jniTypeReference, out target))
if (typeMappings.TryGetValue (jniSimpleReference, out target))
return target;
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ Dictionary<string, List<JavaFieldInfo>> LookupFields ()

var n_type = Field_getType.InvokeVirtualObjectMethod (field);
using (var type = new JniType (ref n_type, JniObjectReferenceOptions.DisposeSourceReference)) {
var info = JniEnvironment.Runtime.GetJniTypeInfoForJniTypeReference (type.Name);
var info = JniEnvironment.Runtime.TypeManager.GetTypeSignature (type.Name);
overloads.Add (new JavaFieldInfo (Members, name + "\u0000" + info.QualifiedReference, isStatic));
}

Expand Down Expand Up @@ -324,7 +324,7 @@ static List<JniType> GetJniTypes (DynamicMetaObject[] args)
var vm = JniEnvironment.Runtime;
foreach (var a in args) {
try {
var at = new JniType (vm.GetJniTypeInfoForType (a.LimitType).QualifiedReference);
var at = new JniType (vm.TypeManager.GetTypeSignature (a.LimitType).QualifiedReference);
r.Add (at);
} catch (JavaException e) {
e.Dispose ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public bool CompatibleWith (List<JniType> args, DynamicMetaObject[] dargs)
for (int i = 0; i < arguments.Count; ++i) {
if (args [i] == null) {
// Builtin type -- JNIEnv.FindClass("I") throws!
if (JniEnvironment.Types.GetJniTypeNameFromClass (arguments [i]) != vm.GetJniTypeInfoForType (dargs [i].LimitType).QualifiedReference)
if (JniEnvironment.Types.GetJniTypeNameFromClass (arguments [i]) != vm.TypeManager.GetTypeSignature (dargs [i].LimitType).QualifiedReference)
return false;
}
else if (!JniEnvironment.Types.IsAssignableFrom (arguments [i], args [i].PeerReference))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected override string JniReturnType {
get {
if (ReturnType == null)
return "V";
return JniEnvironment.Runtime.GetJniTypeInfoForJniTypeReference (ReturnType.Name).QualifiedReference;
return JniEnvironment.Runtime.TypeManager.GetTypeSignature (ReturnType.Name).QualifiedReference;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public override DynamicMetaObject BindConvert (ConvertBinder binder)
{
var vm = JniEnvironment.Runtime;
if (binder.Type == typeof (Type)) {
var type = vm.GetTypeForJniTypeRefererence (info.JniClassName);
var sig = vm.TypeManager.GetTypeSignature (info.JniClassName);
var type = vm.TypeManager.GetType (sig);
var typeE = Expression.Convert (Expression.Constant (type), binder.Type);
return new DynamicMetaObject (typeE, BindingRestrictions.GetTypeRestriction (typeE, binder.Type), type);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Java.Interop.Export/Java.Interop/ExportedMemberBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ public virtual string GetJniMethodSignature (JavaCallableAttribute export, Metho

var signature = new StringBuilder ().Append ("(");
foreach (var p in method.GetParameters ()) {
var info = Runtime.GetJniTypeInfoForType (p.ParameterType);
var info = Runtime.TypeManager.GetTypeSignature (p.ParameterType);
if (info.SimpleReference == null)
throw new NotSupportedException ("Don't know how to determine JNI signature for parameter type: " + p.ParameterType.FullName + ".");
signature.Append (info.QualifiedReference);
}
signature.Append (")");
var ret = Runtime.GetJniTypeInfoForType (method.ReturnType);
var ret = Runtime.TypeManager.GetTypeSignature (method.ReturnType);
if (ret.SimpleReference == null)
throw new NotSupportedException ("Don't know how to determine JNI signature for return type: " + method.ReturnType.FullName + ".");
signature.Append (ret.QualifiedReference);
Expand Down
1 change: 1 addition & 0 deletions src/Java.Interop/Java.Interop.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
<Compile Include="Java.Interop\JniMethodInfo.cs" />
<Compile Include="Java.Interop\JniPeerMembers.cs" />
<Compile Include="Java.Interop\JniRuntime.cs" />
<Compile Include="Java.Interop\JniRuntime.JniTypeManager.cs" />
<Compile Include="Java.Interop\JniStaticMethodInfo.cs" />
<Compile Include="Java.Interop\JniStaticFieldInfo.cs" />
<Compile Include="Java.Interop\JniTransition.cs" />
Expand Down
2 changes: 1 addition & 1 deletion src/Java.Interop/Java.Interop/JavaObjectArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public JavaObjectArray (ref JniObjectReference handle, JniObjectReferenceOptions

static JniObjectReference _NewArray (int length)
{
var info = JniEnvironment.Runtime.GetJniTypeInfoForType (typeof (T));
var info = JniEnvironment.Runtime.TypeManager.GetTypeSignature (typeof (T));
if (info.SimpleReference == null)
info = new JniTypeSignature ("java/lang/Object", info.ArrayRank);
if (info.IsKeyword && info.ArrayRank == 0) {
Expand Down
3 changes: 2 additions & 1 deletion src/Java.Interop/Java.Interop/JniMarshal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ internal static T GetValue<T> (ref JniObjectReference reference, JniObjectRefere
return (T) info.GetValueFromJni (ref reference, transfer, typeof (T));
}

var targetType = jvm.GetTypeForJniTypeRefererence (JniEnvironment.Types.GetJniTypeNameFromInstance (reference));
var signature = jvm.TypeManager.GetTypeSignature (JniEnvironment.Types.GetJniTypeNameFromInstance (reference));
var targetType = jvm.TypeManager.GetType (signature);
if (targetType != null &&
typeof (T).IsAssignableFrom (targetType) &&
(info = jvm.GetJniMarshalInfoForType (targetType)).GetValueFromJni != null) {
Expand Down
10 changes: 9 additions & 1 deletion src/Java.Interop/Java.Interop/JniObjectReferenceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@

namespace Java.Interop {

public class JniObjectReferenceManager : IDisposable {
public class JniObjectReferenceManager : IDisposable, JniRuntime.ISetRuntime {


protected JniRuntime Runtime { get; private set; }

void JniRuntime.ISetRuntime.SetRuntime (JniRuntime runtime)
{
Runtime = runtime;
}

int grefc;
public virtual int GlobalReferenceCount {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal JniInstanceMethods (JniPeerMembers members)
JniInstanceMethods (Type declaringType)
{
var jvm = JniEnvironment.Runtime;
var info = jvm.GetJniTypeInfoForType (declaringType);
var info = jvm.TypeManager.GetTypeSignature (declaringType);
if (info.SimpleReference == null)
throw new NotSupportedException (
string.Format ("Cannot create instance of type '{0}': no Java peer type found.",
Expand Down
8 changes: 4 additions & 4 deletions src/Java.Interop/Java.Interop/JniPeerMembers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ public JniPeerMembers (string jniPeerType, Type managedPeerType)

#if !XA_INTEGRATION
Debug.Assert (
JniEnvironment.Runtime.GetJniTypeInfoForType (managedPeerType).SimpleReference == jniPeerType,
JniEnvironment.Runtime.TypeManager.GetTypeSignature (managedPeerType).SimpleReference == jniPeerType,
string.Format ("ManagedPeerType <=> JniTypeName Mismatch! javaVM.GetJniTypeInfoForType(typeof({0})).JniTypeName=\"{1}\" != \"{2}\"",
managedPeerType.FullName,
JniEnvironment.Runtime.GetJniTypeInfoForType (managedPeerType).SimpleReference,
JniEnvironment.Runtime.TypeManager.GetTypeSignature (managedPeerType).SimpleReference,
jniPeerType));
#endif // !XA_INTEGRATION

Expand All @@ -39,10 +39,10 @@ public JniPeerMembers (string jniPeerType, Type managedPeerType)

#if !XA_INTEGRATION
Debug.Assert (
JniEnvironment.Runtime.GetJniTypeInfoForType (managedPeerType).SimpleReference == jniPeerType,
JniEnvironment.Runtime.TypeManager.GetTypeSignature (managedPeerType).SimpleReference == jniPeerType,
string.Format ("ManagedPeerType <=> JniTypeName Mismatch! javaVM.GetJniTypeInfoForType(typeof({0})).JniTypeName=\"{1}\" != \"{2}\"",
managedPeerType.FullName,
JniEnvironment.Runtime.GetJniTypeInfoForType (managedPeerType).SimpleReference,
JniEnvironment.Runtime.TypeManager.GetTypeSignature (managedPeerType).SimpleReference,
jniPeerType));
#endif // !XA_INTEGRATION
}
Expand Down
Loading

0 comments on commit f60906c

Please sign in to comment.