Skip to content

Commit cc52218

Browse files
[Mono.Android] Java.Lang.Object.GetObject<T>() implementation
The current implementation: return Java.Interop.TypeManager.CreateInstance (handle, transfer, type); Needs to become this, for NativeAOT support: JniObjectReference reference = new (handle); JniObjectReferenceOptions options = JNIEnv.ToJniObjectReferenceOptions (transfer); return (IJavaPeerable) JNIEnvInit.AndroidValueManager?.GetValue (ref reference, options, type); This way we use the appropriate `AndroidValueManager` for the runtime that is currently being used. If we just change the code in `Java.Lang.Object` to do this for all runtimes, this can keep everything a bit simpler. The fallout of this change requires `type` to be decorated with: [DynamicallyAccessedMembers (ConstructorsInterfaces)] This trickled to create many other trimmer warnings, that are likely a real issue. This is a good opportunity to fix them. I also defined the `const` values in `Java.Lang.Object`: internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; internal const DynamicallyAccessedMemberTypes ConstructorsInterfaces = Constructors | DynamicallyAccessedMemberTypes.Interfaces; Which allowed many types that extend `Java.Lang.Object` able to reuse these `const` values and not define them again. I also had to make a helper function to map `JniHandleOwnership` -> `JniObjectReferenceOptions`, such as: internal static JniObjectReferenceOptions ToJniObjectReferenceOptions (JniHandleOwnership transfer)
1 parent de04316 commit cc52218

File tree

21 files changed

+96
-63
lines changed

21 files changed

+96
-63
lines changed

