-
Notifications
You must be signed in to change notification settings - Fork 541
/
Copy pathJNIEnvInit.cs
124 lines (103 loc) · 5.02 KB
/
JNIEnvInit.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using Java.Interop;
using Java.Interop.Tools.TypeNameMappings;
namespace Android.Runtime
{
static internal class JNIEnvInit
{
#pragma warning disable 0649
// NOTE: Keep this in sync with the native side in src/native/monodroid/monodroid-glue-internal.hh
internal struct JnienvInitializeArgs {
public IntPtr javaVm;
public IntPtr env;
public IntPtr grefLoader;
public IntPtr Loader_loadClass;
public IntPtr grefClass; // TODO: remove, not needed anymore
public IntPtr Class_forName;
public uint logCategories;
public int version; // TODO: remove, not needed anymore
public int grefGcThreshold;
public IntPtr grefIGCUserPeer;
public int isRunningOnDesktop;
public byte brokenExceptionTransitions;
public int packageNamingPolicy;
public byte ioExceptionType;
public int jniAddNativeMethodRegistrationAttributePresent;
public bool jniRemappingInUse;
public bool marshalMethodsEnabled;
public IntPtr grefGCUserPeerable;
}
#pragma warning restore 0649
internal static JniRuntime.JniValueManager? ValueManager;
internal static bool IsRunningOnDesktop;
internal static bool jniRemappingInUse;
internal static bool MarshalMethodsEnabled;
internal static bool PropagateExceptions;
internal static BoundExceptionType BoundExceptionType;
internal static int gref_gc_threshold;
internal static IntPtr grefIGCUserPeer_class;
internal static IntPtr grefGCUserPeerable_class;
internal static IntPtr java_class_loader;
internal static JniMethodInfo? mid_Class_forName;
internal static AndroidRuntime? androidRuntime;
[UnmanagedCallersOnly]
static unsafe void RegisterJniNatives (IntPtr typeName_ptr, int typeName_len, IntPtr jniClass, IntPtr methods_ptr, int methods_len)
{
// FIXME: https://github.com/xamarin/xamarin-android/issues/8724
[UnconditionalSuppressMessage ("Trimming", "IL2057", Justification = "Type should be preserved by the MarkJavaObjects trimmer step.")]
[return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
static Type TypeGetType (string typeName) =>
Type.GetType (typeName, throwOnError: false);
string typeName = new string ((char*) typeName_ptr, 0, typeName_len);
var type = TypeGetType (typeName);
if (type == null) {
RuntimeNativeMethods.monodroid_log (LogLevel.Error,
LogCategories.Default,
$"Could not load type '{typeName}'. Skipping JNI registration of type '{Java.Interop.TypeManager.GetClassName (jniClass)}'.");
return;
}
var className = Java.Interop.TypeManager.GetClassName (jniClass);
Java.Interop.TypeManager.RegisterType (className, type);
JniType? jniType = null;
JniType.GetCachedJniType (ref jniType, className);
ReadOnlySpan<char> methods = new ReadOnlySpan<char> ((void*) methods_ptr, methods_len);
((AndroidTypeManager)androidRuntime!.TypeManager).RegisterNativeMembers (jniType, type, methods);
}
[UnmanagedCallersOnly]
internal static unsafe void Initialize (JnienvInitializeArgs* args)
{
IntPtr total_timing_sequence = IntPtr.Zero;
IntPtr partial_timing_sequence = IntPtr.Zero;
Logger.SetLogCategories ((LogCategories)args->logCategories);
gref_gc_threshold = args->grefGcThreshold;
jniRemappingInUse = args->jniRemappingInUse;
MarshalMethodsEnabled = args->marshalMethodsEnabled;
java_class_loader = args->grefLoader;
mid_Class_forName = new JniMethodInfo (args->Class_forName, isStatic: true);
BoundExceptionType = (BoundExceptionType)args->ioExceptionType;
androidRuntime = new AndroidRuntime (args->env, args->javaVm, args->grefLoader, args->Loader_loadClass, args->jniAddNativeMethodRegistrationAttributePresent != 0);
ValueManager = androidRuntime.ValueManager;
IsRunningOnDesktop = args->isRunningOnDesktop == 1;
grefIGCUserPeer_class = args->grefIGCUserPeer;
grefGCUserPeerable_class = args->grefGCUserPeerable;
PropagateExceptions = args->brokenExceptionTransitions == 0;
JavaNativeTypeManager.PackageNamingPolicy = (PackageNamingPolicy)args->packageNamingPolicy;
if (IsRunningOnDesktop) {
var packageNamingPolicy = Environment.GetEnvironmentVariable ("__XA_PACKAGE_NAMING_POLICY__");
if (Enum.TryParse (packageNamingPolicy, out PackageNamingPolicy pnp)) {
JavaNativeTypeManager.PackageNamingPolicy = pnp;
}
}
SetSynchronizationContext ();
}
// NOTE: prevents Android.App.Application static ctor from running
[MethodImpl (MethodImplOptions.NoInlining)]
static void SetSynchronizationContext () =>
SynchronizationContext.SetSynchronizationContext (Android.App.Application.SynchronizationContext);
}
}