src/Mono.Android/Android.App/Activity.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ namespace Android.App {
66

77
partial class Activity {
88

9-
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
10-
119
public T? FindViewById<
12-
[DynamicallyAccessedMembers (Constructors)]
10+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
1311
T
1412
> (int id)
1513
where T : Android.Views.View
@@ -19,7 +17,7 @@ public T? FindViewById<
1917

2018
// See: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/Activity.java;l=3430
2119
public T RequireViewById<
22-
[DynamicallyAccessedMembers (Constructors)]
20+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
2321
T
2422
> (int id)
2523
where T : Android.Views.View

src/Mono.Android/Android.App/Dialog.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ protected Dialog (Android.Content.Context context, bool cancelable, EventHandler
1010
: this (context, cancelable, new Android.Content.IDialogInterfaceOnCancelListenerImplementor () { Handler = cancelHandler }) {}
1111

1212
public T? FindViewById<
13-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
13+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
1414
T
1515
> (int id)
1616
where T : Android.Views.View

src/Mono.Android/Android.App/FragmentManager.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
#if ANDROID_11
66
namespace Android.App {
77
public partial class FragmentManager {
8-
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
9-
108
public T? FindFragmentById<
11-
[DynamicallyAccessedMembers (Constructors)]
9+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
1210
T
1311
> (int id)
1412
where T : Fragment
@@ -17,7 +15,7 @@ public T? FindFragmentById<
1715
}
1816

1917
public T? FindFragmentByTag<
20-
[DynamicallyAccessedMembers (Constructors)]
18+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
2119
T
2220
> (string tag)
2321
where T : Fragment
@@ -26,7 +24,7 @@ public T? FindFragmentByTag<
2624
}
2725

2826
public T? GetFragment<
29-
[DynamicallyAccessedMembers (Constructors)]
27+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
3028
T
3129
> (Bundle bundle, string key)
3230
where T : Fragment

src/Mono.Android/Android.OS/AsyncTask.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@ namespace Android.OS {
1010
[global::System.Runtime.Versioning.ObsoletedOSPlatform ("android30.0")]
1111
[Register ("android/os/AsyncTask", DoNotGenerateAcw=true)]
1212
public abstract class AsyncTask<
13-
[DynamicallyAccessedMembers (Constructors)]
13+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
1414
TParams,
15-
[DynamicallyAccessedMembers (Constructors)]
15+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
1616
TProgress,
17-
[DynamicallyAccessedMembers (Constructors)]
17+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
1818
TResult
1919
> : AsyncTask {
2020

21-
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
22-
2321
static IntPtr java_class_handle;
2422
internal static IntPtr class_ref {
2523
get {

src/Mono.Android/Android.Runtime/Extensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public static class Extensions {
88

99
[return: NotNullIfNotNull ("instance")]
1010
public static TResult? JavaCast<
11-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
11+
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.Interfaces)]
1212
TResult
1313
> (this IJavaObject? instance)
1414
where TResult : class, IJavaObject

src/Mono.Android/Android.Runtime/JNIEnv.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
namespace Android.Runtime {
1818
public static partial class JNIEnv {
1919
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
20+
const DynamicallyAccessedMemberTypes ConstructorsInterfaces = Constructors | DynamicallyAccessedMemberTypes.Interfaces;
2021

2122
[ThreadStatic]
2223
static byte[]? mvid_bytes;
@@ -322,6 +323,21 @@ public static IntPtr FindClass (System.Type type)
322323
}
323324
}
324325

326+
internal static JniObjectReferenceOptions ToJniObjectReferenceOptions (JniHandleOwnership transfer)
327+
{
328+
switch (transfer) {
329+
case JniHandleOwnership.DoNotTransfer:
330+
return JniObjectReferenceOptions.Copy;
331+
case JniHandleOwnership.TransferGlobalRef:
332+
case JniHandleOwnership.TransferLocalRef:
333+
return JniObjectReferenceOptions.CopyAndDispose;
334+
case JniHandleOwnership.DoNotRegister:
335+
return JniObjectReferenceOptions.CopyAndDoNotRegister;
336+
default:
337+
throw new ArgumentOutOfRangeException (nameof (transfer), transfer, "Invalid JniHandleOwnership value.");
338+
}
339+
}
340+
325341
const int nameBufferLength = 1024;
326342
[ThreadStatic] static char[]? nameBuffer;
327343

@@ -704,7 +720,13 @@ public static void CopyArray (IntPtr src, string[] dest)
704720
AssertIsJavaObject (type);
705721

706722
IntPtr elem = GetObjectArrayElement (source, index);
707-
return Java.Lang.Object.GetObject (elem, JniHandleOwnership.TransferLocalRef, type);
723+
return GetObject (elem, type);
724+
725+
// FIXME: Since a Dictionary<Type, Func> is used here, the trimmer will not be able to properly analyze `Type t`
726+
// error IL2111: Method 'lambda expression' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
727+
[UnconditionalSuppressMessage ("Trimming", "IL2067", Justification = "FIXME: https://github.com/xamarin/xamarin-android/issues/8724")]
728+
static object? GetObject (IntPtr e, Type t) =>
729+
Java.Lang.Object.GetObject (e, JniHandleOwnership.TransferLocalRef, t);
708730
} },
709731
{ typeof (Array), (type, source, index) => {
710732
IntPtr elem = GetObjectArrayElement (source, index);
@@ -1135,7 +1157,7 @@ static int _GetArrayLength (IntPtr array_ptr)
11351157
}
11361158

11371159
public static T[]? GetArray<
1138-
[DynamicallyAccessedMembers (Constructors)]
1160+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
11391161
T
11401162
> (Java.Lang.Object[] array)
11411163
{
@@ -1252,7 +1274,7 @@ static IntPtr GetArrayElementClass<T>(T[] values)
12521274
}
12531275

12541276
public static void CopyObjectArray<
1255-
[DynamicallyAccessedMembers (Constructors)]
1277+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
12561278
T
12571279
>(IntPtr source, T[] destination)
12581280
{

src/Mono.Android/Android.Runtime/JavaArray.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4-
4+
using System.Diagnostics.CodeAnalysis;
55

66
namespace Android.Runtime {
77

88
[Register ("mono/android/runtime/JavaArray", DoNotGenerateAcw=true)]
9-
public sealed class JavaArray<T> : Java.Lang.Object, IList<T> {
9+
public sealed class JavaArray<
10+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
11+
T
12+
> : Java.Lang.Object, IList<T> {
1013

1114
public JavaArray (IntPtr handle, JniHandleOwnership transfer)
1215
: base (handle, transfer)

src/Mono.Android/Android.Runtime/JavaCollection.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ namespace Android.Runtime {
1414
// java.util.Collection allows null values
1515
public class JavaCollection : Java.Lang.Object, System.Collections.ICollection {
1616

17-
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
18-
1917
internal static IntPtr collection_class = JNIEnv.FindClass ("java/util/Collection");
2018

2119
internal static IntPtr id_add;
@@ -151,7 +149,7 @@ internal Java.Lang.Object[] ToArray ()
151149
public void CopyTo (Array array, int array_index)
152150
{
153151
[UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = "JavaCollection<T> constructors are preserved by the MarkJavaObjects trimmer step.")]
154-
[return: DynamicallyAccessedMembers (Constructors)]
152+
[return: DynamicallyAccessedMembers (ConstructorsInterfaces)]
155153
static Type GetElementType (Array array) =>
156154
array.GetType ().GetElementType ();
157155

@@ -211,7 +209,7 @@ public static IntPtr ToLocalJniHandle (ICollection? items)
211209

212210
[Register ("java/util/Collection", DoNotGenerateAcw=true)]
213211
public sealed class JavaCollection<
214-
[DynamicallyAccessedMembers (Constructors)]
212+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
215213
T
216214
> : JavaCollection, ICollection<T> {
217215

src/Mono.Android/Android.Runtime/JavaDictionary.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ namespace Android.Runtime {
1212
// java.util.HashMap allows null keys and values
1313
public class JavaDictionary : Java.Lang.Object, System.Collections.IDictionary {
1414

15-
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
16-
1715
class DictionaryEnumerator : IDictionaryEnumerator {
1816

1917
IEnumerator simple_enumerator;
@@ -399,9 +397,9 @@ public static IntPtr ToLocalJniHandle (IDictionary? dictionary)
399397
//
400398
[Register ("java/util/HashMap", DoNotGenerateAcw=true)]
401399
public class JavaDictionary<
402-
[DynamicallyAccessedMembers (Constructors)]
400+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
403401
K,
404-
[DynamicallyAccessedMembers (Constructors)]
402+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
405403
V
406404
> : JavaDictionary, IDictionary<K, V> {
407405

src/Mono.Android/Android.Runtime/JavaList.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ namespace Android.Runtime {
1010
// java.util.ArrayList allows null values
1111
public partial class JavaList : Java.Lang.Object, System.Collections.IList {
1212

13-
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
1413
internal static readonly JniPeerMembers list_members = new XAPeerMembers ("java/util/List", typeof (JavaList), isInterface: true);
1514

1615
//
@@ -26,7 +25,7 @@ public partial class JavaList : Java.Lang.Object, System.Collections.IList {
2625
//
2726
internal unsafe object? InternalGet (
2827
int location,
29-
[DynamicallyAccessedMembers (Constructors)]
28+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
3029
Type? targetType = null)
3130
{
3231
const string id = "get.(I)Ljava/lang/Object;";
@@ -271,7 +270,7 @@ public unsafe bool Contains (object? item)
271270
public void CopyTo (Array array, int array_index)
272271
{
273272
[UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = "JavaList<T> constructors are preserved by the MarkJavaObjects trimmer step.")]
274-
[return: DynamicallyAccessedMembers (Constructors)]
273+
[return: DynamicallyAccessedMembers (ConstructorsInterfaces)]
275274
static Type GetElementType (Array array) =>
276275
array.GetType ().GetElementType ();
277276

@@ -683,7 +682,7 @@ public virtual Java.Lang.Object [] ToArray ()
683682

684683
[Register ("java/util/ArrayList", DoNotGenerateAcw=true)]
685684
public class JavaList<
686-
[DynamicallyAccessedMembers (Constructors)]
685+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
687686
T
688687
> : JavaList, IList<T> {
689688

src/Mono.Android/Android.Runtime/JavaSet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ public static IntPtr ToLocalJniHandle (ICollection? items)
269269
[Register ("java/util/HashSet", DoNotGenerateAcw=true)]
270270
// java.util.HashSet allows null
271271
public class JavaSet<
272-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
272+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
273273
T
274274
> : JavaSet, ICollection<T> {
275275

src/Mono.Android/Android.Util/SparseArray.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Android.Util
99
{
1010
[Register ("android/util/SparseArray", DoNotGenerateAcw=true)]
1111
public partial class SparseArray<
12-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
12+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
1313
E
1414
> : SparseArray
1515
{

src/Mono.Android/Android.Views/View.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ public enum SystemUiFlags {
1313
#endif
1414

1515
public partial class View {
16-
17-
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
18-
1916
#if ANDROID_16
2017
[Obsolete ("This method uses wrong enum type. Please use PerformAccessibilityAction(Action) instead.")]
2118
public bool PerformAccessibilityAction (GlobalAction action, Bundle arguments)
@@ -25,7 +22,7 @@ public bool PerformAccessibilityAction (GlobalAction action, Bundle arguments)
2522
#endif
2623

2724
public T? FindViewById<
28-
[DynamicallyAccessedMembers (Constructors)]
25+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
2926
T
3027
> (int id)
3128
where T : Android.Views.View
@@ -35,7 +32,7 @@ public T? FindViewById<
3532

3633
// See: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/View.java;l=25322
3734
public T RequireViewById<
38-
[DynamicallyAccessedMembers (Constructors)]
35+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
3936
T
4037
> (int id)
4138
where T : Android.Views.View

src/Mono.Android/Android.Views/Window.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Android.Views {
77
partial class Window {
88

99
public T? FindViewById<
10-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
10+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
1111
T
1212
> (int id)
1313
where T : Android.Views.View

src/Mono.Android/Android.Widget/AdapterView.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public event EventHandler ItemSelectionCleared {
5151

5252
[Register ("android/widget/AdapterView", DoNotGenerateAcw=true)]
5353
public abstract class AdapterView<
54-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
54+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
5555
T
5656
> : AdapterView where T : IAdapter {
5757

src/Mono.Android/Android.Widget/ArrayAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Android.Widget {
99

1010
[Register ("android/widget/ArrayAdapter", DoNotGenerateAcw=true)]
1111
public partial class ArrayAdapter<
12-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
12+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
1313
T
1414
> : ArrayAdapter {
1515

src/Mono.Android/Java.Interop/JavaConvert.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace Java.Interop {
1111

1212
static class JavaConvert {
1313
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
14+
const DynamicallyAccessedMemberTypes ConstructorsInterfaces = Constructors | DynamicallyAccessedMemberTypes.Interfaces;
1415

1516
static Dictionary<Type, Func<IntPtr, JniHandleOwnership, object>> JniHandleConverters = new Dictionary<Type, Func<IntPtr, JniHandleOwnership, object>>() {
1617
{ typeof (bool), (handle, transfer) => {
@@ -109,7 +110,7 @@ static Func<IntPtr, JniHandleOwnership, object> GetJniHandleConverterForType ([D
109110
}
110111

111112
public static T? FromJniHandle<
112-
[DynamicallyAccessedMembers (Constructors)]
113+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
113114
T
114115
>(IntPtr handle, JniHandleOwnership transfer)
115116
{
@@ -118,7 +119,7 @@ public static T? FromJniHandle<
118119
}
119120

120121
public static T? FromJniHandle<
121-
[DynamicallyAccessedMembers (Constructors)]
122+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
122123
T
123124
>(IntPtr handle, JniHandleOwnership transfer, out bool set)
124125
{
@@ -158,7 +159,7 @@ public static T? FromJniHandle<
158159
public static object? FromJniHandle (
159160
IntPtr handle,
160161
JniHandleOwnership transfer,
161-
[DynamicallyAccessedMembers (Constructors)]
162+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
162163
Type? targetType = null)
163164
{
164165
if (handle == IntPtr.Zero) {
@@ -233,7 +234,7 @@ public static T? FromJniHandle<
233234
}
234235

235236
public static T? FromJavaObject<
236-
[DynamicallyAccessedMembers (Constructors)]
237+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
237238
T
238239
>(IJavaObject? value)
239240
{
@@ -242,7 +243,7 @@ public static T? FromJavaObject<
242243
}
243244

244245
public static T? FromJavaObject<
245-
[DynamicallyAccessedMembers (Constructors)]
246+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
246247
T
247248
>(IJavaObject? value, out bool set)
248249
{
@@ -279,7 +280,7 @@ public static T? FromJavaObject<
279280

280281
public static object? FromJavaObject (
281282
IJavaObject value,
282-
[DynamicallyAccessedMembers (Constructors)]
283+
[DynamicallyAccessedMembers (ConstructorsInterfaces)]
283284
Type? targetType = null)
284285
{
285286
if (value == null)

0 commit comments

Comments
 (0)