diff --git a/external/Java.Interop/tests/generator-Tests/Integration-Tests/Compiler.cs b/external/Java.Interop/tests/generator-Tests/Integration-Tests/Compiler.cs index d227479ea1d..57e23183e2a 100644 --- a/external/Java.Interop/tests/generator-Tests/Integration-Tests/Compiler.cs +++ b/external/Java.Interop/tests/generator-Tests/Integration-Tests/Compiler.cs @@ -51,18 +51,7 @@ public static Assembly Compile (Xamarin.Android.Binder.CodeGeneratorOptions opti .ToArray (); // Set up the assemblies we need to reference - var binDir = Path.GetDirectoryName (typeof (BaseGeneratorTest).Assembly.Location); - var facDir = GetFacadesPath (); - - var referencePaths = new[]{ - unitTestFrameworkAssemblyPath, - typeof(object).Assembly.Location, - typeof(Enumerable).Assembly.Location, - typeof(Uri).Assembly.Location, - Path.Combine (binDir, "Java.Interop.dll"), - Path.Combine (facDir, "netstandard.dll"), - Path.Combine (facDir, "System.Runtime.dll"), - }; + var referencePaths = GetReferencePaths (); var references = referencePaths.Select (p => MetadataReference.CreateFromFile (p)).ToArray (); @@ -76,10 +65,43 @@ public static Assembly Compile (Xamarin.Android.Binder.CodeGeneratorOptions opti Console.WriteLine ($"# Trying to compile: {testCommandLine}"); + return Compile (Path.GetFileName (assemblyFileName), syntax_trees, references, out hasErrors, out output, allowWarnings); + } + + public static Assembly CompileSources (IEnumerable sources, out bool hasErrors, out string output) + { + var supportFiles = Directory.EnumerateFiles (Path.Combine (Path.GetDirectoryName (supportFilePath), "SupportFiles"), + "*.cs", SearchOption.AllDirectories); + var parseOptions = new CSharpParseOptions (preprocessorSymbols: new [] { "NET" }); + var syntaxTrees = sources.Concat (supportFiles.Select (File.ReadAllText)) + .Select (s => CSharpSyntaxTree.ParseText (s, parseOptions)); + var references = GetReferencePaths ().Select (p => MetadataReference.CreateFromFile (p)); + + return Compile ("GeneratedCallbacks_" + Guid.NewGuid ().ToString ("N"), syntaxTrees, references, out hasErrors, out output, allowWarnings: true); + } + + static string [] GetReferencePaths () + { + var binDir = Path.GetDirectoryName (typeof (BaseGeneratorTest).Assembly.Location); + var facDir = GetFacadesPath (); + return new [] { + unitTestFrameworkAssemblyPath, + typeof (object).Assembly.Location, + typeof (Enumerable).Assembly.Location, + typeof (Uri).Assembly.Location, + Path.Combine (binDir, "Java.Interop.dll"), + Path.Combine (facDir, "netstandard.dll"), + Path.Combine (facDir, "System.Runtime.dll"), + }; + } + + static Assembly Compile (string assemblyName, IEnumerable syntaxTrees, IEnumerable references, + out bool hasErrors, out string output, bool allowWarnings) + { // Compile! var compilation = CSharpCompilation.Create ( - Path.GetFileName (assemblyFileName), - syntaxTrees: syntax_trees, + assemblyName, + syntaxTrees: syntaxTrees, references: references, options: new CSharpCompilationOptions (OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true)); diff --git a/external/Java.Interop/tests/generator-Tests/Unit-Tests/UnmanagedCallersOnlyCallbackTests.cs b/external/Java.Interop/tests/generator-Tests/Unit-Tests/UnmanagedCallersOnlyCallbackTests.cs new file mode 100644 index 00000000000..153b5bf323f --- /dev/null +++ b/external/Java.Interop/tests/generator-Tests/Unit-Tests/UnmanagedCallersOnlyCallbackTests.cs @@ -0,0 +1,537 @@ +using System; +using System.Linq; +using System.Reflection; +using NUnit.Framework; +using MonoDroid.Generation; +using Xamarin.Android.Binder; + +namespace generatortests +{ + /// + /// Tests for the experimental direct-[UnmanagedCallersOnly] binding callback shape + /// enabled by --lang-features=unmanaged-callers-only-callbacks. + /// + [TestFixture] + class UnmanagedCallersOnlyCallbackTests : CodeGeneratorTestBase + { + protected override CodeGenerationTarget Target => CodeGenerationTarget.XAJavaInterop1; + + protected override CodeGenerationOptions CreateOptions () => new CodeGenerationOptions { + CodeGenerationTarget = Target, + SupportNullableReferenceTypes = true, + UseUnmanagedCallersOnlyCallbacks = true, + UseGlobal = true, + }; + + const string Api = """ + + + + + + + + + + + + + + + + + + + + + + + + + + """; + + string GenerateWidget () + { + var gens = ParseApiDefinition (Api); + return GetGeneratedTypeOutput (gens.Single (g => g.Name == "Widget")); + } + + [Test] + public void CallbacksAreUnmanagedCallersOnlyAndDropConnectors () + { + var source = GenerateWidget (); + + Assert.True (source.Contains ("[global::System.Runtime.InteropServices.UnmanagedCallersOnly]"), source); + + // No `cb_*` delegate cache fields and no `Get*Handler ()` connector methods. + Assert.False (source.Contains ("cb_onLayout"), source); + Assert.False (source.Contains ("static Delegate GetOnLayout_ZIIIIHandler ()"), source); + Assert.False (source.Contains ("static Delegate Get"), source); + + // There is no connector method left to name, so the connector stores the callback name. + Assert.True (source.Contains ("\"onLayout\", \"(ZIIII)V\", \"n_OnLayout\""), source); + } + + [Test] + public void AllScalarCallbackUsesTypedHelper () + { + var source = GenerateWidget (); + + // boolean marshals as a blittable `sbyte`, so the shape is 5 scalars returning void. + Assert.True (source.Contains ( + "global::Java.Interop.JniMarshalTyped.Invoke_SSSSSX (jnienv, native__this, native_changed, left, top, right, bottom, &global::Com.Example.Widget.m3);"), + source); + + // The function-pointer target contains only the projection of the JNI scalars and the + // managed member invocation -- no JNI transition, no peer lookup, no exception handling. + Assert.True (source.Contains ( + "private static void m3 (global::Com.Example.Widget __this, sbyte native_changed, int left, int top, int right, int bottom)"), + source); + Assert.True (source.Contains ("var changed = native_changed != 0;"), source); + Assert.True (source.Contains ("__this.OnLayout (changed, left, top, right, bottom);"), source); + } + + [Test] + public void PeerArgumentAndPeerReturnUseTypedHelper () + { + var source = GenerateWidget (); + + // The peer return is not a type argument: bound methods frequently have covariant + // returns, so the target is typed as IJavaObject. That also keeps the MethodSpec smaller. + Assert.True (source.Contains ( + "global::Java.Interop.JniMarshalTyped.Invoke_OSO (jnienv, native__this, native_peer, flags, &global::Com.Example.Widget.m0);"), + source); + + // The helper owns both the argument peer lookup and the JNI conversion of the result, + // so the target neither calls GetObject () nor ToLocalJniHandle (). + Assert.True (source.Contains ( + "private static global::Android.Runtime.IJavaObject? m0 (global::Com.Example.Widget __this, global::Com.Example.Peer? peer, int flags)"), + source); + Assert.True (source.Contains ("return __this.Attach (peer, flags);"), source); + Assert.False (source.Contains ("m0 (IntPtr jnienv"), source); + } + + [Test] + public void StringShapesFallBackToRawSafeInvoke () + { + var source = GenerateWidget (); + + // Strings need JNI string marshaling the shared typed helper cannot own, so the callback + // stays [UnmanagedCallersOnly] but forwards to the raw SafeInvoke helper. + Assert.True (source.Contains ( + "global::Java.Interop.JniMarshal.SafeInvokeFunc (jnienv, native__this, native_label, &global::Com.Example.Widget.m2);"), + source); + Assert.True (source.Contains ( + "private static IntPtr m2 (IntPtr jnienv, IntPtr native__this, IntPtr native_label)"), + source); + Assert.True (source.Contains ("global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer)"), source); + } + + [Test] + public void ScalarReturnUsesTypedHelper () + { + var source = GenerateWidget (); + + Assert.True (source.Contains ( + "global::Java.Interop.JniMarshalTyped.Invoke_S (jnienv, native__this, &global::Com.Example.Widget.m1);"), + source); + Assert.True (source.Contains ("private static int m1 (global::Com.Example.Widget __this)"), source); + } + + [Test] + public void DefaultsAreUnchangedWhenFlagIsOff () + { + options = new CodeGenerationOptions { + CodeGenerationTarget = Target, + SupportNullableReferenceTypes = true, + UseGlobal = true, + }; + generator = options.CreateCodeGenerator (writer); + + var source = GenerateWidget (); + + Assert.False (source.Contains ("UnmanagedCallersOnly"), source); + Assert.False (source.Contains ("JniMarshalTyped"), source); + Assert.True (source.Contains ("cb_onLayout"), source); + Assert.True (source.Contains ("static Delegate GetOnLayout_ZIIIIHandler ()"), source); + } + /// + /// A class with several overloads of the same Java method, plus an interface whose members + /// collide with a class member name, to exercise the disambiguation rules. + /// + const string OverloadApi = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + """; + + string GenerateOverloads (string type = "Registry") + { + var gens = ParseApiDefinition (OverloadApi); + return GetGeneratedTypeOutput (gens.Single (g => g.Name == type)); + } + + /// + /// Generates from a completely fresh generator, so that a second + /// call shares no state at all with the first. + /// + string GenerateFromScratch (string type) + { + builder = new System.Text.StringBuilder (); + writer = new System.IO.StringWriter (builder); + options = CreateOptions (); + generator = options.CreateCodeGenerator (writer); + + return GenerateOverloads (type); + } + + [Test] + public void CallbackNamesDoNotContainJavaSignatures () + { + var source = GenerateWidget (); + + foreach (var name in new [] { "n_OnLayout", "n_Attach", "n_Describe", "n_Count" }) + Assert.True (source.Contains ($"static {(name == "n_Count" ? "int" : "void")} {name} (IntPtr jnienv") || source.Contains ($" {name} (IntPtr jnienv"), $"missing {name}\n{source}"); + + // None of the escaped Java signatures the legacy format appends survive. + Assert.False (source.Contains ("n_OnLayout_ZIIII"), source); + Assert.False (source.Contains ("_Lcom_example_Peer_"), source); + Assert.False (source.Contains ("_Ljava_lang_String_"), source); + } + + [Test] + public void DuplicateManagedNamesAreNumberedDeterministically () + { + var source = GenerateOverloads (); + + // Ordering is by the member's own signature, not by its position in the API + // description, so (I)V < (J)V < (Z)V. + Assert.True (source.Contains ("\"remove\", \"(I)V\", \"n_Remove\")"), source); + Assert.True (source.Contains ("\"remove\", \"(J)V\", \"n_Remove_1\")"), source); + Assert.True (source.Contains ("\"remove\", \"(Z)V\", \"n_Remove_2\")"), source); + + // A name which is unique needs no suffix, and the numbering of an unrelated group does + // not shift it. + Assert.True (source.Contains ("\"clear\", \"()V\", \"n_Clear\")"), source); + + foreach (var name in new [] { "n_Remove", "n_Remove_1", "n_Remove_2", "n_Clear" }) + Assert.True (source.Contains ($"static void {name} (IntPtr jnienv"), $"missing {name}\n{source}"); + } + + [Test] + public void FunctionPointerTargetsAreOpaquePerTypeOrdinals () + { + var source = GenerateOverloads (); + + // Ordinals are assigned in the same deterministic order as the callbacks: Clear first + // (group names are ordered), then the three Remove overloads. + Assert.True (source.Contains ("private static void m0 (global::Com.Example.Registry __this)"), source); + Assert.True (source.Contains ("&global::Com.Example.Registry.m0);"), source); + + foreach (var target in new [] { "m1", "m2", "m3" }) + Assert.True (source.Contains ($"&global::Com.Example.Registry.{target});"), $"missing &{target}\n{source}"); + + Assert.False (source.Contains ("__n_"), source); + } + + [Test] + public void GenerationIsRepeatable () + { + // A second generator run over the same API description must produce byte-identical + // output: nothing in the allocation may depend on a counter that survives a run or on + // the order in which writers were constructed. + Assert.AreEqual (GenerateFromScratch ("Registry"), GenerateFromScratch ("Registry")); + Assert.AreEqual (GenerateFromScratch ("IListener"), GenerateFromScratch ("IListener")); + } + + [Test] + public void InterfaceConnectorsKeepTheirOwnerQualifier () + { + var source = GenerateOverloads ("IListener"); + + // The compact name replaces only the Get*Handler segment; the invoker qualifier which + // tells a reader which type declares the callback is preserved verbatim. + Assert.True (source.Contains ("\"remove\", \"(I)V\", \"n_Remove:Com.Example.IListenerInvoker"), source); + Assert.True (source.Contains ("\"remove\", \"(J)V\", \"n_Remove_1:Com.Example.IListenerInvoker"), source); + + // ... and the invoker really does declare callbacks under those names. + Assert.True (source.Contains ("static void n_Remove (IntPtr jnienv"), source); + Assert.True (source.Contains ("static void n_Remove_1 (IntPtr jnienv"), source); + } + + [Test] + public void JavaNamesAndSignaturesAreUnaffected () + { + var source = GenerateOverloads (); + + // Renaming managed callback infrastructure must not disturb the Java method name or + // JNI signature a JCW declares and RegisterNatives binds. + Assert.True (source.Contains ("[Register (\"remove\", \"(I)V\""), source); + Assert.True (source.Contains ("[Register (\"remove\", \"(J)V\""), source); + Assert.True (source.Contains ("[Register (\"remove\", \"(Z)V\""), source); + Assert.True (source.Contains ("[Register (\"clear\", \"()V\""), source); + } + + [Test] + public void LegacyOutputIsUnchangedWhenFlagIsOff () + { + options = new CodeGenerationOptions { + CodeGenerationTarget = Target, + SupportNullableReferenceTypes = true, + UseGlobal = true, + }; + generator = options.CreateCodeGenerator (writer); + + var source = GenerateOverloads (); + + // Legacy names still carry the escaped Java signature, and the connector still names a + // connector method rather than the callback. + Assert.True (source.Contains ("\"remove\", \"(I)V\", \"GetRemove_IHandler\")"), source); + Assert.True (source.Contains ("static void n_Remove_I (IntPtr jnienv"), source); + Assert.True (source.Contains ("static Delegate GetRemove_IHandler ()"), source); + Assert.False (source.Contains ("n_Remove_1"), source); + Assert.False (source.Contains ("&m0)"), source); + } + + const string CompilationSupport = """ + using System; + delegate long _JniMarshal_PP_J (IntPtr env, IntPtr self); + delegate long _JniMarshal_PPI_J (IntPtr env, IntPtr self, int value); + delegate void _JniMarshal_PPJ_V (IntPtr env, IntPtr self, long value); + delegate void _JniMarshal_PPI_V (IntPtr env, IntPtr self, int value); + namespace Java.Interop { + public static unsafe class JniMarshalTyped { + public static void Invoke_SX (IntPtr env, IntPtr self, T value, delegate* target) + where TSelf : class, Android.Runtime.IJavaObject where T : unmanaged { } + public static T Invoke_S (IntPtr env, IntPtr self, delegate* target) + where TSelf : class, Android.Runtime.IJavaObject where T : unmanaged => default; + public static TResult Invoke_SS (IntPtr env, IntPtr self, T value, delegate* target) + where TSelf : class, Android.Runtime.IJavaObject where T : unmanaged where TResult : unmanaged => default; + } + public static unsafe class JniMarshal { + public static void SafeInvokeAction (IntPtr env, IntPtr self, T1 a, T2 b, delegate* target) { } + public static void SafeInvokeAction (IntPtr env, IntPtr self, T value, delegate* target) { } + public static T SafeInvokeFunc (IntPtr env, IntPtr self, delegate* target) => default; + public static TResult SafeInvokeFunc (IntPtr env, IntPtr self, T value, delegate* target) => default; + } + } + """; + + static Assembly CompileCallbacks (string source) + { + var assembly = Compiler.CompileSources (new [] { + "using System; using Android.Runtime; using Java.Interop; namespace Com.Example {\n" + source + "\n}", + CompilationSupport, + }, out var hasErrors, out var output); + Assert.False (hasErrors, output + "\n" + source); + return assembly; + } + + [TestCase (false, false)] + [TestCase (false, true)] + [TestCase (true, false)] + [TestCase (true, true)] + public void PrimitiveParametersDoNotShadowCallbackTargets (bool isInterface, bool raw) + { + var element = isInterface ? "interface" : "class"; + var api = $$""" + + + + + + <{{element}} name='Widget' extends='java.lang.Object' visibility='public' abstract='{{isInterface.ToString ().ToLowerInvariant ()}}'> + + + {{(raw ? "" : "")}} + + + + + """; + var gens = ParseApiDefinition (api); + var name = isInterface ? "IWidget" : "Widget"; + var source = GetGeneratedTypeOutput (gens.Single (g => g.Name == name)); + var owner = name + (isInterface ? "Invoker" : ""); + + var assembly = CompileCallbacks (source); + Assert.True (source.Contains ($"&global::Com.Example.{owner}.m0)"), source); + Assert.True (source.Contains (raw ? "JniMarshal.SafeInvokeAction" : "JniMarshalTyped.Invoke_SX"), source); + var callback = assembly.GetType ("Com.Example." + owner)?.GetMethod ("n_Work", BindingFlags.Static | BindingFlags.NonPublic); + Assert.IsNotNull (callback); + } + + [Test] + public void InterfacePropertyTargetsUseInvokerOwner () + { + var api = """ + + + + + + + + + + + + """; + var gens = ParseApiDefinition (api); + var source = GetGeneratedTypeOutput (gens.Single (g => g.Name == "IWidget")); + CompileCallbacks (source); + Assert.True (source.Contains ("&global::Com.Example.IWidgetInvoker.m0)"), source); + Assert.True (source.Contains ("&global::Com.Example.IWidgetInvoker.m1)"), source); + } + + [TestCase (false)] + [TestCase (true)] + public void InheritedInterfaceTargetsUseEmittedInvoker (bool raw) + { + var api = $$""" + + + + + + + {{(raw ? "" : "")}} + + + + + + + + """; + foreach (var gen in ParseApiDefinition (api).Where (g => g.Namespace == "Com.Example")) + GetGeneratedTypeOutput (gen); + var source = writer.ToString (); + CompileCallbacks (source); + Assert.True (source.Contains ("&global::Com.Example.IChildInvoker.m0)"), source); + Assert.True (source.Contains ("&global::Com.Example.IParentInvoker.m0)"), source); + } + + [TestCase (false)] + [TestCase (true)] + public void DefaultInterfaceTargetsUseInterfaceOwner (bool raw) + { + options.SupportDefaultInterfaceMethods = true; + var api = $$""" + + + + + + + {{(raw ? "" : "")}} + + + + + """; + var gens = ParseApiDefinition (api); + var source = GetGeneratedTypeOutput (gens.Single (g => g.Name == "IWidget")); + CompileCallbacks (source); + Assert.True (source.Contains ("&global::Com.Example.IWidget.m0)"), source); + } + + [TestCase (true, false, false)] + [TestCase (true, true, false)] + [TestCase (false, false, false)] + [TestCase (true, false, true)] + public void AbstractPropertyOverridesReuseEmittingDeclaration (bool abstractBase, bool redeclareMiddle, bool genericBase) + { + const string property = """ + + + + + """; + var api = $$""" + + + + + {{(genericBase ? "" : "")}} + {{(abstractBase ? property : property.Replace ("abstract='true'", "abstract='false'"))}} + + + + + + + + + {{(redeclareMiddle ? property : "")}} + + + {{property}} + + + + """; + options.AssemblyName = "Callbacks"; + var gens = ParseApiDefinition (api); + foreach (var gen in gens.Where (g => g.Namespace == "Com.Example").Reverse ()) + GetGeneratedTypeOutput (gen); + var source = writer.ToString (); + var assembly = CompileCallbacks (source); + + foreach (var typeName in new [] { "Derived", "DerivedInvoker" }) { + var type = assembly.GetType ("Com.Example." + typeName); + Assert.IsNotNull (type); + var value = type.GetProperty ("Value", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); + Assert.IsNotNull (value); + Assert.Multiple (() => { + AssertInheritedConnector (assembly, value.GetMethod, (genericBase ? "GetGetValueHandler" : "n_GetValue") + ":Com.Example.Base, Callbacks", genericBase); + AssertInheritedConnector (assembly, value.SetMethod, (genericBase ? "GetSetValue_JHandler" : "n_SetValue_1") + ":Com.Example.Base, Callbacks", genericBase); + }); + Assert.False (type.GetMethods (BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.DeclaredOnly) + .Any (m => m.Name.StartsWith ("n_", StringComparison.Ordinal)), source); + } + } + + static void AssertInheritedConnector (Assembly assembly, MethodInfo accessor, string expected, bool legacy) + { + Assert.IsNotNull (accessor); + var register = accessor.GetCustomAttributesData ().Single (a => a.AttributeType.Name == "RegisterAttribute"); + var connector = (string) register.ConstructorArguments [2].Value; + Assert.AreEqual (expected, connector); + var callbackName = connector.Split (':') [0]; + var callback = assembly.GetType ("Com.Example.Base")?.GetMethod (callbackName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + Assert.IsNotNull (callback, connector); + Assert.AreEqual (!legacy, callback.GetCustomAttributesData ().Any (a => a.AttributeType.Name == "UnmanagedCallersOnlyAttribute"), connector); + if (!legacy) { + Assert.AreEqual (accessor.ReturnType, callback.ReturnType, connector); + CollectionAssert.AreEqual (accessor.GetParameters ().Select (p => p.ParameterType), + callback.GetParameters ().Skip (2).Select (p => p.ParameterType), connector); + } + } + } +} diff --git a/external/Java.Interop/tools/generator/CodeGenerationOptions.cs b/external/Java.Interop/tools/generator/CodeGenerationOptions.cs index baabc393364..57c64d2bbe5 100644 --- a/external/Java.Interop/tools/generator/CodeGenerationOptions.cs +++ b/external/Java.Interop/tools/generator/CodeGenerationOptions.cs @@ -66,6 +66,17 @@ public SymbolTable SymbolTable { public bool UseObsoletedOSPlatformAttributes { get; set; } public bool UseRestrictToAttributes { get; set; } public bool FixObsoleteOverrides { get; set; } + + // Experimental: emit each supported non-generic `n_*` binding callback as an + // [UnmanagedCallersOnly] method which forwards to a shared typed marshaling helper, + // and omit the `cb_*` delegate cache field and the `Get*Handler ()` connector method. + public bool UseUnmanagedCallersOnlyCallbacks { get; set; } + + // Compact, deterministic names for the callback infrastructure emitted for + // UseUnmanagedCallersOnlyCallbacks. Shared so that a [Register] connector and the callback + // it names agree even when they are emitted by different source writers. + public generator.SourceWriters.CallbackNameAllocator CallbackNames { get; } = new generator.SourceWriters.CallbackNameAllocator (); + public bool RemoveConstSugar => BuildingCoreAssembly; bool? buildingCoreAssembly; diff --git a/external/Java.Interop/tools/generator/CodeGenerator.cs b/external/Java.Interop/tools/generator/CodeGenerator.cs index d21c4c163b6..d2de49c70e8 100644 --- a/external/Java.Interop/tools/generator/CodeGenerator.cs +++ b/external/Java.Interop/tools/generator/CodeGenerator.cs @@ -84,6 +84,7 @@ static void Run (CodeGeneratorOptions options, DirectoryAssemblyResolver resolve UseObsoletedOSPlatformAttributes = options.UseObsoletedOSPlatformAttributes, UseRestrictToAttributes = options.UseRestrictToAttributes, FixObsoleteOverrides = options.FixObsoleteOverrides, + UseUnmanagedCallersOnlyCallbacks = options.UseUnmanagedCallersOnlyCallbacks, }; var resolverCache = new TypeDefinitionCache (); diff --git a/external/Java.Interop/tools/generator/CodeGeneratorOptions.cs b/external/Java.Interop/tools/generator/CodeGeneratorOptions.cs index b6a564df0c7..be45be8b5b5 100644 --- a/external/Java.Interop/tools/generator/CodeGeneratorOptions.cs +++ b/external/Java.Interop/tools/generator/CodeGeneratorOptions.cs @@ -56,6 +56,7 @@ public CodeGeneratorOptions () public bool SupportNullableReferenceTypes { get; set; } public bool UseRestrictToAttributes { get; set; } public bool FixObsoleteOverrides { get; set;} = true; + public bool UseUnmanagedCallersOnlyCallbacks { get; set; } public bool UseObsoletedOSPlatformAttributes { get; set; } public XmldocStyle XmldocStyle { get; set; } = XmldocStyle.IntelliSense; @@ -109,7 +110,7 @@ public static CodeGeneratorOptions Parse (string[] args) "SDK Platform {VERSION}/API level.", v => opts.ApiLevel = v }, { "lang-features=", - "For internal use. (Flags: interface-constants,default-interface-methods,nested-interface-types,nullable-reference-types,obsoleted-platform-attributes,restrict-to-attributes,do-not-fix-obsolete-overrides)", + "For internal use. (Flags: interface-constants,default-interface-methods,nested-interface-types,nullable-reference-types,obsoleted-platform-attributes,restrict-to-attributes,do-not-fix-obsolete-overrides,unmanaged-callers-only-callbacks)", v => { opts.SupportInterfaceConstants = v?.Contains ("interface-constants") == true; opts.SupportDefaultInterfaceMethods = v?.Contains ("default-interface-methods") == true; @@ -118,6 +119,7 @@ public static CodeGeneratorOptions Parse (string[] args) opts.UseObsoletedOSPlatformAttributes = v?.Contains ("obsoleted-platform-attributes") == true; opts.UseRestrictToAttributes = v?.Contains ("restrict-to-attributes") == true; opts.FixObsoleteOverrides = v?.Contains ("do-not-fix-obsolete-overrides") == false; + opts.UseUnmanagedCallersOnlyCallbacks = v?.Contains ("unmanaged-callers-only-callbacks") == true; }}, { "preserve-enums", "For internal use.", diff --git a/external/Java.Interop/tools/generator/Java.Interop.Tools.Generator.ObjectModel/NamespaceMapping.cs b/external/Java.Interop/tools/generator/Java.Interop.Tools.Generator.ObjectModel/NamespaceMapping.cs index bb27a608761..2c7082c10a1 100644 --- a/external/Java.Interop/tools/generator/Java.Interop.Tools.Generator.ObjectModel/NamespaceMapping.cs +++ b/external/Java.Interop/tools/generator/Java.Interop.Tools.Generator.ObjectModel/NamespaceMapping.cs @@ -25,6 +25,14 @@ public void Generate (CodeGenerationOptions opt, GenerationInfo gen_info) sw.WriteLine (); if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { + // Only the experimental format is marked: the absence of the attribute means + // JavaPeerCallbackFormatAttribute.ConnectorDelegates, so existing bindings and + // existing consumers are unaffected. + if (opt.UseUnmanagedCallersOnlyCallbacks) { + sw.WriteLine ("[assembly:global::Java.Interop.JavaPeerCallbackFormat (global::Java.Interop.JavaPeerCallbackFormatAttribute.UnmanagedCallersOnlyCallbacks)]"); + sw.WriteLine (); + } + foreach (var p in mappings) { sw.WriteLine ($"[assembly:global::Android.Runtime.NamespaceMapping (Java = \"{p.Key}\", Managed=\"{p.Value}\")]"); } diff --git a/external/Java.Interop/tools/generator/SourceWriters/BoundAbstractProperty.cs b/external/Java.Interop/tools/generator/SourceWriters/BoundAbstractProperty.cs index 7e09855283a..330aaa1af6c 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/BoundAbstractProperty.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/BoundAbstractProperty.cs @@ -48,7 +48,7 @@ public BoundAbstractProperty (GenBase gen, Property property, CodeGenerationOpti SourceWriterExtensions.AddSupportedOSPlatform (GetterAttributes, property.Getter, opt); - GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, property.Getter.GetConnectorNameFull (opt), additionalProperties: property.Getter.AdditionalAttributeString ()) { + GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, UnmanagedCallbackSupport.GetPropertyConnectorNameFull (gen, property, property.Getter, opt), additionalProperties: property.Getter.AdditionalAttributeString ()) { MemberType = opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1 ? null : (MemberTypes?) MemberTypes.Method, }); @@ -63,7 +63,7 @@ public BoundAbstractProperty (GenBase gen, Property property, CodeGenerationOpti SourceWriterExtensions.AddSupportedOSPlatform (SetterAttributes, property.Setter, opt); SourceWriterExtensions.AddMethodCustomAttributes (SetterAttributes, property.Setter); - SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, property.Setter.GetConnectorNameFull (opt), additionalProperties: property.Setter.AdditionalAttributeString ()) { + SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, UnmanagedCallbackSupport.GetPropertyConnectorNameFull (gen, property, property.Setter, opt), additionalProperties: property.Setter.AdditionalAttributeString ()) { MemberType = opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1 ? null : (MemberTypes?) MemberTypes.Method, }); } diff --git a/external/Java.Interop/tools/generator/SourceWriters/BoundInterface.cs b/external/Java.Interop/tools/generator/SourceWriters/BoundInterface.cs index f3288ebc37a..b213d1a23de 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/BoundInterface.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/BoundInterface.cs @@ -38,6 +38,11 @@ public BoundInterface (InterfaceGen iface, CodeGenerationOptions opt, CodeGenera UsePriorityOrder = true; + // Renaming happens up front, before any member is written, so that every writer -- and + // in particular the callback name allocator, which snapshots a type's members the first + // time it is asked about one of them -- observes the final managed names. + FixupInvokerMethodNames (iface); + SetVisibility (iface.Visibility); iface.JavadocInfo?.AddJavadocs (Comments); @@ -223,13 +228,20 @@ void AddProperties (InterfaceGen iface, CodeGenerationOptions opt) } } - void AddMethods (InterfaceGen iface, CodeGenerationOptions opt) + // A method whose managed name would collide with the interface itself or with one of its + // properties is prefixed with "Invoke". + static void FixupInvokerMethodNames (InterfaceGen iface) { foreach (var m in iface.Methods.Where (m => !m.IsStatic && !m.IsInterfaceDefaultMethod)) { if (m.Name == iface.Name || iface.ContainsProperty (m.Name, true)) m.Name = "Invoke" + m.Name; + } + } - Methods.Add (new BoundInterfaceMethodDeclaration (m, iface.AssemblyQualifiedName + "Invoker", opt)); + void AddMethods (InterfaceGen iface, CodeGenerationOptions opt) + { + foreach (var m in iface.Methods.Where (m => !m.IsStatic && !m.IsInterfaceDefaultMethod)) { + Methods.Add (new BoundInterfaceMethodDeclaration (iface, m, iface.AssemblyQualifiedName + "Invoker", opt)); } if (!opt.SupportDefaultInterfaceMethods) diff --git a/external/Java.Interop/tools/generator/SourceWriters/BoundInterfaceMethodDeclaration.cs b/external/Java.Interop/tools/generator/SourceWriters/BoundInterfaceMethodDeclaration.cs index 01f8493de42..b215d6b7796 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/BoundInterfaceMethodDeclaration.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/BoundInterfaceMethodDeclaration.cs @@ -16,7 +16,7 @@ public class BoundInterfaceMethodDeclaration : MethodWriter readonly Method method; readonly CodeGenerationOptions opt; - public BoundInterfaceMethodDeclaration (Method method, string adapter, CodeGenerationOptions opt) + public BoundInterfaceMethodDeclaration (GenBase iface, Method method, string adapter, CodeGenerationOptions opt) { this.method = method; this.opt = opt; @@ -44,7 +44,7 @@ public BoundInterfaceMethodDeclaration (Method method, string adapter, CodeGener SourceWriterExtensions.AddSupportedOSPlatform (Attributes, method, opt); - Attributes.Add (new RegisterAttr (method.JavaName, method.JniSignature, method.ConnectorName + ":" + method.GetAdapterName (opt, adapter), additionalProperties: method.AdditionalAttributeString ()) { + Attributes.Add (new RegisterAttr (method.JavaName, method.JniSignature, UnmanagedCallbackSupport.GetConnectorName (iface, method, opt) + ":" + method.GetAdapterName (opt, adapter), additionalProperties: method.AdditionalAttributeString ()) { MemberType = opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1 ? null : (MemberTypes?) MemberTypes.Method, }); diff --git a/external/Java.Interop/tools/generator/SourceWriters/BoundInterfacePropertyDeclaration.cs b/external/Java.Interop/tools/generator/SourceWriters/BoundInterfacePropertyDeclaration.cs index 1031b197a5b..c0234e72726 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/BoundInterfacePropertyDeclaration.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/BoundInterfacePropertyDeclaration.cs @@ -35,7 +35,7 @@ public BoundInterfacePropertyDeclaration (GenBase gen, Property property, string SourceWriterExtensions.AddSupportedOSPlatform (GetterAttributes, property.Getter, opt); - GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, property.Getter.ConnectorName + ":" + property.Getter.GetAdapterName (opt, adapter), additionalProperties: property.Getter.AdditionalAttributeString ()) { + GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, UnmanagedCallbackSupport.GetConnectorName (gen, property.Getter, opt) + ":" + property.Getter.GetAdapterName (opt, adapter), additionalProperties: property.Getter.AdditionalAttributeString ()) { MemberType = opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1 ? null : (MemberTypes?) MemberTypes.Method, }); } @@ -50,7 +50,7 @@ public BoundInterfacePropertyDeclaration (GenBase gen, Property property, string SourceWriterExtensions.AddSupportedOSPlatform (SetterAttributes, property.Setter, opt); - SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, property.Setter.ConnectorName + ":" + property.Setter.GetAdapterName (opt, adapter), additionalProperties: property.Setter.AdditionalAttributeString ()) { + SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, UnmanagedCallbackSupport.GetConnectorName (gen, property.Setter, opt) + ":" + property.Setter.GetAdapterName (opt, adapter), additionalProperties: property.Setter.AdditionalAttributeString ()) { MemberType = opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1 ? null : (MemberTypes?) MemberTypes.Method, }); } diff --git a/external/Java.Interop/tools/generator/SourceWriters/BoundMethod.cs b/external/Java.Interop/tools/generator/SourceWriters/BoundMethod.cs index 747191bce4e..d88c78947e1 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/BoundMethod.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/BoundMethod.cs @@ -82,7 +82,7 @@ public BoundMethod (GenBase type, Method method, CodeGenerationOptions opt, bool SourceWriterExtensions.AddSupportedOSPlatform (Attributes, method, opt); - Attributes.Add (new RegisterAttr (method.JavaName, method.JniSignature, method.IsVirtual ? method.GetConnectorNameFull (opt) : string.Empty, additionalProperties: method.AdditionalAttributeString ()) { + Attributes.Add (new RegisterAttr (method.JavaName, method.JniSignature, method.IsVirtual ? UnmanagedCallbackSupport.GetConnectorNameFull (type, method, opt) : string.Empty, additionalProperties: method.AdditionalAttributeString ()) { MemberType = opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1 ? null : (MemberTypes?) MemberTypes.Method, }); diff --git a/external/Java.Interop/tools/generator/SourceWriters/BoundMethodAbstractDeclaration.cs b/external/Java.Interop/tools/generator/SourceWriters/BoundMethodAbstractDeclaration.cs index 95db2399165..a166c1d3473 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/BoundMethodAbstractDeclaration.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/BoundMethodAbstractDeclaration.cs @@ -62,7 +62,7 @@ public BoundMethodAbstractDeclaration (GenBase gen, Method method, CodeGeneratio SourceWriterExtensions.AddSupportedOSPlatform (Attributes, method, opt); if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { - Attributes.Add (new RegisterAttr (method.JavaName, method.JniSignature, method.ConnectorName, additionalProperties: method.AdditionalAttributeString ())); + Attributes.Add (new RegisterAttr (method.JavaName, method.JniSignature, UnmanagedCallbackSupport.GetConnectorName (impl, method, opt), additionalProperties: method.AdditionalAttributeString ())); } SourceWriterExtensions.AddMethodCustomAttributes (Attributes, method); diff --git a/external/Java.Interop/tools/generator/SourceWriters/BoundProperty.cs b/external/Java.Interop/tools/generator/SourceWriters/BoundProperty.cs index 41b48d88e14..e07fa6f461e 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/BoundProperty.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/BoundProperty.cs @@ -97,7 +97,7 @@ public BoundProperty (GenBase gen, Property property, CodeGenerationOptions opt, GetterComments.Add ($"// Metadata.xml XPath method reference: path=\"{gen.MetadataXPathReference}/method[@name='{property.Getter.JavaName}'{property.Getter.Parameters.GetMethodXPathPredicate ()}]\""); if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { - GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, property.Getter.IsVirtual ? property.Getter.GetConnectorNameFull (opt) : string.Empty, additionalProperties: property.Getter.AdditionalAttributeString ())); + GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, property.Getter.IsVirtual ? UnmanagedCallbackSupport.GetPropertyConnectorNameFull (gen, property, property.Getter, opt) : string.Empty, additionalProperties: property.Getter.AdditionalAttributeString ())); } SourceWriterExtensions.AddMethodBody (GetBody, property.Getter, opt); @@ -112,7 +112,7 @@ public BoundProperty (GenBase gen, Property property, CodeGenerationOptions opt, SourceWriterExtensions.AddMethodCustomAttributes (SetterAttributes, property.Setter); if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { - SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, property.Setter.IsVirtual ? property.Setter.GetConnectorNameFull (opt) : string.Empty, additionalProperties: property.Setter.AdditionalAttributeString ())); + SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, property.Setter.IsVirtual ? UnmanagedCallbackSupport.GetPropertyConnectorNameFull (gen, property, property.Setter, opt) : string.Empty, additionalProperties: property.Setter.AdditionalAttributeString ())); } var pname = property.Setter.Parameters [0].Name; diff --git a/external/Java.Interop/tools/generator/SourceWriters/CallbackNameAllocator.cs b/external/Java.Interop/tools/generator/SourceWriters/CallbackNameAllocator.cs new file mode 100644 index 00000000000..348de96c76b --- /dev/null +++ b/external/Java.Interop/tools/generator/SourceWriters/CallbackNameAllocator.cs @@ -0,0 +1,209 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using MonoDroid.Generation; + +namespace generator.SourceWriters +{ + /// + /// Allocates compact, deterministic CLR names for the generated callback infrastructure of a + /// single emitted type when the experimental [UnmanagedCallersOnly] callback format is + /// enabled. + /// + /// + /// + /// The legacy format names a callback n_{ManagedName}{IDSignature}, where + /// IDSignature is the escaped JNI signature of the parameter list. That is unique by + /// construction, but it puts a full Java signature into the #Strings heap for every one + /// of the ~30,000 callbacks, twice (once for the callback and once for its + /// __n_* marshaling target). + /// + /// + /// This allocator instead names the callback n_{ManagedName}, appending _1, + /// _2, … only when several callbacks in the same emitted type share a managed name. + /// The method-specific function pointer target becomes an opaque per-type ordinal + /// m0, m1, … since it is private, referenced only by &m{N} from the + /// callback in the very same type, and never named in metadata that another assembly reads. + /// + /// + /// Allocation is a pure function of the owning type's own API definition. It never depends on + /// the order in which source writers happen to be constructed, because a + /// [Register] connector emitted by one writer must agree with the callback name emitted + /// by a different writer — sometimes in a different assembly, for interface invokers and + /// default interface methods whose connector carries an explicit owner qualifier. + /// + /// + public sealed class CallbackNameAllocator + { + /// + /// Names allocated for one owning type. Keyed by , which is the + /// legacy unique callback discriminator, so that two instances + /// describing the same Java member — clones produced for inherited or interface members — + /// resolve to the same name. + /// + sealed class TypeAllocation + { + public Dictionary CallbackNames { get; } = new Dictionary (StringComparer.Ordinal); + + public Dictionary TargetNames { get; } = new Dictionary (StringComparer.Ordinal); + + public HashSet UsedCallbackNames { get; } = new HashSet (StringComparer.Ordinal); + } + + readonly Dictionary allocations = new Dictionary (); + + /// + /// The unique-within-a-type discriminator for a callback: exactly the suffix the legacy + /// format appends to n_. + /// + public static string GetMethodKey (Method method) => method.Name + method.IDSignature; + + /// + /// The compact n_* callback name for as declared by + /// . + /// + public string GetCallbackName (GenBase owner, Method method) + { + var allocation = GetAllocation (owner); + var key = GetMethodKey (method); + + if (allocation.CallbackNames.TryGetValue (key, out var name)) + return name; + + return AddFallback (allocation, key).callback; + } + + /// + /// The opaque m{N} name of the method-specific function pointer target for + /// as declared by . + /// + public string GetTargetName (GenBase owner, Method method) + { + var allocation = GetAllocation (owner); + var key = GetMethodKey (method); + + if (allocation.TargetNames.TryGetValue (key, out var name)) + return name; + + return AddFallback (allocation, key).target; + } + + /// + /// A member which is not part of the owning type's own API definition — the generator can + /// emit a callback into a class for an interface member it implements — falls back to the + /// legacy names. They are unique by construction and, unlike an allocation counter, do not + /// depend on the order in which the name happened to be requested. + /// + static (string callback, string target) AddFallback (TypeAllocation allocation, string key) + { + var callback = Disambiguate (allocation, "n_" + key); + allocation.CallbackNames [key] = callback; + + var target = "__" + callback; + allocation.TargetNames [key] = target; + + return (callback, target); + } + + TypeAllocation GetAllocation (GenBase owner) + { + if (allocations.TryGetValue (owner, out var allocation)) + return allocation; + + allocation = Build (owner); + allocations.Add (owner, allocation); + return allocation; + } + + static TypeAllocation Build (GenBase owner) + { + var allocation = new TypeAllocation (); + + // Group by managed name so that the disambiguating index of a member depends only on + // the other members which share its name, and order within a group by the member's own + // signature. Neither depends on the position of unrelated members in the type, which + // keeps the allocation stable when a type is re-read from a reference API description + // in another assembly's generator run. + var groups = GetCallbackCandidates (owner) + .GroupBy (m => m.Name, StringComparer.Ordinal) + .OrderBy (g => g.Key, StringComparer.Ordinal); + + var ordinal = 0; + + foreach (var group in groups) { + var index = 0; + + foreach (var key in group.Select (GetMethodKey).Distinct (StringComparer.Ordinal).OrderBy (k => k, StringComparer.Ordinal)) { + if (allocation.CallbackNames.ContainsKey (key)) + continue; + + var candidate = index == 0 ? "n_" + group.Key : $"n_{group.Key}_{index}"; + + allocation.CallbackNames [key] = Disambiguate (allocation, candidate); + allocation.TargetNames [key] = "m" + ordinal.ToString (System.Globalization.CultureInfo.InvariantCulture); + + index++; + ordinal++; + } + } + + return allocation; + } + + static string Disambiguate (TypeAllocation allocation, string candidate) + { + var name = candidate; + var suffix = 0; + + while (!allocation.UsedCallbackNames.Add (name)) + name = candidate + "_" + (++suffix).ToString (System.Globalization.CultureInfo.InvariantCulture); + + return name; + } + + /// + /// Every member of which the generator may emit a callback for. + /// + /// + /// The inherited interfaces are included because an emitted type declares their members + /// too: a class implements the abstract members of the interfaces it implements, and an + /// interface invoker implements the members of the interfaces its interface derives from. + /// Including them is what makes an allocation collision-free for the type it is emitted + /// into. Note that only the copy in the interface's *own* invoker is ever named by a + /// [Register] connector, so the duplicate copies in derived invokers are free to be + /// numbered differently. + /// + static IEnumerable GetCallbackCandidates (GenBase owner) + { + foreach (var m in GetDeclaredMethods (owner)) + yield return m; + + var inherited = owner switch { + ClassGen klass => klass.GetAllDerivedInterfaces (), + InterfaceGen iface => iface.GetAllDerivedInterfaces (), + _ => null, + }; + + if (inherited is null) + yield break; + + foreach (var iface in inherited) { + foreach (var m in GetDeclaredMethods (iface)) + yield return m; + } + } + + static IEnumerable GetDeclaredMethods (GenBase type) + { + foreach (var m in type.Methods) + yield return m; + + foreach (var p in type.Properties) { + if (p.Getter != null) + yield return p.Getter; + if (p.Setter != null) + yield return p.Setter; + } + } + } +} diff --git a/external/Java.Interop/tools/generator/SourceWriters/GenericExplicitInterfaceImplementationProperty.cs b/external/Java.Interop/tools/generator/SourceWriters/GenericExplicitInterfaceImplementationProperty.cs index ee9880aaa0a..dde1962f642 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/GenericExplicitInterfaceImplementationProperty.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/GenericExplicitInterfaceImplementationProperty.cs @@ -32,7 +32,7 @@ public GenericExplicitInterfaceImplementationProperty (Property property, Generi SourceWriterExtensions.AddSupportedOSPlatform (GetterAttributes, property.Getter, opt); if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { - GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, property.Getter.ConnectorName + ":" + property.Getter.GetAdapterName (opt, adapter), additionalProperties: property.Getter.AdditionalAttributeString ())); + GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, UnmanagedCallbackSupport.GetConnectorName (gen.Gen, property.Getter, opt) + ":" + property.Getter.GetAdapterName (opt, adapter), additionalProperties: property.Getter.AdditionalAttributeString ())); } if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1 && @@ -72,7 +72,7 @@ public GenericExplicitInterfaceImplementationProperty (Property property, Generi SourceWriterExtensions.AddSupportedOSPlatform (SetterAttributes, property.Setter, opt); if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { - SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, property.Setter.ConnectorName + ":" + property.Setter.GetAdapterName (opt, adapter), additionalProperties: property.Setter.AdditionalAttributeString ())); + SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, UnmanagedCallbackSupport.GetConnectorName (gen.Gen, property.Setter, opt) + ":" + property.Setter.GetAdapterName (opt, adapter), additionalProperties: property.Setter.AdditionalAttributeString ())); } // Temporarily rename the parameter to "value" diff --git a/external/Java.Interop/tools/generator/SourceWriters/InterfaceInvokerMethod.cs b/external/Java.Interop/tools/generator/SourceWriters/InterfaceInvokerMethod.cs index 2760627f763..e4efc765071 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/InterfaceInvokerMethod.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/InterfaceInvokerMethod.cs @@ -27,7 +27,7 @@ public InterfaceInvokerMethod (InterfaceGen iface, Method method, CodeGeneration IsStatic = method.IsStatic; if (opt.CodeGenerationTarget != CodeGenerationTarget.JavaInterop1) { - method_callback = new MethodCallback (iface, method, opt, null, method.IsReturnCharSequence); + method_callback = new MethodCallback (iface, method, opt, null, method.IsReturnCharSequence, iface.FullName + "Invoker"); } SourceWriterExtensions.AddSupportedOSPlatform (Attributes, method, opt); diff --git a/external/Java.Interop/tools/generator/SourceWriters/InterfaceInvokerProperty.cs b/external/Java.Interop/tools/generator/SourceWriters/InterfaceInvokerProperty.cs index 2ce7e859869..c62431ccd11 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/InterfaceInvokerProperty.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/InterfaceInvokerProperty.cs @@ -32,12 +32,12 @@ public InterfaceInvokerProperty (InterfaceGen iface, Property property, CodeGene if (property.Getter != null) { HasGet = true; - getter_callback = new MethodCallback (iface, property.Getter, opt, property.AdjustedName, false); + getter_callback = new MethodCallback (iface, property.Getter, opt, property.AdjustedName, false, iface.FullName + "Invoker"); } if (property.Setter != null) { HasSet = true; - setter_callback = new MethodCallback (iface, property.Setter, opt, property.AdjustedName, false); + setter_callback = new MethodCallback (iface, property.Setter, opt, property.AdjustedName, false, iface.FullName + "Invoker"); } if (HasGet) { diff --git a/external/Java.Interop/tools/generator/SourceWriters/MethodCallback.cs b/external/Java.Interop/tools/generator/SourceWriters/MethodCallback.cs index 84375400266..01324b64a0e 100644 --- a/external/Java.Interop/tools/generator/SourceWriters/MethodCallback.cs +++ b/external/Java.Interop/tools/generator/SourceWriters/MethodCallback.cs @@ -16,16 +16,20 @@ public class MethodCallback : MethodWriter readonly string property_name; readonly bool is_formatted; readonly CodeGenerationOptions opt; + readonly string target_name; + readonly string declaring_type; readonly FieldWriter delegate_field; readonly MethodWriter delegate_getter; + readonly UnmanagedCallbackKind kind; + readonly TypedCallbackShape typed_shape; // static sbyte n_ByteValueExact (IntPtr jnienv, IntPtr native__this) // { // var __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); // return __this.ByteValueExact (); // } - public MethodCallback (GenBase type, Method method, CodeGenerationOptions options, string propertyName, bool isFormatted) + public MethodCallback (GenBase type, Method method, CodeGenerationOptions options, string propertyName, bool isFormatted, string declaringType = null) { this.type = type; this.method = method; @@ -34,15 +38,34 @@ public MethodCallback (GenBase type, Method method, CodeGenerationOptions option is_formatted = isFormatted; opt = options; - delegate_field = new MethodCallbackDelegateField (method, options); - delegate_getter = new GetDelegateHandlerMethod (method, options); + kind = UnmanagedCallbackSupport.GetCallbackKind (type, method, options, propertyName, isFormatted); + if (kind == UnmanagedCallbackKind.UnmanagedTyped) + UnmanagedCallbackSupport.TryGetTypedShape (type, method, options, propertyName, isFormatted, out typed_shape); - Name = "n_" + method.Name + method.IDSignature; + if (kind == UnmanagedCallbackKind.Legacy) { + delegate_field = new MethodCallbackDelegateField (method, options); + delegate_getter = new GetDelegateHandlerMethod (method, options); + } else { + // The cb_* field and Get*Handler () connector are gone, but the _JniMarshal_* + // delegate *type* is still registered. Mono.Android's hand-written legacy + // JNINativeWrapper wraps a fixed set of these signatures, and dropping the type + // declarations breaks its compilation. Removing them is a further, separate + // saving that requires retiring the reflection-based registration path. + method.GetDelegateType (options); + } + + Name = UnmanagedCallbackSupport.GetCallbackName (type, method, options); + target_name = UnmanagedCallbackSupport.GetCallbackTargetName (type, method, options); + // Interface invokers marshal an interface peer but declare the target on the invoker. + declaring_type = opt.GetOutputName (declaringType ?? type.FullName); ReturnType = new TypeReferenceWriter (method.RetVal.NativeType); IsStatic = true; IsPrivate = method.IsInterfaceDefaultMethod; + if (kind != UnmanagedCallbackKind.Legacy) + Attributes.Add (new CustomAttr ("[global::System.Runtime.InteropServices.UnmanagedCallersOnly]")); + SourceWriterExtensions.AddObsolete (Attributes, null, opt, forceDeprecate: !string.IsNullOrWhiteSpace (method.Deprecated), deprecatedSince: method.DeprecatedSince); SourceWriterExtensions.AddSupportedOSPlatform (Attributes, method, opt); @@ -56,8 +79,14 @@ public MethodCallback (GenBase type, Method method, CodeGenerationOptions option protected override void WriteBody (CodeWriter writer) { - var paramArgs = string.Join ("", method.Parameters.Select (p => $", {opt.GetSafeIdentifier (p.UnsafeNativeName)}")); - var call = $"global::Java.Interop.JniMarshal.{(method.IsVoid ? "SafeInvokeAction" : "SafeInvokeFunc")} (jnienv, native__this{paramArgs}, &__{Name})"; + string call; + if (typed_shape != null) { + call = typed_shape.GetHelperInvocation (declaring_type, target_name); + } else { + var paramArgs = string.Join ("", method.Parameters.Select (p => $", {opt.GetSafeIdentifier (p.UnsafeNativeName)}")); + var target = kind == UnmanagedCallbackKind.Legacy ? target_name : declaring_type + "." + target_name; + call = $"global::Java.Interop.JniMarshal.{(method.IsVoid ? "SafeInvokeAction" : "SafeInvokeFunc")} (jnienv, native__this{paramArgs}, &{target})"; + } writer.WriteLine ("unsafe {"); writer.Indent (); @@ -74,46 +103,71 @@ void WriteMarshalBody (CodeWriter writer) foreach (var attribute in attributes) attribute.WriteAttribute (writer); - writer.WriteLine ($"private static {method.RetVal.NativeType} __{Name} (IntPtr jnienv, IntPtr native__this{method.Parameters.GetCallbackSignature (opt)})"); + if (typed_shape != null) + writer.WriteLine (typed_shape.GetTargetSignature (opt.GetOutputName (type.FullName), target_name, opt.NullableOperator)); + else + writer.WriteLine ($"private static {method.RetVal.NativeType} {target_name} (IntPtr jnienv, IntPtr native__this{method.Parameters.GetCallbackSignature (opt)})"); writer.WriteLine ("{"); writer.Indent (); - writer.WriteLine ($"var __this = global::Java.Lang.Object.GetObject<{opt.GetOutputName (type.FullName)}> (jnienv, native__this, JniHandleOwnership.DoNotTransfer){opt.NullForgivingOperator};"); + if (typed_shape == null) + writer.WriteLine ($"var __this = global::Java.Lang.Object.GetObject<{opt.GetOutputName (type.FullName)}> (jnienv, native__this, JniHandleOwnership.DoNotTransfer){opt.NullForgivingOperator};"); - foreach (var s in method.Parameters.GetCallbackPrep (opt)) + foreach (var s in typed_shape != null ? GetTypedCallbackPrep () : method.Parameters.GetCallbackPrep (opt).Cast ()) writer.WriteLine (s); + // The typed helper owns the JNI conversion of a peer return value, and no typed shape + // has a parameter requiring post-call cleanup, so the `__ret` dance is unnecessary. + var useRetTemporary = typed_shape == null && method.Parameters.HasCleanup; + string ToReturn (string call) => typed_shape != null && typed_shape.ReturnsPeer ? call : method.RetVal.ToNative (opt, call); + if (string.IsNullOrEmpty (property_name)) { var call = "__this." + method.Name + (is_formatted ? "Formatted" : string.Empty) + " (" + method.Parameters.GetCall (opt) + ")"; if (method.IsVoid) writer.WriteLine (call + ";"); else - writer.WriteLine ("{0} {1};", method.Parameters.HasCleanup ? method.RetVal.NativeType + " __ret =" : "return", method.RetVal.ToNative (opt, call)); + writer.WriteLine ("{0} {1};", useRetTemporary ? method.RetVal.NativeType + " __ret =" : "return", ToReturn (call)); } else { if (method.IsVoid) writer.WriteLine ("__this.{0} = {1};", property_name, method.Parameters.GetCall (opt)); else - writer.WriteLine ("{0} {1};", method.Parameters.HasCleanup ? method.RetVal.NativeType + " __ret =" : "return", method.RetVal.ToNative (opt, "__this." + property_name)); + writer.WriteLine ("{0} {1};", useRetTemporary ? method.RetVal.NativeType + " __ret =" : "return", ToReturn ("__this." + property_name)); } - foreach (var cleanup in method.Parameters.GetCallbackCleanup (opt)) - writer.WriteLine (cleanup); + if (typed_shape == null) { + foreach (var cleanup in method.Parameters.GetCallbackCleanup (opt)) + writer.WriteLine (cleanup); + } - if (!method.IsVoid && method.Parameters.HasCleanup) + if (!method.IsVoid && useRetTemporary) writer.WriteLine ("return __ret;"); writer.Unindent (); writer.WriteLine ("}"); } + // Object parameters are marshaled by the shared typed helper and arrive already converted; + // only the pure scalar projections (bool, char, enums) remain for the target method. + IEnumerable GetTypedCallbackPrep () + { + foreach (var p in method.Parameters) { + if (p.NeedsPrep) + continue; + foreach (var line in p.GetPreCallback (opt)) + yield return line; + } + } + public override void Write (CodeWriter writer) { - delegate_field.Write (writer); + delegate_field?.Write (writer); writer.WriteLineNoIndent ("#pragma warning disable 0169"); - delegate_getter.Write (writer); - writer.WriteLine (); + if (delegate_getter != null) { + delegate_getter.Write (writer); + writer.WriteLine (); + } base.Write (writer); WriteMarshalBody (writer); diff --git a/external/Java.Interop/tools/generator/SourceWriters/UnmanagedCallbackSupport.cs b/external/Java.Interop/tools/generator/SourceWriters/UnmanagedCallbackSupport.cs new file mode 100644 index 00000000000..26586b1618f --- /dev/null +++ b/external/Java.Interop/tools/generator/SourceWriters/UnmanagedCallbackSupport.cs @@ -0,0 +1,405 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using MonoDroid.Generation; +using Xamarin.Android.Binder; + +namespace generator.SourceWriters +{ + /// + /// Describes how a single binding callback is emitted when + /// is enabled. + /// + public enum UnmanagedCallbackKind + { + /// + /// The legacy shape: a cb_* delegate cache field, a Get*Handler () connector + /// method, and a managed-callable n_* callback. + /// + Legacy, + + /// + /// An [UnmanagedCallersOnly] n_* callback which forwards the raw JNI + /// arguments to Java.Interop.JniMarshal.SafeInvokeAction/SafeInvokeFunc. Used for + /// shapes whose marshaling cannot be centralized — strings, arrays and other copy-back + /// parameters, CharSequence formatting, collections, and so on. + /// + UnmanagedRaw, + + /// + /// An [UnmanagedCallersOnly] n_* callback which forwards the raw JNI + /// arguments to a Java.Interop.JniMarshalTyped.Invoke_* helper along + /// with a function pointer to a method containing only the managed member invocation. + /// + UnmanagedTyped, + } + + /// + /// Classifies binding callbacks for the experimental direct-[UnmanagedCallersOnly] + /// callback shape, and computes the shared typed-marshaling helper to invoke. + /// + public static class UnmanagedCallbackSupport + { + /// + /// Version of the callback format emitted when the experimental shape is enabled. Kept in + /// sync with Java.Interop.JavaPeerCallbackFormatAttribute.UnmanagedCallersOnlyCallbacks. + /// + public const int UnmanagedCallersOnlyFormatVersion = 2; + + /// + /// Version of the callback format emitted by default. Kept in sync with + /// Java.Interop.JavaPeerCallbackFormatAttribute.ConnectorDelegates. + /// + public const int ConnectorDelegatesFormatVersion = 1; + + public const string TypedMarshalerType = "global::Java.Interop.JniMarshalTyped"; + + // Native (JNI ABI) types which may appear in an [UnmanagedCallersOnly] signature. + // `bool` and `char` are deliberately absent: they are not blittable, so a callback which + // declares them must keep the legacy delegate-based shape. + static readonly HashSet BlittableNativeTypes = new HashSet (StringComparer.Ordinal) { + "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", + "float", "double", "IntPtr", "UIntPtr", "nint", "nuint", + "System.IntPtr", "System.UIntPtr", + }; + + // Native types which the typed helpers accept as an unconstrained scalar argument. This is + // deliberately narrower than BlittableNativeTypes: an IntPtr scalar would be a disguised + // object reference, which the helper must not forward without marshaling it. + static readonly HashSet ScalarNativeTypes = new HashSet (StringComparer.Ordinal) { + "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "double", + }; + + /// + /// Determines how declared on should be + /// emitted. + /// + public static UnmanagedCallbackKind GetCallbackKind (GenBase type, Method method, CodeGenerationOptions opt, string propertyName, bool isFormatted) + { + if (!CanUseUnmanagedCallersOnly (type, method, opt)) + return UnmanagedCallbackKind.Legacy; + + return TryGetTypedShape (type, method, opt, propertyName, isFormatted, out _) + ? UnmanagedCallbackKind.UnmanagedTyped + : UnmanagedCallbackKind.UnmanagedRaw; + } + + /// + /// The CLR name of the n_* callback for , as declared by + /// . + /// + /// + /// Only callbacks which actually become [UnmanagedCallersOnly] are renamed. A + /// callback which keeps the legacy shape also keeps its legacy name and its + /// Get*Handler () connector method, so the reflection-based registration path + /// continues to work for it even inside an assembly marked with the new format. + /// + public static string GetCallbackName (GenBase owner, Method method, CodeGenerationOptions opt) + { + if (!UsesCompactNames (owner, method, opt)) + return "n_" + method.Name + method.IDSignature; + + return opt.CallbackNames.GetCallbackName (owner, method); + } + + /// + /// The CLR name of the method-specific function pointer target invoked by the + /// n_* callback for . + /// + public static string GetCallbackTargetName (GenBase owner, Method method, CodeGenerationOptions opt) + { + if (!UsesCompactNames (owner, method, opt)) + return "__n_" + method.Name + method.IDSignature; + + return opt.CallbackNames.GetTargetName (owner, method); + } + + /// + /// The leading segment of a [Register] connector: either the legacy + /// Get*Handler connector method name, or — for a callback emitted in the new format + /// — the compact n_* callback name itself. + /// + /// + /// A leading n_ is what identifies the compact form to a reader, which is why the + /// callback name is stored verbatim rather than being re-derived from a mangled connector. + /// The optional :Owner, Assembly qualifier that some connectors carry is unaffected + /// and is still appended by the caller. + /// + public static string GetConnectorName (GenBase owner, Method method, CodeGenerationOptions opt) + { + if (!UsesCompactNames (owner, method, opt)) + return method.ConnectorName; + + return opt.CallbackNames.GetCallbackName (owner, method); + } + + /// + /// The full [Register] connector for a member bound on , + /// including the owner qualifier a default interface method requires. Mirrors + /// but resolves the compact name against the + /// type which actually declares the callback. + /// + public static string GetConnectorNameFull (GenBase type, Method method, CodeGenerationOptions opt) + { + var isDefaultInterfaceMethod = opt.SupportDefaultInterfaceMethods && method.IsInterfaceDefaultMethod; + + // Connectors for a default interface method are defined on the interface, not on the + // implementing type, so the callback name must be allocated against the interface. + var owner = isDefaultInterfaceMethod ? method.DeclaringType : type; + var connector = GetConnectorName (owner, method, opt); + + if (!isDefaultInterfaceMethod) + return connector; + + return connector + $":{method.DeclaringType.AssemblyQualifiedName}, " + (method.AssemblyName ?? opt.AssemblyName); + } + + public static string GetPropertyConnectorNameFull (GenBase type, Property property, Method method, CodeGenerationOptions opt) + { + if (!opt.UseUnmanagedCallersOnlyCallbacks) + return GetConnectorNameFull (type, method, opt); + + var owner = type; + var callbackProperty = property; + // Abstract overrides (including their class invokers) reuse the base callbacks. + // Resolve both the name allocation and the format against the emitting declaration. + while (callbackProperty.Getter.IsAbstract && owner.BaseSymbol is GenBase baseType) { + var baseProperty = baseType.GetPropertyByName (property.Name, true); + if (baseProperty == null) + break; + + owner = baseType; + callbackProperty = baseProperty; + // The lookup can skip intermediate classes which do not redeclare the property. + while (!owner.Properties.Contains (callbackProperty) && + owner.BaseSymbol?.GetPropertyByName (property.Name, true) == callbackProperty) + owner = owner.BaseSymbol; + } + + var callbackMethod = method == property.Getter ? callbackProperty.Getter : callbackProperty.Setter; + if (callbackMethod == null) + return GetConnectorNameFull (type, method, opt); + + var connector = GetConnectorNameFull (owner, callbackMethod, opt); + if (owner != type && !(opt.SupportDefaultInterfaceMethods && callbackMethod.IsInterfaceDefaultMethod)) + connector += $":{owner.AssemblyQualifiedName}, " + (callbackMethod.AssemblyName ?? opt.AssemblyName); + return connector; + } + + static bool UsesCompactNames (GenBase owner, Method method, CodeGenerationOptions opt) => + opt != null && opt.UseUnmanagedCallersOnlyCallbacks && CanUseUnmanagedCallersOnly (owner, method, opt); + + /// + /// Returns whether the n_* callback for can carry + /// [UnmanagedCallersOnly] at all. + /// + public static bool CanUseUnmanagedCallersOnly (GenBase type, Method method, CodeGenerationOptions opt) + { + if (opt == null || !opt.UseUnmanagedCallersOnlyCallbacks) + return false; + + // The JavaInterop1 callback shape marshals through JniValueManager and has not been + // evaluated for this experiment. + if (opt.CodeGenerationTarget != CodeGenerationTarget.XAJavaInterop1) + return false; + + // [UnmanagedCallersOnly] cannot be applied to a method of a generic type, because the + // generated entry point would need a type argument that JNI cannot supply. Generic + // declaring types therefore keep the legacy shape. + if (type == null || type.IsGeneric || type.FullName.IndexOf ('<') >= 0) + return false; + + // Neither `method.IsGeneric` nor `method.Parameters.HasGeneric` is consulted here. Both + // report *Java* generics, which are erased to plain object references at the JNI + // boundary, so the emitted `n_*` entry point is non-generic either way and can carry + // [UnmanagedCallersOnly]. Such methods do fall out of the typed shape below, because + // the shared helper cannot know the erased type; they use the raw fallback instead. + if (method.IsStatic) + return false; + + // Every value crossing the boundary must be blittable. + if (!method.IsVoid && !IsBlittableNativeType (method.RetVal.NativeType)) + return false; + + foreach (var p in method.Parameters) { + if (!IsBlittableNativeType (p.NativeType)) + return false; + } + + return true; + } + + /// + /// Attempts to compute the shared typed-marshaling helper which can own the JNI transition, + /// exception reporting, peer lookup and return conversion for . + /// + public static bool TryGetTypedShape (GenBase type, Method method, CodeGenerationOptions opt, string propertyName, bool isFormatted, out TypedCallbackShape shape) + { + shape = null; + + if (isFormatted || method.Parameters.HasCharSequence) + return false; + + // The typed helpers pass `self` as a typed peer; a sender parameter or a parameter + // requiring post-call cleanup would need code the helper cannot own. + foreach (var p in method.Parameters) { + if (p.IsSender) + return false; + if (p.GetPostCallback (opt).Length != 0) + return false; + } + + var argKinds = new StringBuilder (method.Parameters.Count); + var typeArguments = new List { opt.GetOutputName (type.FullName) }; + var targetParameters = new List (); + var forwardedArguments = new List (); + + foreach (var p in method.Parameters) { + if (TryGetPeerType (p.Symbol, opt, out var peerType)) { + argKinds.Append ('O'); + typeArguments.Add (peerType); + targetParameters.Add ($"{peerType}{opt.NullableOperator} {opt.GetSafeIdentifier (p.Name)}"); + forwardedArguments.Add (opt.GetSafeIdentifier (p.UnsafeNativeName)); + continue; + } + + if (!p.NeedsPrep && ScalarNativeTypes.Contains (p.NativeType)) { + argKinds.Append ('S'); + typeArguments.Add (p.NativeType); + targetParameters.Add ($"{p.NativeType} {opt.GetSafeIdentifier (p.UnsafeNativeName)}"); + forwardedArguments.Add (opt.GetSafeIdentifier (p.UnsafeNativeName)); + continue; + } + + return false; + } + + char returnKind; + string targetReturnType; + if (method.IsVoid) { + returnKind = 'X'; + targetReturnType = "void"; + } else if (TryGetPeerType (method.RetVal.Symbol, opt, out _)) { + // Peer returns are not generic in the helper: bound methods frequently have + // covariant returns, so the target must be typed as IJavaObject. This also + // removes one type argument from every MethodSpec of this shape. + returnKind = 'O'; + targetReturnType = "global::Android.Runtime.IJavaObject" + opt.NullableOperator; + } else if (ScalarNativeTypes.Contains (method.RetVal.NativeType)) { + returnKind = 'S'; + targetReturnType = method.RetVal.NativeType; + typeArguments.Add (method.RetVal.NativeType); + } else { + return false; + } + + var pattern = argKinds.ToString (); + if (!IsSupportedPattern (pattern)) + return false; + + shape = new TypedCallbackShape ( + helperName: $"Invoke_{pattern}{returnKind}", + typeArguments: typeArguments, + targetParameters: targetParameters, + forwardedArguments: forwardedArguments, + targetReturnType: targetReturnType, + returnsPeer: returnKind == 'O'); + return true; + } + + /// + /// The set of argument patterns for which JniMarshalTyped provides helpers: every + /// combination for arities 0-3, plus all-scalar shapes up to arity 8. + /// + static bool IsSupportedPattern (string pattern) + { + if (pattern.Length <= 3) + return true; + if (pattern.Length > 8) + return false; + return pattern.All (c => c == 'S'); + } + + static bool IsBlittableNativeType (string nativeType) => + nativeType != null && BlittableNativeTypes.Contains (nativeType); + + /// + /// Returns the managed peer type for a symbol whose callback marshaling is exactly + /// Java.Lang.Object.GetObject<T> (handle, JniHandleOwnership.DoNotTransfer). + /// + /// + /// Symbols which project onto a different managed type than the one they are marshaled as — + /// notably the collection interfaces, which marshal as JavaList/JavaDictionary + /// and are then cast — are rejected, because the helper cannot perform that projection. + /// + static bool TryGetPeerType (ISymbol symbol, CodeGenerationOptions opt, out string peerType) + { + peerType = null; + + if (!(symbol is ClassGen || symbol is InterfaceGen)) + return false; + + var gen = (GenBase) symbol; + if (gen.IsGeneric || gen.FullName.IndexOf ('<') >= 0) + return false; + + if (symbol is IRequireGenericMarshal rgm && rgm.GetGenericJavaObjectTypeOverride () != null) + return false; + + peerType = opt.GetOutputName (gen.FullName); + return true; + } + } + + /// + /// The shared typed-marshaling helper invocation, and the signature of the method-specific + /// function pointer target it calls. + /// + public sealed class TypedCallbackShape + { + public TypedCallbackShape (string helperName, IList typeArguments, IList targetParameters, IList forwardedArguments, string targetReturnType, bool returnsPeer) + { + HelperName = helperName; + TypeArguments = typeArguments; + TargetParameters = targetParameters; + ForwardedArguments = forwardedArguments; + TargetReturnType = targetReturnType; + ReturnsPeer = returnsPeer; + } + + /// Name of the JniMarshalTyped helper, e.g. Invoke_OSX. + public string HelperName { get; } + + /// Type arguments to the helper: the peer type, one per argument, then the return type. + public IList TypeArguments { get; } + + /// Parameters of the method-specific function pointer target, excluding __this. + public IList TargetParameters { get; } + + /// Raw JNI arguments forwarded from the n_* callback to the helper. + public IList ForwardedArguments { get; } + + public string TargetReturnType { get; } + + public bool ReturnsPeer { get; } + + public string GetHelperInvocation (string declaringType, string targetName) + { + var typeArgs = string.Join (", ", TypeArguments); + var args = new StringBuilder ("jnienv, native__this"); + foreach (var a in ForwardedArguments) + args.Append (", ").Append (a); + args.Append (", &").Append (declaringType).Append ('.').Append (targetName); + return $"{UnmanagedCallbackSupport.TypedMarshalerType}.{HelperName}<{typeArgs}> ({args})"; + } + + public string GetTargetSignature (string thisType, string targetName, string nullableOperator) + { + var parameters = new StringBuilder ($"{thisType} __this"); + foreach (var p in TargetParameters) + parameters.Append (", ").Append (p); + return $"private static {TargetReturnType} {targetName} ({parameters})"; + } + } +} diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/Model/TypeMapAssemblyData.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/Model/TypeMapAssemblyData.cs index 03100fa3cae..928c7216800 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/Model/TypeMapAssemblyData.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/Model/TypeMapAssemblyData.cs @@ -302,6 +302,13 @@ sealed record UcoMethodData /// True when this wrapper performs the managed direct-dispatch path. /// public bool UsesExportMethodDispatch => ExportMethodDispatch != null; + + /// + /// True when the callback is already an [UnmanagedCallersOnly] method in its own + /// assembly. No wrapper is emitted for such a callback: RegisterNatives takes its address + /// directly through a MemberRef, because managed code must never call it. + /// + public bool IsDirectUnmanagedCallersOnlyCallback { get; init; } } sealed record UcoWrapperTargetData @@ -440,6 +447,13 @@ sealed record NativeRegistrationData /// same base callback. /// public required UcoWrapperTargetData WrapperTarget { get; init; } + + /// + /// When set, RegisterNatives binds this external [UnmanagedCallersOnly] callback + /// directly and no wrapper is emitted for it. is then only a + /// lookup key. + /// + public UcoMethodData? DirectCallback { get; init; } } /// diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ModelBuilder.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ModelBuilder.cs index 65d6a024180..994a2b1945f 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ModelBuilder.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ModelBuilder.cs @@ -94,6 +94,13 @@ public static TypeMapAssemblyData Build (IReadOnlyList peers, stri foreach (var uco in proxy.UcoMethods) { AddIfCrossAssembly (referencedAssemblies, uco.CallbackType.AssemblyName, assemblyName); } + // Directly-registered [UnmanagedCallersOnly] callbacks have no wrapper in UcoMethods, + // but ldftn still needs access to the (usually private) n_* method. + foreach (var registration in proxy.NativeRegistrations) { + if (registration.DirectCallback is not null) { + AddIfCrossAssembly (referencedAssemblies, registration.DirectCallback.CallbackType.AssemblyName, assemblyName); + } + } if (proxy.ActivationCtor != null && !proxy.ActivationCtor.IsOnLeafType) { AddIfCrossAssembly (referencedAssemblies, proxy.ActivationCtor.DeclaringType.AssemblyName, assemblyName); } @@ -341,6 +348,9 @@ static void BuildUcoMethods (JavaPeerInfo peer, JavaPeerProxyData proxy) JniSignature = mm.JniSignature, CallbackParameterTypeNames = mm.NativeCallbackParameterTypeNames, CallbackReturnTypeName = mm.NativeCallbackReturnTypeName, + // A callback which is already [UnmanagedCallersOnly] is registered directly; a + // generated wrapper would have to managed-call it, which is illegal. + IsDirectUnmanagedCallersOnlyCallback = mm.IsUnmanagedCallersOnlyCallback && !mm.IsExport && !mm.CallManagedMethodDirectly, ExportMethodDispatch = (mm.IsExport || mm.CallManagedMethodDirectly) ? new ExportMethodDispatchData { ManagedMethodName = mm.ManagedMethodName, ParameterTypes = mm.ManagedParameterTypes, @@ -391,7 +401,7 @@ static void BuildNativeRegistrations (TypeMapAssemblyData model) var sharedWrapperTargets = new Dictionary (); foreach (var proxy in model.ProxyTypes) { foreach (var uco in proxy.UcoMethods) { - if (!CanShareUcoWrapper (proxy, uco)) { + if (uco.IsDirectUnmanagedCallersOnlyCallback || !CanShareUcoWrapper (proxy, uco)) { continue; } @@ -405,8 +415,23 @@ static void BuildNativeRegistrations (TypeMapAssemblyData model) foreach (var proxy in model.ProxyTypes) { HashSet? reusedUcoMethods = null; + HashSet? directUcoMethods = null; + foreach (var uco in proxy.UcoMethods) { var wrapperTarget = UcoWrapperTargetData.From (proxy, uco.WrapperName); + + if (uco.IsDirectUnmanagedCallersOnlyCallback) { + (directUcoMethods ??= new ()).Add (uco); + proxy.NativeRegistrations.Add (new NativeRegistrationData { + JniMethodName = uco.CallbackMethodName, + JniSignature = uco.JniSignature, + WrapperMethodName = wrapperTarget.MethodName, + WrapperTarget = wrapperTarget, + DirectCallback = uco, + }); + continue; + } + if (CanReuseUcoWrapper (proxy, uco) && sharedWrapperTargets.TryGetValue (CreateUcoWrapperReuseKey (uco), out var sharedWrapperTarget)) { wrapperTarget = sharedWrapperTarget; @@ -420,6 +445,10 @@ static void BuildNativeRegistrations (TypeMapAssemblyData model) }); } + if (directUcoMethods is not null) { + proxy.UcoMethods.RemoveAll (uco => directUcoMethods.Contains (uco)); + } + if (reusedUcoMethods is not null) { proxy.UcoMethods.RemoveAll (uco => reusedUcoMethods.Contains (uco)); } diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/PEAssemblyBuilder.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/PEAssemblyBuilder.cs index 6434c515e27..50ae0994f86 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/PEAssemblyBuilder.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/PEAssemblyBuilder.cs @@ -691,7 +691,14 @@ public void LoadStaticFieldAddress (FieldDefinitionHandle handle) Push (1); } - public void LoadFunction (MethodDefinitionHandle handle) + public void LoadFunction (MethodDefinitionHandle handle) => LoadFunction ((EntityHandle) handle); + + /// + /// ldftn against an arbitrary method token. The overload + /// exists so RegisterNatives can take the address of an external + /// [UnmanagedCallersOnly] callback through a MemberRef. + /// + public void LoadFunction (EntityHandle handle) { Encoder.OpCode (ILOpCode.Ldftn); Encoder.Token (handle); diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/TypeMapAssemblyEmitter.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/TypeMapAssemblyEmitter.cs index 69611e89afb..8b3b8a98823 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/TypeMapAssemblyEmitter.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/TypeMapAssemblyEmitter.cs @@ -199,7 +199,7 @@ void EmitCore (TypeMapAssemblyData model, bool useSharedTypemapUniverse) _pe.PrepareUtf8Fields (EnumerateNativeRegistrationStrings (model.ProxyTypes)); // Track wrapper targets → handles for RegisterNatives. - var wrapperHandles = new Dictionary (); + var wrapperHandles = new Dictionary (); foreach (var proxy in OrderProxiesForWrapperTargets (model.ProxyTypes)) { EmitProxyType (proxy, wrapperHandles); @@ -624,7 +624,7 @@ ExportMethodDispatchEmitter GetExportMethodDispatchEmitter () return _exportMethodDispatchEmitter; } - void EmitProxyType (JavaPeerProxyData proxy, Dictionary wrapperHandles) + void EmitProxyType (JavaPeerProxyData proxy, Dictionary wrapperHandles) { var metadata = _pe.Metadata; var targetTypeRef = _pe.ResolveTypeRef (proxy.TargetType); @@ -690,6 +690,15 @@ void EmitProxyType (JavaPeerProxyData proxy, Dictionary + /// Builds a MemberRef for the real MCW n_* callback, mirroring its signature. JNI boolean + /// and char are ambiguous (bool/sbyte, char/ushort) across generator versions, so when we could + /// read the real n_* method's signature (NuGet binding implementation assemblies, e.g. + /// AndroidX) we use it exactly. When we couldn't — framework callbacks, because the generator + /// scans the compile-time *reference* assemblies (Microsoft.Android.Ref) which strip the private + /// static n_* methods — we fall back to the blittable encoding (sbyte/ushort). That is + /// correct for those callbacks because framework bindings are always produced by the current + /// (post-#1296) generator. + /// + MemberReferenceHandle CreateCallbackMemberRef (UcoMethodData uco) { var jniParams = JniSignatureHelper.ParseParameterTypes (uco.JniSignature); var returnKind = JniSignatureHelper.ParseReturnType (uco.JniSignature); int paramCount = 2 + jniParams.Count; bool isVoid = returnKind == JniParamKind.Void; - // UCO wrapper signature: uses JNI ABI types (byte for boolean) - Action encodeSig = sig => sig.MethodSignature ().Parameters (paramCount, - rt => { if (isVoid) rt.Void (); else JniSignatureHelper.EncodeClrType (rt.Type (), returnKind); }, - p => { - p.AddParameter ().Type ().IntPtr (); - p.AddParameter ().Type ().IntPtr (); - for (int j = 0; j < jniParams.Count; j++) - JniSignatureHelper.EncodeClrType (p.AddParameter ().Type (), jniParams [j]); - }); - - // Callback member reference: mirror the real MCW n_* method's signature. JNI boolean and char - // are ambiguous (bool/sbyte, char/ushort) across generator versions, so when we could read the - // real n_* method's signature (NuGet binding implementation assemblies, e.g. AndroidX) we use it - // exactly. When we couldn't — framework callbacks, because the generator scans the compile-time - // *reference* assemblies (Microsoft.Android.Ref) which strip the private static n_* methods — we - // fall back to the blittable encoding (sbyte/ushort). That is correct for those callbacks because - // framework bindings are always produced by the current (post-#1296) generator. var capturedParameterTypeNames = uco.CallbackParameterTypeNames; var capturedReturnTypeName = uco.CallbackReturnTypeName; bool hasCapturedCallbackSignature = capturedParameterTypeNames is not null && @@ -1073,7 +1075,27 @@ MethodDefinitionHandle EmitUcoMethod (UcoMethodData uco, JavaPeerProxyData proxy }); var callbackTypeHandle = _pe.ResolveTypeRef (uco.CallbackType); - var callbackRef = _pe.AddMemberRef (callbackTypeHandle, uco.CallbackMethodName, encodeCallbackSig); + return _pe.AddMemberRef (callbackTypeHandle, uco.CallbackMethodName, encodeCallbackSig); + } + + MethodDefinitionHandle EmitUcoMethod (UcoMethodData uco, JavaPeerProxyData proxy) + { + var jniParams = JniSignatureHelper.ParseParameterTypes (uco.JniSignature); + var returnKind = JniSignatureHelper.ParseReturnType (uco.JniSignature); + int paramCount = 2 + jniParams.Count; + bool isVoid = returnKind == JniParamKind.Void; + + // UCO wrapper signature: uses JNI ABI types (byte for boolean) + Action encodeSig = sig => sig.MethodSignature ().Parameters (paramCount, + rt => { if (isVoid) rt.Void (); else JniSignatureHelper.EncodeClrType (rt.Type (), returnKind); }, + p => { + p.AddParameter ().Type ().IntPtr (); + p.AddParameter ().Type ().IntPtr (); + for (int j = 0; j < jniParams.Count; j++) + JniSignatureHelper.EncodeClrType (p.AddParameter ().Type (), jniParams [j]); + }); + + var callbackRef = CreateCallbackMemberRef (uco); var handle = _pe.EmitBody (uco.WrapperName, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, @@ -1597,11 +1619,11 @@ void EncodeUcoConstructorLocals_DefaultConstructor (BlobBuilder blob, EntityHand } void EmitRegisterNatives (JavaPeerProxyData proxy, - Dictionary wrapperHandles) + Dictionary wrapperHandles) { // Filter to only registrations that have corresponding wrapper methods var registrations = proxy.NativeRegistrations; - var validRegs = new List<(NativeRegistrationData Reg, MethodDefinitionHandle Wrapper)> (registrations.Count); + var validRegs = new List<(NativeRegistrationData Reg, EntityHandle Wrapper)> (registrations.Count); foreach (var reg in registrations) { if (wrapperHandles.TryGetValue (reg.WrapperTarget, out var wrapperHandle)) { validRegs.Add ((reg, wrapperHandle)); diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/AssemblyIndex.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/AssemblyIndex.cs index 85109952ec8..8897a00233b 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/AssemblyIndex.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/AssemblyIndex.cs @@ -54,6 +54,21 @@ sealed class AssemblyIndex : IDisposable /// public HashSet ExportedTypeNames { get; } = new (StringComparer.Ordinal); + /// + /// The version declared by the assembly's [assembly: Java.Interop.JavaPeerCallbackFormat] + /// attribute, or when the attribute is + /// absent — an unmarked assembly uses the legacy cb_*/Get*Handler () shape. + /// + public int CallbackFormatVersion { get; private set; } = JavaPeerCallbackFormat.ConnectorDelegates; + + /// + /// True when the assembly's n_* binding callbacks are [UnmanagedCallersOnly] and + /// therefore have no Get*Handler () connector method to bind through. RegisterNatives + /// must point at those callbacks directly rather than at a generated managed-calling wrapper. + /// + public bool UsesUnmanagedCallersOnlyCallbacks => + CallbackFormatVersion == JavaPeerCallbackFormat.UnmanagedCallersOnlyCallbacks; + /// /// Maps forwarded managed type names to the target assembly simple name. /// @@ -122,6 +137,8 @@ void Build () } } + ReadCallbackFormatVersion (); + foreach (var typeHandle in Reader.TypeDefinitions) { var typeDef = Reader.GetTypeDefinition (typeHandle); @@ -416,6 +433,30 @@ bool ImplementsJniNameProviderAttribute (CustomAttribute ca) return false; } + /// + /// Reads [assembly: Java.Interop.JavaPeerCallbackFormat (version)], which declares the + /// shape of the assembly's generated binding callbacks. + /// + void ReadCallbackFormatVersion () + { + if (!Reader.IsAssembly) { + return; + } + + foreach (var caHandle in Reader.GetAssemblyDefinition ().GetCustomAttributes ()) { + var ca = Reader.GetCustomAttribute (caHandle); + if (!IsCustomAttributeMatch (ca, Reader, "Java.Interop", "JavaPeerCallbackFormatAttribute")) { + continue; + } + + var value = ca.DecodeValue (customAttributeTypeProvider); + if (value.FixedArguments.Length == 1 && value.FixedArguments [0].Value is int version) { + CallbackFormatVersion = version; + } + return; + } + } + internal static string? GetCustomAttributeName (CustomAttribute ca, MetadataReader reader) { if (ca.Constructor.Kind == HandleKind.MemberReference) { diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerCallbackFormat.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerCallbackFormat.cs new file mode 100644 index 00000000000..0bf469c1f08 --- /dev/null +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerCallbackFormat.cs @@ -0,0 +1,23 @@ +namespace Microsoft.Android.Sdk.TrimmableTypeMap; + +/// +/// Mirrors the constants on Java.Interop.JavaPeerCallbackFormatAttribute, which declares the +/// shape of an assembly's generated binding callbacks. +/// +static class JavaPeerCallbackFormat +{ + /// + /// The legacy format: a cb_* delegate cache field and a Get*Handler () connector + /// method per callback, with a managed-callable static n_* callback. This is also the + /// interpretation of an assembly which carries no marker attribute at all. + /// + public const int ConnectorDelegates = 1; + + /// + /// The experimental format: each supported n_* callback is an + /// [UnmanagedCallersOnly] method and there are no cb_* fields or + /// Get*Handler () methods. RegisterNatives must bind such callbacks directly, and + /// managed code must never call them. + /// + public const int UnmanagedCallersOnlyCallbacks = 2; +} diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs index b560ec50f54..742de376af6 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs @@ -310,6 +310,14 @@ public sealed record MarshalMethodInfo /// public bool CallManagedMethodDirectly { get; init; } + /// + /// True when the generated n_* callback carries + /// [System.Runtime.InteropServices.UnmanagedCallersOnly]. Such a callback has no + /// Get*Handler () connector method and must never be called from managed code, so + /// RegisterNatives binds its address directly instead of going through a generated wrapper. + /// + public bool IsUnmanagedCallersOnlyCallback { get; init; } + /// /// Java annotations forwarded from the managed method or constructor. /// diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerScanner.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerScanner.cs index b9f60a3c9a3..29df7f68e23 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerScanner.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerScanner.cs @@ -97,31 +97,39 @@ bool TryGetAssemblyIndex (string assemblyName, [NotNullWhen (true)] out Assembly /// names a declaring type (e.g. an *Invoker in another assembly) that type is used; /// otherwise the callback lives on the scanned method's own declaring type. /// - bool TryResolveNativeCallbackType (MethodDefinition methodDef, AssemblyIndex index, - string declaringTypeName, string declaringAssemblyName, - [NotNullWhen (true)] out AssemblyIndex? callbackIndex, out TypeDefinitionHandle callbackTypeHandle) + TypeRefData GetNativeCallbackDeclaringType (TypeRefData declaringType, string? connector) { - if (!declaringTypeName.IsNullOrEmpty ()) { - if (!declaringAssemblyName.IsNullOrEmpty () && - TryResolveType (declaringTypeName, declaringAssemblyName, out callbackTypeHandle, out callbackIndex)) { - return true; + ParseConnectorDeclaringType (connector, out var typeName, out var assemblyName); + if (typeName.IsNullOrEmpty () || + (typeName == declaringType.ManagedTypeName && + (assemblyName.IsNullOrEmpty () || assemblyName == declaringType.AssemblyName))) { + return declaringType; + } + + if (assemblyName.IsNullOrEmpty ()) { + // Prefer the registration's assembly for type-only connectors before searching others. + assemblyName = declaringType.AssemblyName; + if (TryResolveType (typeName, assemblyName, out _, out _)) { + return new TypeRefData { ManagedTypeName = typeName, AssemblyName = assemblyName }; } - // Type-only connector (no assembly), or the named assembly wasn't indexed: - // search every indexed assembly for the type by full name. foreach (var candidate in assemblyCache.Values) { - if (candidate.TypesByFullName.TryGetValue (declaringTypeName, out callbackTypeHandle)) { - callbackIndex = candidate; - return true; + if (candidate.TypesByFullName.ContainsKey (typeName)) { + assemblyName = candidate.AssemblyName; + break; } } - callbackIndex = null; - callbackTypeHandle = default; - return false; } - callbackIndex = index; - callbackTypeHandle = methodDef.GetDeclaringType (); - return true; + return new TypeRefData { ManagedTypeName = typeName, AssemblyName = assemblyName }; + } + + bool MustResolveNativeCallback (TypeRefData callbackType, string registrationAssemblyName) + { + if (TryResolveType (callbackType.ManagedTypeName, callbackType.AssemblyName, out _, out var index) || + TryGetAssemblyIndex (callbackType.AssemblyName, out index)) { + return index.UsesUnmanagedCallersOnlyCallbacks; + } + return TryGetAssemblyIndex (registrationAssemblyName, out index) && index.UsesUnmanagedCallersOnlyCallbacks; } /// @@ -134,10 +142,12 @@ bool TryResolveNativeCallbackType (MethodDefinition methodDef, AssemblyIndex ind /// static bool TryReadNativeCallbackSignature (AssemblyIndex callbackIndex, TypeDefinitionHandle callbackTypeHandle, string nativeCallbackName, int jniParameterCount, - [NotNullWhen (true)] out IReadOnlyList? parameterTypeNames, [NotNullWhen (true)] out string? returnTypeName) + [NotNullWhen (true)] out IReadOnlyList? parameterTypeNames, [NotNullWhen (true)] out string? returnTypeName, + out bool isUnmanagedCallersOnly) { parameterTypeNames = null; returnTypeName = null; + isUnmanagedCallersOnly = false; var reader = callbackIndex.Reader; var typeDef = reader.GetTypeDefinition (callbackTypeHandle); @@ -167,6 +177,8 @@ static bool TryReadNativeCallbackSignature (AssemblyIndex callbackIndex, TypeDef } parameterTypeNames = names; returnTypeName = signature.ReturnType; + isUnmanagedCallersOnly = callbackIndex.UsesUnmanagedCallersOnlyCallbacks && + HasUnmanagedCallersOnlyAttribute (methodDef, reader); return true; } @@ -174,21 +186,50 @@ static bool TryReadNativeCallbackSignature (AssemblyIndex callbackIndex, TypeDef } /// - /// Captures the real n_* callback signature for a callback declared on - /// (used by the base-hierarchy [Register] paths, where the callback always lives on a named base type). + /// True when a generated n_* callback carries + /// [System.Runtime.InteropServices.UnmanagedCallersOnly], meaning it can only be reached + /// through JNI: it has no Get*Handler () connector, and managed code — including a + /// generated forwarding wrapper — must never call it. + /// + static bool HasUnmanagedCallersOnlyAttribute (MethodDefinition methodDef, MetadataReader reader) + { + foreach (var caHandle in methodDef.GetCustomAttributes ()) { + var ca = reader.GetCustomAttribute (caHandle); + if (AssemblyIndex.IsCustomAttributeMatch (ca, reader, "System.Runtime.InteropServices", "UnmanagedCallersOnlyAttribute")) { + return true; + } + } + return false; + } + + /// + /// Captures the real n_* callback signature on the resolved callback owner. A missing callback in + /// the versioned format cannot safely be assumed to be a managed-callable legacy callback. /// - (IReadOnlyList? ParameterTypeNames, string? ReturnTypeName) CaptureNativeCallbackSignature ( - TypeRefData declaringType, string nativeCallbackName, string jniSignature) + (IReadOnlyList? ParameterTypeNames, string? ReturnTypeName, bool IsUnmanagedCallersOnly) CaptureNativeCallbackSignature ( + TypeRefData declaringType, string nativeCallbackName, string jniSignature, bool mustResolve) { if (TryResolveType (declaringType.ManagedTypeName, declaringType.AssemblyName, out var handle, out var index)) { int jniParameterCount = JniSignatureHelper.ParseParameterTypes (jniSignature).Count; - if (TryReadNativeCallbackSignature (index, handle, nativeCallbackName, jniParameterCount, out var parameterTypeNames, out var returnTypeName)) { - return (parameterTypeNames, returnTypeName); + if (TryReadNativeCallbackSignature (index, handle, nativeCallbackName, jniParameterCount, out var parameterTypeNames, out var returnTypeName, out var isUnmanagedCallersOnly)) { + return (parameterTypeNames, returnTypeName, isUnmanagedCallersOnly); } } - return (null, null); + if (mustResolve) { + throw new InvalidOperationException ( + $"Cannot resolve binding callback '{declaringType.ManagedTypeName}.{nativeCallbackName}' with JNI signature '{jniSignature}' in assembly '{declaringType.AssemblyName}'. " + + "The UnmanagedCallersOnly callback format requires the callback's metadata; provide the binding implementation assembly rather than a reference assembly."); + } + return (null, null, false); } + /// + /// True when at least one scanned assembly declares the + /// [UnmanagedCallersOnly] callback format. When no assembly does — the overwhelmingly + /// common case — the scanner skips the extra callback resolution entirely. + /// + bool AnyUnmanagedCallersOnlyAssembly { get; set; } + /// /// Looks up the [Register] JNI name for a type identified by name + assembly. /// @@ -214,6 +255,7 @@ public List Scan (IEnumerable assemblies) var index = AssemblyIndex.Create (assembly.Reader, assembly.Name, assembly.Path); assemblyCache [index.AssemblyName] = index; resolvabilityCache [index.AssemblyName] = new ResolvabilityResult? [index.Reader.TypeDefinitions.Count + 1]; + AnyUnmanagedCallersOnlyAssembly |= index.UsesUnmanagedCallersOnlyCallbacks; } // Key by (managedTypeName, assemblyName) to avoid collisions when two assemblies @@ -1570,9 +1612,12 @@ static TypeRefData SubstituteGenericArguments (TypeRefData type, TypeRefData con var registerInfo = result.Value.Info; bool isConstructor = registerInfo.JniName == "" || registerInfo.JniName == ".ctor"; string nativeCallbackName = GetNativeCallbackName (registerInfo.Connector, methodName, isConstructor); - var (callbackParameterTypeNames, callbackReturnTypeName) = !isConstructor && JniSignatureHelper.HasAmbiguousCallbackType (registerInfo.Signature) - ? CaptureNativeCallbackSignature (result.Value.DeclaringType, nativeCallbackName, registerInfo.Signature) - : (null, null); + var callbackType = GetNativeCallbackDeclaringType (result.Value.DeclaringType, registerInfo.Connector); + var (callbackParameterTypeNames, callbackReturnTypeName, isUnmanagedCallersOnlyCallback) = + !isConstructor && (JniSignatureHelper.HasAmbiguousCallbackType (registerInfo.Signature) || AnyUnmanagedCallersOnlyAssembly) + ? CaptureNativeCallbackSignature (callbackType, nativeCallbackName, registerInfo.Signature, + MustResolveNativeCallback (callbackType, result.Value.DeclaringType.AssemblyName)) + : (null, null, false); return new MarshalMethodInfo { JniName = registerInfo.JniName, JniSignature = registerInfo.Signature, @@ -1581,10 +1626,11 @@ static TypeRefData SubstituteGenericArguments (TypeRefData type, TypeRefData con NativeCallbackName = nativeCallbackName, NativeCallbackParameterTypeNames = callbackParameterTypeNames, NativeCallbackReturnTypeName = callbackReturnTypeName, + IsUnmanagedCallersOnlyCallback = isUnmanagedCallersOnlyCallback, IsConstructor = isConstructor, - DeclaringTypeName = result.Value.DeclaringType.ManagedTypeName, - DeclaringAssemblyName = result.Value.DeclaringType.AssemblyName, - DeclaringType = result.Value.DeclaringType, + DeclaringTypeName = callbackType.ManagedTypeName, + DeclaringAssemblyName = callbackType.AssemblyName, + DeclaringType = callbackType, Annotations = annotationParser.Parse (derivedMethod.GetCustomAttributes (), index), }; } @@ -1622,9 +1668,12 @@ static TypeRefData SubstituteGenericArguments (TypeRefData type, TypeRefData con var propRegister = TryGetPropertyRegisterInfo (basePropDef, baseIndex); if (propRegister is not null && propRegister.Signature is not null) { string nativeCallbackName = GetNativeCallbackName (propRegister.Connector, getterName, false); - var (callbackParameterTypeNames, callbackReturnTypeName) = JniSignatureHelper.HasAmbiguousCallbackType (propRegister.Signature) - ? CaptureNativeCallbackSignature (baseTypeRef, nativeCallbackName, propRegister.Signature) - : (null, null); + var callbackType = GetNativeCallbackDeclaringType (baseTypeRef, propRegister.Connector); + var (callbackParameterTypeNames, callbackReturnTypeName, isUnmanagedCallersOnlyCallback) = + JniSignatureHelper.HasAmbiguousCallbackType (propRegister.Signature) || AnyUnmanagedCallersOnlyAssembly + ? CaptureNativeCallbackSignature (callbackType, nativeCallbackName, propRegister.Signature, + MustResolveNativeCallback (callbackType, baseIndex.AssemblyName)) + : (null, null, false); return new MarshalMethodInfo { JniName = propRegister.JniName, JniSignature = propRegister.Signature, @@ -1633,10 +1682,11 @@ static TypeRefData SubstituteGenericArguments (TypeRefData type, TypeRefData con NativeCallbackName = nativeCallbackName, NativeCallbackParameterTypeNames = callbackParameterTypeNames, NativeCallbackReturnTypeName = callbackReturnTypeName, + IsUnmanagedCallersOnlyCallback = isUnmanagedCallersOnlyCallback, IsConstructor = false, - DeclaringTypeName = baseTypeRef.ManagedTypeName, - DeclaringAssemblyName = baseTypeRef.AssemblyName, - DeclaringType = baseTypeRef, + DeclaringTypeName = callbackType.ManagedTypeName, + DeclaringAssemblyName = callbackType.AssemblyName, + DeclaringType = callbackType, Annotations = annotationParser.Parse (derivedGetter.GetCustomAttributes (), derivedIndex), }; } @@ -1714,12 +1764,17 @@ void AddMarshalMethod (List methods, RegisterInfo registerInf // this method currently dispatches directly — a caller may re-target it to n_* forwarding. IReadOnlyList? nativeCallbackParameterTypeNames = null; string? nativeCallbackReturnTypeName = null; - if (!isConstructor && !isExport && JniSignatureHelper.HasAmbiguousCallbackType (jniSignature) && - TryResolveNativeCallbackType (methodDef, index, declaringTypeName, declaringAssemblyName, out var callbackIndex, out var callbackTypeHandle)) { - int jniParameterCount = JniSignatureHelper.ParseParameterTypes (jniSignature).Count; - if (TryReadNativeCallbackSignature (callbackIndex, callbackTypeHandle, nativeCallbackName, jniParameterCount, out var capturedParams, out var capturedReturn)) { - nativeCallbackParameterTypeNames = capturedParams; - nativeCallbackReturnTypeName = capturedReturn; + bool isUnmanagedCallersOnlyCallback = false; + if (!isConstructor && !isExport && + (JniSignatureHelper.HasAmbiguousCallbackType (jniSignature) || AnyUnmanagedCallersOnlyAssembly)) { + var callbackType = GetNativeCallbackDeclaringType ( + index.GetTypeRef (methodDef.GetDeclaringType (), rawTypeKind: 0), registerInfo.Connector); + (nativeCallbackParameterTypeNames, nativeCallbackReturnTypeName, isUnmanagedCallersOnlyCallback) = + CaptureNativeCallbackSignature (callbackType, nativeCallbackName, jniSignature, + !callManagedMethodDirectly && MustResolveNativeCallback (callbackType, index.AssemblyName)); + if (!declaringTypeName.IsNullOrEmpty ()) { + declaringTypeName = callbackType.ManagedTypeName; + declaringAssemblyName = callbackType.AssemblyName; } } @@ -1747,6 +1802,7 @@ void AddMarshalMethod (List methods, RegisterInfo registerInf ThrownNames = exportInfo?.ThrownNames, SuperArgumentsString = exportInfo?.SuperArgumentsString, CallManagedMethodDirectly = callManagedMethodDirectly, + IsUnmanagedCallersOnlyCallback = isUnmanagedCallersOnlyCallback, Annotations = exportInfo?.IsField == true ? [] : annotationParser.Parse (methodDef.GetCustomAttributes (), index), }); } @@ -2737,10 +2793,22 @@ bool ExtendsJavaPeer (TypeDefinitionHandle typeHandle, TypeDefinition typeDef, A /// /// Derives the native callback method name from a [Register] attribute's Connector field. - /// The Connector may be a simple name like "GetOnCreate_Landroid_os_Bundle_Handler" - /// or a qualified name like "GetOnClick_Landroid_view_View_Handler:Android.Views.View/IOnClickListenerInvoker, Mono.Android, …". - /// In both cases the result is e.g. "n_OnCreate_Landroid_os_Bundle_". - /// Falls back to "n_{managedName}" when the Connector doesn't follow the expected pattern. + /// + /// A legacy connector names the Get*Handler connector method, either bare + /// ("GetOnCreate_Landroid_os_Bundle_Handler") or with a type qualifier + /// ("GetOnClick_Landroid_view_View_Handler:Android.Views.View/IOnClickListenerInvoker, Mono.Android, …"), + /// and the callback name is recovered by rewriting Get…Handler to n_…. + /// + /// + /// An assembly using the version 2 format has no + /// connector method for a callback which became [UnmanagedCallersOnly]; there is nothing + /// left to derive a name from, because the callback name no longer encodes the Java signature. + /// Such a connector therefore stores the callback name itself, keeping any type qualifier: + /// "n_OnClick_1:Android.Views.View/IOnClickListenerInvoker, Mono.Android, …". The + /// leading n_ is what distinguishes the two forms — no legacy connector method name can + /// begin with it, since they all begin with Get. + /// + /// Falls back to "n_{managedName}" when the Connector doesn't follow either pattern. /// static string GetNativeCallbackName (string? connector, string managedName, bool isConstructor) { @@ -2753,6 +2821,10 @@ static string GetNativeCallbackName (string? connector, string managedName, bool int colonIndex = connector.IndexOf (':'); string handlerName = colonIndex >= 0 ? connector.Substring (0, colonIndex) : connector; + if (handlerName.StartsWith ("n_", StringComparison.Ordinal)) { + return handlerName; + } + if (handlerName.StartsWith ("Get", StringComparison.Ordinal) && handlerName.EndsWith ("Handler", StringComparison.Ordinal)) { return "n_" + handlerName.Substring (3, handlerName.Length - 3 - "Handler".Length); diff --git a/src/Mono.Android/Java.Interop/JavaPeerCallbackFormatAttribute.cs b/src/Mono.Android/Java.Interop/JavaPeerCallbackFormatAttribute.cs new file mode 100644 index 00000000000..ff61087a313 --- /dev/null +++ b/src/Mono.Android/Java.Interop/JavaPeerCallbackFormatAttribute.cs @@ -0,0 +1,72 @@ +#nullable enable + +using System; + +namespace Java.Interop { + + /// + /// Declares the version of the binding callback format used by the assembly. + /// + /// + /// + /// Assemblies which do not carry this attribute use the + /// format: every [Register] attribute's Connector names a + /// Get<Method>Handler() method which allocates and returns a delegate wrapping a + /// managed-callable static n_* callback. + /// + /// + /// Assemblies which carry this attribute with set to + /// emit each supported n_* callback as an + /// method and omit + /// the cb_* delegate cache field and the Get<Method>Handler() connector + /// method. Such callbacks must not be invoked from managed code: they can only be + /// registered with JNI via RegisterNatives. The Connector string names the + /// native callback directly, retaining any declaring-type qualifier for a default interface + /// method or interface adapter. Callbacks using the legacy fallback keep their connector method. + /// The typemap generator requires implementation metadata to distinguish the two callback shapes + /// and reports an error if a callback it needs to register cannot be resolved. + /// + /// + /// The attribute is deliberately versioned rather than boolean so that a future callback shape + /// can be introduced without breaking consumers which understand only earlier versions. A + /// consumer which does not recognize must treat the assembly as + /// unsupported rather than assuming the legacy format. + /// + /// + /// This attribute is an implementation detail of the .NET for Android bindings and the + /// trimmable typemap generator. It is not intended for use by application code. + /// + /// + [AttributeUsage (AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] + public sealed class JavaPeerCallbackFormatAttribute : Attribute { + + /// + /// The legacy format: cb_* delegate fields plus Get*Handler() connector + /// methods, resolved reflectively or by the typemap generator. + /// + public const int ConnectorDelegates = 1; + + /// + /// The experimental format: n_* callbacks are + /// methods and + /// there are no cb_* fields or Get*Handler() methods. + /// + public const int UnmanagedCallersOnlyCallbacks = 2; + + /// + /// Creates a new . + /// + /// + /// One of or . + /// + public JavaPeerCallbackFormatAttribute (int version) + { + Version = version; + } + + /// + /// The callback format version used by the assembly. + /// + public int Version { get; } + } +} diff --git a/src/Mono.Android/Java.Interop/JniMarshalTyped.cs b/src/Mono.Android/Java.Interop/JniMarshalTyped.cs new file mode 100644 index 00000000000..2f9f7824934 --- /dev/null +++ b/src/Mono.Android/Java.Interop/JniMarshalTyped.cs @@ -0,0 +1,1631 @@ +// +// This file is generated from JniMarshalTyped.tt. Do not edit it directly; +// edit the template and re-run `t4 JniMarshalTyped.tt -o JniMarshalTyped.cs`. +// +#nullable enable + +using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +using Android.Runtime; + +namespace Java.Interop { + + /// + /// Typed marshaling helpers shared by the experimental direct-[UnmanagedCallersOnly] + /// binding callback shape. + /// + /// + /// + /// These helpers own everything that would otherwise be duplicated into every generated + /// n_* callback: the JNI transition (BeginMarshalMethod/EndMarshalMethod), + /// GC bridge synchronization, unhandled exception reporting, the managed peer lookup for + /// self, the peer lookup for supported object arguments, and the JNI conversion of a + /// peer return value. + /// + /// + /// Method names encode the shape being marshaled: Invoke_ followed by one + /// character per argument (O = object reference, S = scalar) followed by one + /// character for the return value (X = void, S = scalar, O = object + /// reference). Shapes which are not safely centralizable — strings, arrays and other + /// copy-back parameters, generic and by-ref parameters — are intentionally absent: the + /// generator falls back to + /// and friends for those. + /// + /// + [SuppressMessage ( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Exceptions cannot cross a JNI boundary.")] + public static class JniMarshalTyped { + + const DynamicallyAccessedMemberTypes Constructors = + DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; + + const string PeerLookupFailed = "Unable to marshal the JNI `this` reference to its managed peer."; + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_X<[DynamicallyAccessedMembers (Constructors)] TPeer> (IntPtr jnienv, IntPtr self, delegate* managed body) + where TPeer : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + body (__this); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_S<[DynamicallyAccessedMembers (Constructors)] TPeer, TResult> (IntPtr jnienv, IntPtr self, delegate* managed body) + where TPeer : class, IJavaObject + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return body (__this); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_O<[DynamicallyAccessedMembers (Constructors)] TPeer> (IntPtr jnienv, IntPtr self, delegate* managed body) + where TPeer : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return JNIEnv.ToLocalJniHandle (body (__this)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0> (IntPtr jnienv, IntPtr self, T0 p0, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + body (__this, p0); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, TResult> (IntPtr jnienv, IntPtr self, T0 p0, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return body (__this, p0); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0> (IntPtr jnienv, IntPtr self, T0 p0, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return JNIEnv.ToLocalJniHandle (body (__this, p0)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_OX<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0> (IntPtr jnienv, IntPtr self, IntPtr native_p0, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + body (__this, p0); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_OS<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, TResult> (IntPtr jnienv, IntPtr self, IntPtr native_p0, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + return body (__this, p0); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_OO<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0> (IntPtr jnienv, IntPtr self, IntPtr native_p0, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SSX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + body (__this, p0, p1); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SSS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, TResult> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return body (__this, p0, p1); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SSO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_OSX<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, T1> (IntPtr jnienv, IntPtr self, IntPtr native_p0, T1 p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + body (__this, p0, p1); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_OSS<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, T1, TResult> (IntPtr jnienv, IntPtr self, IntPtr native_p0, T1 p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + return body (__this, p0, p1); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_OSO<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, T1> (IntPtr jnienv, IntPtr self, IntPtr native_p0, T1 p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SOX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, [DynamicallyAccessedMembers (Constructors)] T1> (IntPtr jnienv, IntPtr self, T0 p0, IntPtr native_p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + body (__this, p0, p1); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SOS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, [DynamicallyAccessedMembers (Constructors)] T1, TResult> (IntPtr jnienv, IntPtr self, T0 p0, IntPtr native_p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : class, IJavaObject + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + return body (__this, p0, p1); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SOO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, [DynamicallyAccessedMembers (Constructors)] T1> (IntPtr jnienv, IntPtr self, T0 p0, IntPtr native_p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_OOX<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, [DynamicallyAccessedMembers (Constructors)] T1> (IntPtr jnienv, IntPtr self, IntPtr native_p0, IntPtr native_p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + body (__this, p0, p1); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_OOS<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, [DynamicallyAccessedMembers (Constructors)] T1, TResult> (IntPtr jnienv, IntPtr self, IntPtr native_p0, IntPtr native_p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : class, IJavaObject + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + return body (__this, p0, p1); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_OOO<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, [DynamicallyAccessedMembers (Constructors)] T1> (IntPtr jnienv, IntPtr self, IntPtr native_p0, IntPtr native_p1, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SSSX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SSSS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, TResult> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SSSO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_OSSX<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, T1, T2> (IntPtr jnienv, IntPtr self, IntPtr native_p0, T1 p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : unmanaged + where T2 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_OSSS<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, T1, T2, TResult> (IntPtr jnienv, IntPtr self, IntPtr native_p0, T1 p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : unmanaged + where T2 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + return body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_OSSO<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, T1, T2> (IntPtr jnienv, IntPtr self, IntPtr native_p0, T1 p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : unmanaged + where T2 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SOSX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, [DynamicallyAccessedMembers (Constructors)] T1, T2> (IntPtr jnienv, IntPtr self, T0 p0, IntPtr native_p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : class, IJavaObject + where T2 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SOSS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, [DynamicallyAccessedMembers (Constructors)] T1, T2, TResult> (IntPtr jnienv, IntPtr self, T0 p0, IntPtr native_p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : class, IJavaObject + where T2 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + return body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SOSO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, [DynamicallyAccessedMembers (Constructors)] T1, T2> (IntPtr jnienv, IntPtr self, T0 p0, IntPtr native_p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : class, IJavaObject + where T2 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_OOSX<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, [DynamicallyAccessedMembers (Constructors)] T1, T2> (IntPtr jnienv, IntPtr self, IntPtr native_p0, IntPtr native_p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : class, IJavaObject + where T2 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_OOSS<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, [DynamicallyAccessedMembers (Constructors)] T1, T2, TResult> (IntPtr jnienv, IntPtr self, IntPtr native_p0, IntPtr native_p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : class, IJavaObject + where T2 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + return body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_OOSO<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, [DynamicallyAccessedMembers (Constructors)] T1, T2> (IntPtr jnienv, IntPtr self, IntPtr native_p0, IntPtr native_p1, T2 p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : class, IJavaObject + where T2 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SSOX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, [DynamicallyAccessedMembers (Constructors)] T2> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SSOS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, [DynamicallyAccessedMembers (Constructors)] T2, TResult> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : class, IJavaObject + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + return body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SSOO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, [DynamicallyAccessedMembers (Constructors)] T2> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_OSOX<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, T1, [DynamicallyAccessedMembers (Constructors)] T2> (IntPtr jnienv, IntPtr self, IntPtr native_p0, T1 p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : unmanaged + where T2 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_OSOS<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, T1, [DynamicallyAccessedMembers (Constructors)] T2, TResult> (IntPtr jnienv, IntPtr self, IntPtr native_p0, T1 p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : unmanaged + where T2 : class, IJavaObject + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + return body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_OSOO<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, T1, [DynamicallyAccessedMembers (Constructors)] T2> (IntPtr jnienv, IntPtr self, IntPtr native_p0, T1 p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : unmanaged + where T2 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SOOX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, [DynamicallyAccessedMembers (Constructors)] T1, [DynamicallyAccessedMembers (Constructors)] T2> (IntPtr jnienv, IntPtr self, T0 p0, IntPtr native_p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : class, IJavaObject + where T2 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SOOS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, [DynamicallyAccessedMembers (Constructors)] T1, [DynamicallyAccessedMembers (Constructors)] T2, TResult> (IntPtr jnienv, IntPtr self, T0 p0, IntPtr native_p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : class, IJavaObject + where T2 : class, IJavaObject + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + return body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SOOO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, [DynamicallyAccessedMembers (Constructors)] T1, [DynamicallyAccessedMembers (Constructors)] T2> (IntPtr jnienv, IntPtr self, T0 p0, IntPtr native_p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : class, IJavaObject + where T2 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_OOOX<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, [DynamicallyAccessedMembers (Constructors)] T1, [DynamicallyAccessedMembers (Constructors)] T2> (IntPtr jnienv, IntPtr self, IntPtr native_p0, IntPtr native_p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : class, IJavaObject + where T2 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_OOOS<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, [DynamicallyAccessedMembers (Constructors)] T1, [DynamicallyAccessedMembers (Constructors)] T2, TResult> (IntPtr jnienv, IntPtr self, IntPtr native_p0, IntPtr native_p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : class, IJavaObject + where T2 : class, IJavaObject + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + return body (__this, p0, p1, p2); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_OOOO<[DynamicallyAccessedMembers (Constructors)] TPeer, [DynamicallyAccessedMembers (Constructors)] T0, [DynamicallyAccessedMembers (Constructors)] T1, [DynamicallyAccessedMembers (Constructors)] T2> (IntPtr jnienv, IntPtr self, IntPtr native_p0, IntPtr native_p1, IntPtr native_p2, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : class, IJavaObject + where T1 : class, IJavaObject + where T2 : class, IJavaObject + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + var p0 = global::Java.Lang.Object.GetObject (native_p0, JniHandleOwnership.DoNotTransfer); + var p1 = global::Java.Lang.Object.GetObject (native_p1, JniHandleOwnership.DoNotTransfer); + var p2 = global::Java.Lang.Object.GetObject (native_p2, JniHandleOwnership.DoNotTransfer); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SSSSX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + body (__this, p0, p1, p2, p3); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SSSSS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, TResult> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return body (__this, p0, p1, p2, p3); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SSSSO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2, p3)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SSSSSX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + body (__this, p0, p1, p2, p3, p4); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SSSSSS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4, TResult> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return body (__this, p0, p1, p2, p3, p4); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SSSSSO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2, p3, p4)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SSSSSSX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4, T5> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + body (__this, p0, p1, p2, p3, p4, p5); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SSSSSSS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4, T5, TResult> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return body (__this, p0, p1, p2, p3, p4, p5); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SSSSSSO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4, T5> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2, p3, p4, p5)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SSSSSSSX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4, T5, T6> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + body (__this, p0, p1, p2, p3, p4, p5, p6); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SSSSSSSS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4, T5, T6, TResult> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return body (__this, p0, p1, p2, p3, p4, p5, p6); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SSSSSSSO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4, T5, T6> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2, p3, p4, p5, p6)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe void Invoke_SSSSSSSSX<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4, T5, T6, T7> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + body (__this, p0, p1, p2, p3, p4, p5, p6, p7); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe TResult Invoke_SSSSSSSSS<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4, T5, T6, T7, TResult> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + where TResult : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return body (__this, p0, p1, p2, p3, p4, p5, p6, p7); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe IntPtr Invoke_SSSSSSSSO<[DynamicallyAccessedMembers (Constructors)] TPeer, T0, T1, T2, T3, T4, T5, T6, T7> (IntPtr jnienv, IntPtr self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* managed body) + where TPeer : class, IJavaObject + where T0 : unmanaged + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + where T6 : unmanaged + where T7 : unmanaged + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return default; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); + return JNIEnv.ToLocalJniHandle (body (__this, p0, p1, p2, p3, p4, p5, p6, p7)); + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return default; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } + } +} diff --git a/src/Mono.Android/Java.Interop/JniMarshalTyped.tt b/src/Mono.Android/Java.Interop/JniMarshalTyped.tt new file mode 100644 index 00000000000..605959c6710 --- /dev/null +++ b/src/Mono.Android/Java.Interop/JniMarshalTyped.tt @@ -0,0 +1,185 @@ +<#@ template language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<# + // Argument kinds: + // 'O' — a JNI object reference which is marshaled to a managed peer. + // 'S' — a scalar (JNI primitive) which is forwarded unchanged. + // Return kinds: + // 'X' — void + // 'S' — scalar, forwarded unchanged + // 'O' — managed peer, converted to a JNI local reference + // + // Every combination is emitted for arity 0-3, which covers the overwhelming + // majority of bound virtual/abstract methods. Arity 4-8 only emits the + // all-scalar shape, which covers the remaining high-volume cases such as + // `View.OnLayout (bool, int, int, int, int)`. Anything not covered here + // falls back to `Java.Interop.JniMarshal.SafeInvokeAction/SafeInvokeFunc`. + var patterns = new List (); + for (int arity = 0; arity <= 3; ++arity) { + for (int mask = 0; mask < (1 << arity); ++mask) { + var chars = new char [arity]; + for (int i = 0; i < arity; ++i) + chars [i] = (mask & (1 << i)) != 0 ? 'O' : 'S'; + patterns.Add (new string (chars)); + } + } + for (int arity = 4; arity <= 8; ++arity) + patterns.Add (new string ('S', arity)); +#> +// +// This file is generated from JniMarshalTyped.tt. Do not edit it directly; +// edit the template and re-run `t4 JniMarshalTyped.tt -o JniMarshalTyped.cs`. +// +#nullable enable + +using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +using Android.Runtime; + +namespace Java.Interop { + + /// + /// Typed marshaling helpers shared by the experimental direct-[UnmanagedCallersOnly] + /// binding callback shape. + /// + /// + /// + /// These helpers own everything that would otherwise be duplicated into every generated + /// n_* callback: the JNI transition (BeginMarshalMethod/EndMarshalMethod), + /// GC bridge synchronization, unhandled exception reporting, the managed peer lookup for + /// self, the peer lookup for supported object arguments, and the JNI conversion of a + /// peer return value. + /// + /// + /// Method names encode the shape being marshaled: Invoke_ followed by one + /// character per argument (O = object reference, S = scalar) followed by one + /// character for the return value (X = void, S = scalar, O = object + /// reference). Shapes which are not safely centralizable — strings, arrays and other + /// copy-back parameters, generic and by-ref parameters — are intentionally absent: the + /// generator falls back to + /// and friends for those. + /// + /// + [SuppressMessage ( + "Design", + "CA1031:Do not catch general exception types", + Justification = "Exceptions cannot cross a JNI boundary.")] + public static class JniMarshalTyped { + + const DynamicallyAccessedMemberTypes Constructors = + DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; + + const string PeerLookupFailed = "Unable to marshal the JNI `this` reference to its managed peer."; +<# + foreach (var pattern in patterns) { + foreach (var ret in new [] { 'X', 'S', 'O' }) { + var typeParams = new List () { "[DynamicallyAccessedMembers (Constructors)] TPeer" }; + var constraints = new List () { "where TPeer : class, IJavaObject" }; + var nativeParams = new List (); + var managedArgs = new List (); + var callArgs = new List () { "__this" }; + var conversions = new List (); + + for (int i = 0; i < pattern.Length; ++i) { + var t = "T" + i; + if (pattern [i] == 'O') { + typeParams.Add ($"[DynamicallyAccessedMembers (Constructors)] {t}"); + constraints.Add ($"where {t} : class, IJavaObject"); + nativeParams.Add ($"IntPtr native_p{i}"); + managedArgs.Add (t + "?"); + callArgs.Add ("p" + i); + conversions.Add ($"var p{i} = global::Java.Lang.Object.GetObject<{t}> (native_p{i}, JniHandleOwnership.DoNotTransfer);"); + } else { + typeParams.Add (t); + constraints.Add ($"where {t} : unmanaged"); + nativeParams.Add ($"{t} p{i}"); + managedArgs.Add (t); + callArgs.Add ("p" + i); + } + } + + string returnType, managedReturn; + switch (ret) { + case 'X': + returnType = managedReturn = "void"; + break; + case 'S': + typeParams.Add ("TResult"); + constraints.Add ("where TResult : unmanaged"); + returnType = managedReturn = "TResult"; + break; + default: + // A peer return is deliberately *not* generic. Bound methods frequently have + // covariant returns (e.g. IChronoLocalDate.Minus returns ITemporal), so pinning + // the target's return type to the declared type does not compile. All the helper + // needs is IJavaObject, and dropping the type parameter also shrinks every + // MethodSpec for this shape. + returnType = "IntPtr"; + managedReturn = "IJavaObject?"; + break; + } + + var name = "Invoke_" + pattern + ret; + var fnPtr = "delegate* managed a + ", ")) + managedReturn + ">"; + var parameters = "IntPtr jnienv, IntPtr self" + + string.Join ("", nativeParams.Select (p => ", " + p)) + + ", " + fnPtr + " body"; + var invocation = $"body ({string.Join (", ", callArgs)})"; +#> + + [DebuggerDisableUserUnhandledExceptions] + public static unsafe <#= returnType #> <#= name #><<#= string.Join (", ", typeParams) #>> (<#= parameters #>) +<# + foreach (var constraint in constraints) { +#> + <#= constraint #> +<# + } +#> + { + AndroidRuntimeInternal.WaitForBridgeProcessing (); + + if (!JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r)) + return<#= ret == 'X' ? "" : " default" #>; + + try { + var __this = global::Java.Lang.Object.GetObject (self, JniHandleOwnership.DoNotTransfer); + if (__this is null) + throw new NullReferenceException (PeerLookupFailed); +<# + foreach (var conversion in conversions) { +#> + <#= conversion #> +<# + } + if (ret == 'X') { +#> + <#= invocation #>; +<# + } else if (ret == 'S') { +#> + return <#= invocation #>; +<# + } else { +#> + return JNIEnv.ToLocalJniHandle (<#= invocation #>); +<# + } +#> + } catch (Exception __e) { + __r.OnUserUnhandledException (ref __envp, __e); + return<#= ret == 'X' ? "" : " default" #>; + } finally { + JniEnvironment.EndMarshalMethod (ref __envp); + } + } +<# + } + } +#> + } +} diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index a8b5764cad1..460e9d5cb1e 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -320,8 +320,10 @@ + + diff --git a/src/Mono.Android/Mono.Android.targets b/src/Mono.Android/Mono.Android.targets index 912294a3b63..c6f94590be7 100644 --- a/src/Mono.Android/Mono.Android.targets +++ b/src/Mono.Android/Mono.Android.targets @@ -142,6 +142,11 @@ <_LangFeatures>--lang-features=nullable-reference-types <_LangFeatures Condition="$(AndroidApiLevel) >= 30">$(_LangFeatures),default-interface-methods,nested-interface-types,interface-constants <_LangFeatures Condition=" $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '7.0')) ">$(_LangFeatures),obsoleted-platform-attributes + + <_LangFeatures Condition=" '$(_MonoAndroidEnableUnmanagedCallersOnlyCallbacks)' == 'true' ">$(_LangFeatures),unmanaged-callers-only-callbacks ../../tests/api-compatibility + + True diff --git a/src/Mono.Android/PublicAPI/API-35/PublicAPI.Unshipped.txt b/src/Mono.Android/PublicAPI/API-35/PublicAPI.Unshipped.txt index 96701c76f82..f99d6a95964 100644 --- a/src/Mono.Android/PublicAPI/API-35/PublicAPI.Unshipped.txt +++ b/src/Mono.Android/PublicAPI/API-35/PublicAPI.Unshipped.txt @@ -1,5 +1,11 @@ #nullable enable -static Android.Runtime.JNIEnv.BridgeProcessingGeneration.get -> int +Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.get -> bool +Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.set -> void +Java.Interop.BaseExportAttribute +Java.Interop.JavaPeerCallbackFormatAttribute +Java.Interop.JavaPeerCallbackFormatAttribute.JavaPeerCallbackFormatAttribute(int version) -> void +Java.Interop.JavaPeerCallbackFormatAttribute.Version.get -> int +Java.Interop.JniMarshalTyped REMOVED Xamarin.Android.Net.AndroidClientHandler REMOVED Xamarin.Android.Net.AndroidClientHandler.AndroidClientHandler() -> void REMOVED Xamarin.Android.Net.AndroidClientHandler.AssertSelf() -> void @@ -10,8 +16,8 @@ REMOVED Xamarin.Android.Net.AndroidClientHandler.PreAuthenticationData.set -> vo REMOVED Xamarin.Android.Net.AndroidClientHandler.ProxyAuthenticationRequested.get -> bool REMOVED Xamarin.Android.Net.AndroidClientHandler.ReadTimeout.get -> System.TimeSpan REMOVED Xamarin.Android.Net.AndroidClientHandler.ReadTimeout.set -> void -REMOVED Xamarin.Android.Net.AndroidClientHandler.RequestedAuthentication.get -> System.Collections.Generic.IList? REMOVED Xamarin.Android.Net.AndroidClientHandler.RequestNeedsAuthorization.get -> bool +REMOVED Xamarin.Android.Net.AndroidClientHandler.RequestedAuthentication.get -> System.Collections.Generic.IList? REMOVED Xamarin.Android.Net.AndroidClientHandler.TrustedCerts.get -> System.Collections.Generic.IList? REMOVED Xamarin.Android.Net.AndroidClientHandler.TrustedCerts.set -> void REMOVED override Xamarin.Android.Net.AndroidClientHandler.Dispose(bool disposing) -> void @@ -24,6 +30,66 @@ REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.GetJavaProxy(System.Uri REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.GetSSLHostnameVerifier(Javax.Net.Ssl.HttpsURLConnection! connection) -> Javax.Net.Ssl.IHostnameVerifier? REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.SetupRequest(System.Net.Http.HttpRequestMessage! request, Java.Net.HttpURLConnection! conn) -> System.Threading.Tasks.Task! REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.WriteRequestContentToOutput(System.Net.Http.HttpRequestMessage! request, Java.Net.HttpURLConnection! httpConnection, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! -Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.get -> bool -Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.set -> void -Java.Interop.BaseExportAttribute +const Java.Interop.JavaPeerCallbackFormatAttribute.ConnectorDelegates = 1 -> int +const Java.Interop.JavaPeerCallbackFormatAttribute.UnmanagedCallersOnlyCallbacks = 2 -> int +static Android.Runtime.JNIEnv.BridgeProcessingGeneration.get -> int +static Java.Interop.JniMarshalTyped.Invoke_O(nint jnienv, nint self, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OO(nint jnienv, nint self, nint native_p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOO(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOO(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOS(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOOX(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOS(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSO(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOSS(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSX(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOX(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OS(nint jnienv, nint self, nint native_p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSO(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOO(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOS(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSOX(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSS(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSO(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSSS(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSX(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSX(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OX(nint jnienv, nint self, nint native_p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_S(nint jnienv, nint self, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SO(nint jnienv, nint self, T0 p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOO(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOO(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOS(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOOX(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOS(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSO(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOSS(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSX(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOX(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SS(nint jnienv, nint self, T0 p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSO(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOO(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOS(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSOX(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSS(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSX(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SX(nint jnienv, nint self, T0 p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_X(nint jnienv, nint self, delegate* body) -> void diff --git a/src/Mono.Android/PublicAPI/API-36.1/PublicAPI.Unshipped.txt b/src/Mono.Android/PublicAPI/API-36.1/PublicAPI.Unshipped.txt index 96701c76f82..f99d6a95964 100644 --- a/src/Mono.Android/PublicAPI/API-36.1/PublicAPI.Unshipped.txt +++ b/src/Mono.Android/PublicAPI/API-36.1/PublicAPI.Unshipped.txt @@ -1,5 +1,11 @@ #nullable enable -static Android.Runtime.JNIEnv.BridgeProcessingGeneration.get -> int +Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.get -> bool +Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.set -> void +Java.Interop.BaseExportAttribute +Java.Interop.JavaPeerCallbackFormatAttribute +Java.Interop.JavaPeerCallbackFormatAttribute.JavaPeerCallbackFormatAttribute(int version) -> void +Java.Interop.JavaPeerCallbackFormatAttribute.Version.get -> int +Java.Interop.JniMarshalTyped REMOVED Xamarin.Android.Net.AndroidClientHandler REMOVED Xamarin.Android.Net.AndroidClientHandler.AndroidClientHandler() -> void REMOVED Xamarin.Android.Net.AndroidClientHandler.AssertSelf() -> void @@ -10,8 +16,8 @@ REMOVED Xamarin.Android.Net.AndroidClientHandler.PreAuthenticationData.set -> vo REMOVED Xamarin.Android.Net.AndroidClientHandler.ProxyAuthenticationRequested.get -> bool REMOVED Xamarin.Android.Net.AndroidClientHandler.ReadTimeout.get -> System.TimeSpan REMOVED Xamarin.Android.Net.AndroidClientHandler.ReadTimeout.set -> void -REMOVED Xamarin.Android.Net.AndroidClientHandler.RequestedAuthentication.get -> System.Collections.Generic.IList? REMOVED Xamarin.Android.Net.AndroidClientHandler.RequestNeedsAuthorization.get -> bool +REMOVED Xamarin.Android.Net.AndroidClientHandler.RequestedAuthentication.get -> System.Collections.Generic.IList? REMOVED Xamarin.Android.Net.AndroidClientHandler.TrustedCerts.get -> System.Collections.Generic.IList? REMOVED Xamarin.Android.Net.AndroidClientHandler.TrustedCerts.set -> void REMOVED override Xamarin.Android.Net.AndroidClientHandler.Dispose(bool disposing) -> void @@ -24,6 +30,66 @@ REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.GetJavaProxy(System.Uri REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.GetSSLHostnameVerifier(Javax.Net.Ssl.HttpsURLConnection! connection) -> Javax.Net.Ssl.IHostnameVerifier? REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.SetupRequest(System.Net.Http.HttpRequestMessage! request, Java.Net.HttpURLConnection! conn) -> System.Threading.Tasks.Task! REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.WriteRequestContentToOutput(System.Net.Http.HttpRequestMessage! request, Java.Net.HttpURLConnection! httpConnection, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! -Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.get -> bool -Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.set -> void -Java.Interop.BaseExportAttribute +const Java.Interop.JavaPeerCallbackFormatAttribute.ConnectorDelegates = 1 -> int +const Java.Interop.JavaPeerCallbackFormatAttribute.UnmanagedCallersOnlyCallbacks = 2 -> int +static Android.Runtime.JNIEnv.BridgeProcessingGeneration.get -> int +static Java.Interop.JniMarshalTyped.Invoke_O(nint jnienv, nint self, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OO(nint jnienv, nint self, nint native_p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOO(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOO(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOS(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOOX(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOS(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSO(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOSS(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSX(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOX(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OS(nint jnienv, nint self, nint native_p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSO(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOO(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOS(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSOX(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSS(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSO(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSSS(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSX(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSX(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OX(nint jnienv, nint self, nint native_p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_S(nint jnienv, nint self, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SO(nint jnienv, nint self, T0 p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOO(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOO(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOS(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOOX(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOS(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSO(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOSS(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSX(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOX(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SS(nint jnienv, nint self, T0 p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSO(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOO(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOS(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSOX(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSS(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSX(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SX(nint jnienv, nint self, T0 p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_X(nint jnienv, nint self, delegate* body) -> void diff --git a/src/Mono.Android/PublicAPI/API-36/PublicAPI.Unshipped.txt b/src/Mono.Android/PublicAPI/API-36/PublicAPI.Unshipped.txt index 8ab7b82ed22..5b962ac9d59 100644 --- a/src/Mono.Android/PublicAPI/API-36/PublicAPI.Unshipped.txt +++ b/src/Mono.Android/PublicAPI/API-36/PublicAPI.Unshipped.txt @@ -1,38 +1,4 @@ #nullable enable -static Android.Runtime.JNIEnv.BridgeProcessingGeneration.get -> int -REMOVED Xamarin.Android.Net.AndroidClientHandler -REMOVED Xamarin.Android.Net.AndroidClientHandler.AndroidClientHandler() -> void -REMOVED Xamarin.Android.Net.AndroidClientHandler.AssertSelf() -> void -REMOVED Xamarin.Android.Net.AndroidClientHandler.ConnectTimeout.get -> System.TimeSpan -REMOVED Xamarin.Android.Net.AndroidClientHandler.ConnectTimeout.set -> void -REMOVED Xamarin.Android.Net.AndroidClientHandler.PreAuthenticationData.get -> Xamarin.Android.Net.AuthenticationData? -REMOVED Xamarin.Android.Net.AndroidClientHandler.PreAuthenticationData.set -> void -REMOVED Xamarin.Android.Net.AndroidClientHandler.ProxyAuthenticationRequested.get -> bool -REMOVED Xamarin.Android.Net.AndroidClientHandler.ReadTimeout.get -> System.TimeSpan -REMOVED Xamarin.Android.Net.AndroidClientHandler.ReadTimeout.set -> void -REMOVED Xamarin.Android.Net.AndroidClientHandler.RequestedAuthentication.get -> System.Collections.Generic.IList? -REMOVED Xamarin.Android.Net.AndroidClientHandler.RequestNeedsAuthorization.get -> bool -REMOVED Xamarin.Android.Net.AndroidClientHandler.TrustedCerts.get -> System.Collections.Generic.IList? -REMOVED Xamarin.Android.Net.AndroidClientHandler.TrustedCerts.set -> void -REMOVED override Xamarin.Android.Net.AndroidClientHandler.Dispose(bool disposing) -> void -REMOVED override Xamarin.Android.Net.AndroidClientHandler.SendAsync(System.Net.Http.HttpRequestMessage! request, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! -REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.ConfigureCustomSSLSocketFactory(Javax.Net.Ssl.HttpsURLConnection! connection) -> Javax.Net.Ssl.SSLSocketFactory? -REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.ConfigureKeyManagerFactory(Java.Security.KeyStore? keyStore) -> Javax.Net.Ssl.KeyManagerFactory? -REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.ConfigureKeyStore(Java.Security.KeyStore? keyStore) -> Java.Security.KeyStore? -REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.ConfigureTrustManagerFactory(Java.Security.KeyStore? keyStore) -> Javax.Net.Ssl.TrustManagerFactory? -REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.GetJavaProxy(System.Uri! destination, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! -REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.GetSSLHostnameVerifier(Javax.Net.Ssl.HttpsURLConnection! connection) -> Javax.Net.Ssl.IHostnameVerifier? -REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.SetupRequest(System.Net.Http.HttpRequestMessage! request, Java.Net.HttpURLConnection! conn) -> System.Threading.Tasks.Task! -REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.WriteRequestContentToOutput(System.Net.Http.HttpRequestMessage! request, Java.Net.HttpURLConnection! httpConnection, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! -abstract Android.App.AppFunctions.AppFunctionService.OnExecuteFunction(Android.App.AppFunctions.ExecuteAppFunctionRequest! request, string! callingPackage, Android.Content.PM.SigningInfo! callingPackageSigningInfo, Android.OS.CancellationSignal! cancellationSignal, Android.OS.IOutcomeReceiver! callback) -> void -abstract Android.Media.TV.Ads.TvAdService.OnCreateSession(string! serviceId, string! type) -> Android.Media.TV.Ads.TvAdService.Session? -abstract Android.Media.TV.Ads.TvAdService.Session.OnRelease() -> void -abstract Android.Media.TV.Ads.TvAdService.Session.OnSetSurface(Android.Views.Surface? surface) -> bool -abstract Android.Ranging.RangingConfig.DescribeContents() -> int -abstract Android.Ranging.RangingConfig.WriteToParcel(Android.OS.Parcel! dest, Android.OS.ParcelableWriteFlags flags) -> void -abstract Android.Service.Settings.Preferences.SettingsPreferenceService.OnGetAllPreferenceMetadata(Android.Service.Settings.Preferences.MetadataRequest! request, Android.OS.IOutcomeReceiver! callback) -> void -abstract Android.Service.Settings.Preferences.SettingsPreferenceService.OnGetPreferenceValue(Android.Service.Settings.Preferences.GetValueRequest! request, Android.OS.IOutcomeReceiver! callback) -> void -abstract Android.Service.Settings.Preferences.SettingsPreferenceService.OnSetPreferenceValue(Android.Service.Settings.Preferences.SetValueRequest! request, Android.OS.IOutcomeReceiver! callback) -> void Android.AccessibilityServices.GlobalAction.MediaPlayPause = 22 -> Android.AccessibilityServices.GlobalAction Android.AccessibilityServices.GlobalAction.Menu = 21 -> Android.AccessibilityServices.GlobalAction Android.AdServices.AdSelection.AdSelectionOutcome.Builder.SetComponentAdUris(System.Collections.Generic.IList! componentAdUris) -> Android.AdServices.AdSelection.AdSelectionOutcome.Builder! @@ -199,13 +165,6 @@ Android.App.AppFunctions.ExecuteAppFunctionResponse.Extras.get -> Android.OS.Bun Android.App.AppFunctions.ExecuteAppFunctionResponse.InterfaceConsts Android.App.AppFunctions.ExecuteAppFunctionResponse.ResultDocument.get -> Android.App.AppSearch.GenericDocument! Android.App.AppFunctions.ExecuteAppFunctionResponse.WriteToParcel(Android.OS.Parcel! dest, Android.OS.ParcelableWriteFlags flags) -> void -Android.App.ApplicationStartInfo.StartComponent.get -> Android.App.ApplicationStartInfoStartComponent -Android.App.ApplicationStartInfoStartComponent -Android.App.ApplicationStartInfoStartComponent.Activity = 1 -> Android.App.ApplicationStartInfoStartComponent -Android.App.ApplicationStartInfoStartComponent.Broadcast = 2 -> Android.App.ApplicationStartInfoStartComponent -Android.App.ApplicationStartInfoStartComponent.ContentProvider = 3 -> Android.App.ApplicationStartInfoStartComponent -Android.App.ApplicationStartInfoStartComponent.Other = 5 -> Android.App.ApplicationStartInfoStartComponent -Android.App.ApplicationStartInfoStartComponent.Service = 4 -> Android.App.ApplicationStartInfoStartComponent Android.App.AppOpsManagerCallbackFlag Android.App.AppOpsManagerCallbackFlag.Async = 1 -> Android.App.AppOpsManagerCallbackFlag Android.App.AppOpsManagerCallbackFlag.None = 0 -> Android.App.AppOpsManagerCallbackFlag @@ -275,10 +234,10 @@ Android.App.AppSearch.EmbeddingVector.WriteToParcel(Android.OS.Parcel! dest, And Android.App.AppSearch.GetSchemaResponse.Builder.Builder(Android.App.AppSearch.GetSchemaResponse! getSchemaResponse) -> void Android.App.AppSearch.GetSchemaResponse.Builder.ClearPubliclyVisibleSchema(string! schemaType) -> Android.App.AppSearch.GetSchemaResponse.Builder! Android.App.AppSearch.GetSchemaResponse.Builder.ClearRequiredPermissionsForSchemaTypeVisibility(string! schemaType) -> Android.App.AppSearch.GetSchemaResponse.Builder! -Android.App.AppSearch.GetSchemaResponse.Builder.ClearSchemas() -> Android.App.AppSearch.GetSchemaResponse.Builder! Android.App.AppSearch.GetSchemaResponse.Builder.ClearSchemaTypeNotDisplayedBySystem(string! schemaType) -> Android.App.AppSearch.GetSchemaResponse.Builder! Android.App.AppSearch.GetSchemaResponse.Builder.ClearSchemaTypeVisibleToConfigs(string! schemaType) -> Android.App.AppSearch.GetSchemaResponse.Builder! Android.App.AppSearch.GetSchemaResponse.Builder.ClearSchemaTypeVisibleToPackages(string! schemaType) -> Android.App.AppSearch.GetSchemaResponse.Builder! +Android.App.AppSearch.GetSchemaResponse.Builder.ClearSchemas() -> Android.App.AppSearch.GetSchemaResponse.Builder! Android.App.AppSearch.JoinSpec.Builder.Builder(Android.App.AppSearch.JoinSpec! joinSpec) -> void Android.App.AppSearch.JoinSpec.Builder.SetChildPropertyExpression(string! childPropertyExpression) -> Android.App.AppSearch.JoinSpec.Builder! Android.App.AppSearch.OpenBlobForReadResponse @@ -305,14 +264,14 @@ Android.App.AppSearch.SearchResult.Builder.AddInformationalRankingSignal(double Android.App.AppSearch.SearchResult.Builder.SetParentTypeMap(System.Collections.Generic.IDictionary!>! parentTypeMap) -> Android.App.AppSearch.SearchResult.Builder! Android.App.AppSearch.SearchResult.InformationalRankingSignals.get -> System.Collections.Generic.IList! Android.App.AppSearch.SearchResult.ParentTypeMap.get -> System.Collections.Generic.IDictionary!>! -Android.App.AppSearch.SearchSpec.Builder.AddEmbeddingParameters(params Android.App.AppSearch.EmbeddingVector![]! searchEmbeddings) -> Android.App.AppSearch.SearchSpec.Builder! Android.App.AppSearch.SearchSpec.Builder.AddEmbeddingParameters(System.Collections.Generic.ICollection! searchEmbeddings) -> Android.App.AppSearch.SearchSpec.Builder! -Android.App.AppSearch.SearchSpec.Builder.AddFilterDocumentIds(params string![]! documentIds) -> Android.App.AppSearch.SearchSpec.Builder! +Android.App.AppSearch.SearchSpec.Builder.AddEmbeddingParameters(params Android.App.AppSearch.EmbeddingVector![]! searchEmbeddings) -> Android.App.AppSearch.SearchSpec.Builder! Android.App.AppSearch.SearchSpec.Builder.AddFilterDocumentIds(System.Collections.Generic.ICollection! documentIds) -> Android.App.AppSearch.SearchSpec.Builder! -Android.App.AppSearch.SearchSpec.Builder.AddInformationalRankingExpressions(params string![]! informationalRankingExpressions) -> Android.App.AppSearch.SearchSpec.Builder! +Android.App.AppSearch.SearchSpec.Builder.AddFilterDocumentIds(params string![]! documentIds) -> Android.App.AppSearch.SearchSpec.Builder! Android.App.AppSearch.SearchSpec.Builder.AddInformationalRankingExpressions(System.Collections.Generic.ICollection! informationalRankingExpressions) -> Android.App.AppSearch.SearchSpec.Builder! -Android.App.AppSearch.SearchSpec.Builder.AddSearchStringParameters(params string![]! searchStringParameters) -> Android.App.AppSearch.SearchSpec.Builder! +Android.App.AppSearch.SearchSpec.Builder.AddInformationalRankingExpressions(params string![]! informationalRankingExpressions) -> Android.App.AppSearch.SearchSpec.Builder! Android.App.AppSearch.SearchSpec.Builder.AddSearchStringParameters(System.Collections.Generic.IList! searchStringParameters) -> Android.App.AppSearch.SearchSpec.Builder! +Android.App.AppSearch.SearchSpec.Builder.AddSearchStringParameters(params string![]! searchStringParameters) -> Android.App.AppSearch.SearchSpec.Builder! Android.App.AppSearch.SearchSpec.Builder.Builder(Android.App.AppSearch.SearchSpec! searchSpec) -> void Android.App.AppSearch.SearchSpec.Builder.ClearEmbeddingParameters() -> Android.App.AppSearch.SearchSpec.Builder! Android.App.AppSearch.SearchSpec.Builder.ClearFilterDocumentIds() -> Android.App.AppSearch.SearchSpec.Builder! @@ -337,8 +296,8 @@ Android.App.AppSearch.SearchSpec.InformationalRankingExpressions.get -> System.C Android.App.AppSearch.SearchSpec.IsListFilterMatchScoreExpressionFunctionEnabled.get -> bool Android.App.AppSearch.SearchSpec.IsScorablePropertyRankingEnabled.get -> bool Android.App.AppSearch.SearchSpec.SearchStringParameters.get -> System.Collections.Generic.IList! -Android.App.AppSearch.SearchSuggestionSpec.Builder.AddSearchStringParameters(params string![]! searchStringParameters) -> Android.App.AppSearch.SearchSuggestionSpec.Builder! Android.App.AppSearch.SearchSuggestionSpec.Builder.AddSearchStringParameters(System.Collections.Generic.IList! searchStringParameters) -> Android.App.AppSearch.SearchSuggestionSpec.Builder! +Android.App.AppSearch.SearchSuggestionSpec.Builder.AddSearchStringParameters(params string![]! searchStringParameters) -> Android.App.AppSearch.SearchSuggestionSpec.Builder! Android.App.AppSearch.SearchSuggestionSpec.SearchStringParameters.get -> System.Collections.Generic.IList! Android.App.AppSearch.SetBlobVisibilityRequest Android.App.AppSearch.SetBlobVisibilityRequest.Builder @@ -353,6 +312,15 @@ Android.App.AppSearch.SetSchemaRequest.Builder.ClearMigrators() -> Android.App.A Android.App.AppSearch.SetSchemaRequest.Builder.ClearSchemas() -> Android.App.AppSearch.SetSchemaRequest.Builder! Android.App.AppSearch.StorageInfo.Builder.SetBlobsCount(int blobsCount) -> Android.App.AppSearch.StorageInfo.Builder! Android.App.AppSearch.StorageInfo.Builder.SetBlobsSizeBytes(long blobsSizeBytes) -> Android.App.AppSearch.StorageInfo.Builder! +Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.get -> bool +Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.set -> void +Android.App.ApplicationStartInfo.StartComponent.get -> Android.App.ApplicationStartInfoStartComponent +Android.App.ApplicationStartInfoStartComponent +Android.App.ApplicationStartInfoStartComponent.Activity = 1 -> Android.App.ApplicationStartInfoStartComponent +Android.App.ApplicationStartInfoStartComponent.Broadcast = 2 -> Android.App.ApplicationStartInfoStartComponent +Android.App.ApplicationStartInfoStartComponent.ContentProvider = 3 -> Android.App.ApplicationStartInfoStartComponent +Android.App.ApplicationStartInfoStartComponent.Other = 5 -> Android.App.ApplicationStartInfoStartComponent +Android.App.ApplicationStartInfoStartComponent.Service = 4 -> Android.App.ApplicationStartInfoStartComponent Android.App.BackgroundActivityStartMode.AllowAlways = 3 -> Android.App.BackgroundActivityStartMode Android.App.BackgroundActivityStartMode.AllowIfVisible = 4 -> Android.App.BackgroundActivityStartMode Android.App.Jank.AppJankStats @@ -1817,8 +1785,8 @@ Android.Ranging.RangingSession.AddDeviceToRangingSession(Android.Ranging.Ranging Android.Ranging.RangingSession.Close() -> void Android.Ranging.RangingSession.ICallback Android.Ranging.RangingSession.ICallback.OnClosed(int reason) -> void -Android.Ranging.RangingSession.ICallback.OnOpened() -> void Android.Ranging.RangingSession.ICallback.OnOpenFailed(int reason) -> void +Android.Ranging.RangingSession.ICallback.OnOpened() -> void Android.Ranging.RangingSession.ICallback.OnResults(Android.Ranging.RangingDevice! peer, Android.Ranging.RangingData! data) -> void Android.Ranging.RangingSession.ICallback.OnStarted(Android.Ranging.RangingDevice! peer, int technology) -> void Android.Ranging.RangingSession.ICallback.OnStopped(Android.Ranging.RangingDevice! peer, int technology) -> void @@ -2052,8 +2020,8 @@ Android.Service.Carrier.SendStatusResultType.ErrorNullPdu = 201 -> Android.Servi Android.Service.Carrier.SendStatusResultType.ErrorShortCodeNeverAllowed = 206 -> Android.Service.Carrier.SendStatusResultType Android.Service.Carrier.SendStatusResultType.ErrorShortCodeNotAllowed = 205 -> Android.Service.Carrier.SendStatusResultType Android.Service.Carrier.SendStatusResultType.InvalidArguments = 208 -> Android.Service.Carrier.SendStatusResultType -Android.Service.Carrier.SendStatusResultType.InvalidSmscAddress = 213 -> Android.Service.Carrier.SendStatusResultType Android.Service.Carrier.SendStatusResultType.InvalidSmsFormat = 210 -> Android.Service.Carrier.SendStatusResultType +Android.Service.Carrier.SendStatusResultType.InvalidSmscAddress = 213 -> Android.Service.Carrier.SendStatusResultType Android.Service.Carrier.SendStatusResultType.InvalidState = 209 -> Android.Service.Carrier.SendStatusResultType Android.Service.Carrier.SendStatusResultType.NetworkError = 211 -> Android.Service.Carrier.SendStatusResultType Android.Service.Carrier.SendStatusResultType.NetworkReject = 207 -> Android.Service.Carrier.SendStatusResultType @@ -2112,6 +2080,35 @@ Android.Service.Settings.Preferences.MetadataResultType Android.Service.Settings.Preferences.MetadataResultType.InternalError = 2 -> Android.Service.Settings.Preferences.MetadataResultType Android.Service.Settings.Preferences.MetadataResultType.Ok = 0 -> Android.Service.Settings.Preferences.MetadataResultType Android.Service.Settings.Preferences.MetadataResultType.Unsupported = 1 -> Android.Service.Settings.Preferences.MetadataResultType +Android.Service.Settings.Preferences.SetValueRequest +Android.Service.Settings.Preferences.SetValueRequest.Builder +Android.Service.Settings.Preferences.SetValueRequest.Builder.Build() -> Android.Service.Settings.Preferences.SetValueRequest! +Android.Service.Settings.Preferences.SetValueRequest.Builder.Builder(string! screenKey, string! preferenceKey, Android.Service.Settings.Preferences.SettingsPreferenceValue! value) -> void +Android.Service.Settings.Preferences.SetValueRequest.DescribeContents() -> int +Android.Service.Settings.Preferences.SetValueRequest.InterfaceConsts +Android.Service.Settings.Preferences.SetValueRequest.PreferenceKey.get -> string! +Android.Service.Settings.Preferences.SetValueRequest.PreferenceValue.get -> Android.Service.Settings.Preferences.SettingsPreferenceValue! +Android.Service.Settings.Preferences.SetValueRequest.ScreenKey.get -> string! +Android.Service.Settings.Preferences.SetValueRequest.WriteToParcel(Android.OS.Parcel! dest, Android.OS.ParcelableWriteFlags flags) -> void +Android.Service.Settings.Preferences.SetValueResult +Android.Service.Settings.Preferences.SetValueResult.Builder +Android.Service.Settings.Preferences.SetValueResult.Builder.Build() -> Android.Service.Settings.Preferences.SetValueResult! +Android.Service.Settings.Preferences.SetValueResult.Builder.Builder(int resultCode) -> void +Android.Service.Settings.Preferences.SetValueResult.DescribeContents() -> int +Android.Service.Settings.Preferences.SetValueResult.InterfaceConsts +Android.Service.Settings.Preferences.SetValueResult.ResultCode.get -> Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResult.WriteToParcel(Android.OS.Parcel! dest, Android.OS.ParcelableWriteFlags flags) -> void +Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResultType.Disabled = 2 -> Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResultType.Disallow = 7 -> Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResultType.InternalError = 9 -> Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResultType.InvalidRequest = 8 -> Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResultType.Ok = 0 -> Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResultType.RequireAppPermission = 5 -> Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResultType.RequireUserConsent = 6 -> Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResultType.Restricted = 3 -> Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResultType.Unavailable = 4 -> Android.Service.Settings.Preferences.SetValueResultType +Android.Service.Settings.Preferences.SetValueResultType.Unsupported = 1 -> Android.Service.Settings.Preferences.SetValueResultType Android.Service.Settings.Preferences.SettingsPreferenceMetadata Android.Service.Settings.Preferences.SettingsPreferenceMetadata.Builder Android.Service.Settings.Preferences.SettingsPreferenceMetadata.Builder.Build() -> Android.Service.Settings.Preferences.SettingsPreferenceMetadata! @@ -2166,8 +2163,8 @@ Android.Service.Settings.Preferences.SettingsPreferenceValue.Builder.SetLongValu Android.Service.Settings.Preferences.SettingsPreferenceValue.Builder.SetStringValue(string? stringValue) -> Android.Service.Settings.Preferences.SettingsPreferenceValue.Builder! Android.Service.Settings.Preferences.SettingsPreferenceValue.DescribeContents() -> int Android.Service.Settings.Preferences.SettingsPreferenceValue.DoubleValue.get -> double -Android.Service.Settings.Preferences.SettingsPreferenceValue.InterfaceConsts Android.Service.Settings.Preferences.SettingsPreferenceValue.IntValue.get -> int +Android.Service.Settings.Preferences.SettingsPreferenceValue.InterfaceConsts Android.Service.Settings.Preferences.SettingsPreferenceValue.LongValue.get -> long Android.Service.Settings.Preferences.SettingsPreferenceValue.StringValue.get -> string? Android.Service.Settings.Preferences.SettingsPreferenceValue.Type.get -> Android.Service.Settings.Preferences.SettingsPreferenceValueType @@ -2178,35 +2175,6 @@ Android.Service.Settings.Preferences.SettingsPreferenceValueType.Double = 2 -> A Android.Service.Settings.Preferences.SettingsPreferenceValueType.Int = 4 -> Android.Service.Settings.Preferences.SettingsPreferenceValueType Android.Service.Settings.Preferences.SettingsPreferenceValueType.Long = 1 -> Android.Service.Settings.Preferences.SettingsPreferenceValueType Android.Service.Settings.Preferences.SettingsPreferenceValueType.String = 3 -> Android.Service.Settings.Preferences.SettingsPreferenceValueType -Android.Service.Settings.Preferences.SetValueRequest -Android.Service.Settings.Preferences.SetValueRequest.Builder -Android.Service.Settings.Preferences.SetValueRequest.Builder.Build() -> Android.Service.Settings.Preferences.SetValueRequest! -Android.Service.Settings.Preferences.SetValueRequest.Builder.Builder(string! screenKey, string! preferenceKey, Android.Service.Settings.Preferences.SettingsPreferenceValue! value) -> void -Android.Service.Settings.Preferences.SetValueRequest.DescribeContents() -> int -Android.Service.Settings.Preferences.SetValueRequest.InterfaceConsts -Android.Service.Settings.Preferences.SetValueRequest.PreferenceKey.get -> string! -Android.Service.Settings.Preferences.SetValueRequest.PreferenceValue.get -> Android.Service.Settings.Preferences.SettingsPreferenceValue! -Android.Service.Settings.Preferences.SetValueRequest.ScreenKey.get -> string! -Android.Service.Settings.Preferences.SetValueRequest.WriteToParcel(Android.OS.Parcel! dest, Android.OS.ParcelableWriteFlags flags) -> void -Android.Service.Settings.Preferences.SetValueResult -Android.Service.Settings.Preferences.SetValueResult.Builder -Android.Service.Settings.Preferences.SetValueResult.Builder.Build() -> Android.Service.Settings.Preferences.SetValueResult! -Android.Service.Settings.Preferences.SetValueResult.Builder.Builder(int resultCode) -> void -Android.Service.Settings.Preferences.SetValueResult.DescribeContents() -> int -Android.Service.Settings.Preferences.SetValueResult.InterfaceConsts -Android.Service.Settings.Preferences.SetValueResult.ResultCode.get -> Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResult.WriteToParcel(Android.OS.Parcel! dest, Android.OS.ParcelableWriteFlags flags) -> void -Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResultType.Disabled = 2 -> Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResultType.Disallow = 7 -> Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResultType.InternalError = 9 -> Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResultType.InvalidRequest = 8 -> Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResultType.Ok = 0 -> Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResultType.RequireAppPermission = 5 -> Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResultType.RequireUserConsent = 6 -> Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResultType.Restricted = 3 -> Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResultType.Unavailable = 4 -> Android.Service.Settings.Preferences.SetValueResultType -Android.Service.Settings.Preferences.SetValueResultType.Unsupported = 1 -> Android.Service.Settings.Preferences.SetValueResultType Android.Telephony.Data.ApnType.OemPaid = 65536 -> Android.Telephony.Data.ApnType Android.Telephony.Data.ApnType.OemPrivate = 131072 -> Android.Telephony.Data.ApnType Android.Telephony.Satellite.ISatelliteStateChangeListener @@ -2353,6 +2321,62 @@ Android.Window.BackEvent.BackEvent(float touchX, float touchY, float progress, A Android.Window.BackEvent.FrameTimeMillis.get -> long Android.Window.BackEventEdge.None = 2 -> Android.Window.BackEventEdge Android.Window.SystemOnBackInvokedCallbacks +Java.Interop.BaseExportAttribute +Java.Interop.JavaPeerCallbackFormatAttribute +Java.Interop.JavaPeerCallbackFormatAttribute.JavaPeerCallbackFormatAttribute(int version) -> void +Java.Interop.JavaPeerCallbackFormatAttribute.Version.get -> int +Java.Interop.JniMarshalTyped +Java.Lang.Invoke.StringConcatException +Java.Lang.Invoke.StringConcatException.StringConcatException(nint javaReference, Android.Runtime.JniHandleOwnership transfer) -> void +Java.Lang.Invoke.StringConcatException.StringConcatException(string? msg) -> void +Java.Lang.Invoke.StringConcatException.StringConcatException(string? msg, Java.Lang.Throwable? cause) -> void +Java.Lang.MatchException +Java.Lang.MatchException.MatchException(string? message, Java.Lang.Throwable? cause) -> void +Java.Lang.Runtimes.SwitchBootstraps +Java.Lang.Runtimes.SwitchBootstraps.SwitchBootstraps(nint javaReference, Android.Runtime.JniHandleOwnership transfer) -> void +Java.Lang.Thread.IsVirtual.get -> bool +Java.Lang.Thread.ThreadId() -> long +Java.Util.Concurrent.ForkJoinTask.QuietlyJoin(long timeout, Java.Util.Concurrent.TimeUnit? unit) -> bool +Java.Util.Concurrent.ForkJoinTask.QuietlyJoinUninterruptibly(long timeout, Java.Util.Concurrent.TimeUnit? unit) -> bool +Java.Util.Concurrent.ForkJoinWorkerThread.ForkJoinWorkerThread(Java.Lang.ThreadGroup? group, Java.Util.Concurrent.ForkJoinPool? pool, bool preserveThreadLocals) -> void +Java.Util.Concurrent.IExecutorService.Close() -> void +Java.Util.Concurrent.IFuture.ExceptionNow() -> Java.Lang.Throwable? +Java.Util.Concurrent.IFuture.InvokeState() -> Java.Util.Concurrent.IFuture.State? +Java.Util.Concurrent.IFuture.ResultNow() -> Java.Lang.Object? +Java.Util.Concurrent.IFuture.State +REMOVED Xamarin.Android.Net.AndroidClientHandler +REMOVED Xamarin.Android.Net.AndroidClientHandler.AndroidClientHandler() -> void +REMOVED Xamarin.Android.Net.AndroidClientHandler.AssertSelf() -> void +REMOVED Xamarin.Android.Net.AndroidClientHandler.ConnectTimeout.get -> System.TimeSpan +REMOVED Xamarin.Android.Net.AndroidClientHandler.ConnectTimeout.set -> void +REMOVED Xamarin.Android.Net.AndroidClientHandler.PreAuthenticationData.get -> Xamarin.Android.Net.AuthenticationData? +REMOVED Xamarin.Android.Net.AndroidClientHandler.PreAuthenticationData.set -> void +REMOVED Xamarin.Android.Net.AndroidClientHandler.ProxyAuthenticationRequested.get -> bool +REMOVED Xamarin.Android.Net.AndroidClientHandler.ReadTimeout.get -> System.TimeSpan +REMOVED Xamarin.Android.Net.AndroidClientHandler.ReadTimeout.set -> void +REMOVED Xamarin.Android.Net.AndroidClientHandler.RequestNeedsAuthorization.get -> bool +REMOVED Xamarin.Android.Net.AndroidClientHandler.RequestedAuthentication.get -> System.Collections.Generic.IList? +REMOVED Xamarin.Android.Net.AndroidClientHandler.TrustedCerts.get -> System.Collections.Generic.IList? +REMOVED Xamarin.Android.Net.AndroidClientHandler.TrustedCerts.set -> void +REMOVED override Xamarin.Android.Net.AndroidClientHandler.Dispose(bool disposing) -> void +REMOVED override Xamarin.Android.Net.AndroidClientHandler.SendAsync(System.Net.Http.HttpRequestMessage! request, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.ConfigureCustomSSLSocketFactory(Javax.Net.Ssl.HttpsURLConnection! connection) -> Javax.Net.Ssl.SSLSocketFactory? +REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.ConfigureKeyManagerFactory(Java.Security.KeyStore? keyStore) -> Javax.Net.Ssl.KeyManagerFactory? +REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.ConfigureKeyStore(Java.Security.KeyStore? keyStore) -> Java.Security.KeyStore? +REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.ConfigureTrustManagerFactory(Java.Security.KeyStore? keyStore) -> Javax.Net.Ssl.TrustManagerFactory? +REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.GetJavaProxy(System.Uri! destination, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.GetSSLHostnameVerifier(Javax.Net.Ssl.HttpsURLConnection! connection) -> Javax.Net.Ssl.IHostnameVerifier? +REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.SetupRequest(System.Net.Http.HttpRequestMessage! request, Java.Net.HttpURLConnection! conn) -> System.Threading.Tasks.Task! +REMOVED virtual Xamarin.Android.Net.AndroidClientHandler.WriteRequestContentToOutput(System.Net.Http.HttpRequestMessage! request, Java.Net.HttpURLConnection! httpConnection, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +abstract Android.App.AppFunctions.AppFunctionService.OnExecuteFunction(Android.App.AppFunctions.ExecuteAppFunctionRequest! request, string! callingPackage, Android.Content.PM.SigningInfo! callingPackageSigningInfo, Android.OS.CancellationSignal! cancellationSignal, Android.OS.IOutcomeReceiver! callback) -> void +abstract Android.Media.TV.Ads.TvAdService.OnCreateSession(string! serviceId, string! type) -> Android.Media.TV.Ads.TvAdService.Session? +abstract Android.Media.TV.Ads.TvAdService.Session.OnRelease() -> void +abstract Android.Media.TV.Ads.TvAdService.Session.OnSetSurface(Android.Views.Surface? surface) -> bool +abstract Android.Ranging.RangingConfig.DescribeContents() -> int +abstract Android.Ranging.RangingConfig.WriteToParcel(Android.OS.Parcel! dest, Android.OS.ParcelableWriteFlags flags) -> void +abstract Android.Service.Settings.Preferences.SettingsPreferenceService.OnGetAllPreferenceMetadata(Android.Service.Settings.Preferences.MetadataRequest! request, Android.OS.IOutcomeReceiver! callback) -> void +abstract Android.Service.Settings.Preferences.SettingsPreferenceService.OnGetPreferenceValue(Android.Service.Settings.Preferences.GetValueRequest! request, Android.OS.IOutcomeReceiver! callback) -> void +abstract Android.Service.Settings.Preferences.SettingsPreferenceService.OnSetPreferenceValue(Android.Service.Settings.Preferences.SetValueRequest! request, Android.OS.IOutcomeReceiver! callback) -> void const Android.AccessibilityServices.AccessibilityService.GlobalActionMediaPlayPause = Android.AccessibilityServices.GlobalAction.MediaPlayPause -> Android.AccessibilityServices.GlobalAction const Android.AccessibilityServices.AccessibilityService.GlobalActionMenu = Android.AccessibilityServices.GlobalAction.Menu -> Android.AccessibilityServices.GlobalAction const Android.AdServices.AdSelection.PerBuyerConfiguration.InterfaceConsts.ContentsFileDescriptor = 1 -> int @@ -2413,11 +2437,6 @@ const Android.App.AppFunctions.ExecuteAppFunctionRequest.InterfaceConsts.Parcela const Android.App.AppFunctions.ExecuteAppFunctionResponse.InterfaceConsts.ContentsFileDescriptor = 1 -> int const Android.App.AppFunctions.ExecuteAppFunctionResponse.InterfaceConsts.ParcelableWriteReturnValue = Android.OS.ParcelableWriteFlags.ReturnValue -> Android.OS.ParcelableWriteFlags const Android.App.AppFunctions.ExecuteAppFunctionResponse.PropertyReturnValue = "androidAppfunctionsReturnValue" -> string! -const Android.App.ApplicationStartInfo.StartComponentActivity = Android.App.ApplicationStartInfoStartComponent.Activity -> Android.App.ApplicationStartInfoStartComponent -const Android.App.ApplicationStartInfo.StartComponentBroadcast = Android.App.ApplicationStartInfoStartComponent.Broadcast -> Android.App.ApplicationStartInfoStartComponent -const Android.App.ApplicationStartInfo.StartComponentContentProvider = Android.App.ApplicationStartInfoStartComponent.ContentProvider -> Android.App.ApplicationStartInfoStartComponent -const Android.App.ApplicationStartInfo.StartComponentOther = Android.App.ApplicationStartInfoStartComponent.Other -> Android.App.ApplicationStartInfoStartComponent -const Android.App.ApplicationStartInfo.StartComponentService = Android.App.ApplicationStartInfoStartComponent.Service -> Android.App.ApplicationStartInfoStartComponent const Android.App.AppOpsManager.OpNotedCallbackFlagIgnoreAsync = Android.App.AppOpsManagerCallbackFlag.Async -> Android.App.AppOpsManagerCallbackFlag const Android.App.AppSearch.AppSearchBlobHandle.InterfaceConsts.ContentsFileDescriptor = 1 -> int const Android.App.AppSearch.AppSearchBlobHandle.InterfaceConsts.ParcelableWriteReturnValue = Android.OS.ParcelableWriteFlags.ReturnValue -> Android.OS.ParcelableWriteFlags @@ -2440,6 +2459,11 @@ const Android.App.AppSearch.SearchSpec.EmbeddingSearchMetricTypeCosine = Android const Android.App.AppSearch.SearchSpec.EmbeddingSearchMetricTypeDefault = Android.App.AppSearch.EmbeddingSearchMetricType.Default -> Android.App.AppSearch.EmbeddingSearchMetricType const Android.App.AppSearch.SearchSpec.EmbeddingSearchMetricTypeDotProduct = Android.App.AppSearch.EmbeddingSearchMetricType.DotProduct -> Android.App.AppSearch.EmbeddingSearchMetricType const Android.App.AppSearch.SearchSpec.EmbeddingSearchMetricTypeEuclidean = Android.App.AppSearch.EmbeddingSearchMetricType.Euclidean -> Android.App.AppSearch.EmbeddingSearchMetricType +const Android.App.ApplicationStartInfo.StartComponentActivity = Android.App.ApplicationStartInfoStartComponent.Activity -> Android.App.ApplicationStartInfoStartComponent +const Android.App.ApplicationStartInfo.StartComponentBroadcast = Android.App.ApplicationStartInfoStartComponent.Broadcast -> Android.App.ApplicationStartInfoStartComponent +const Android.App.ApplicationStartInfo.StartComponentContentProvider = Android.App.ApplicationStartInfoStartComponent.ContentProvider -> Android.App.ApplicationStartInfoStartComponent +const Android.App.ApplicationStartInfo.StartComponentOther = Android.App.ApplicationStartInfoStartComponent.Other -> Android.App.ApplicationStartInfoStartComponent +const Android.App.ApplicationStartInfo.StartComponentService = Android.App.ApplicationStartInfoStartComponent.Service -> Android.App.ApplicationStartInfoStartComponent const Android.App.Assist.AssistContent.ExtraAppFunctionData = "android.app.assist.extra.APP_FUNCTION_DATA" -> string! const Android.App.Jank.AppJankStats.WidgetCategoryAnimation = "animation" -> string! const Android.App.Jank.AppJankStats.WidgetCategoryKeyboard = "keyboard" -> string! @@ -2944,15 +2968,15 @@ const Android.Media.TV.TvInputManager.SessionDataKeyAdResponse = "ad_response" - const Android.Media.TV.TvInputManager.SessionDataKeyBroadcastInfoResponse = "broadcast_info_response" -> string! const Android.Media.TV.TvInputManager.SessionDataKeyChannelUri = "channel_uri" -> string! const Android.Media.TV.TvInputManager.SessionDataKeyTrackId = "track_id" -> string! -const Android.Media.TV.TvInputManager.SessionDataKeyTracks = "tracks" -> string! const Android.Media.TV.TvInputManager.SessionDataKeyTrackType = "track_type" -> string! +const Android.Media.TV.TvInputManager.SessionDataKeyTracks = "tracks" -> string! const Android.Media.TV.TvInputManager.SessionDataKeyTvMessageType = "tv_message_type" -> string! const Android.Media.TV.TvInputManager.SessionDataKeyVideoUnavailableReason = "video_unavailable_reason" -> string! const Android.Media.TV.TvInputManager.SessionDataTypeAdBufferConsumed = "ad_buffer_consumed" -> string! const Android.Media.TV.TvInputManager.SessionDataTypeAdResponse = "ad_response" -> string! const Android.Media.TV.TvInputManager.SessionDataTypeBroadcastInfoResponse = "broadcast_info_response" -> string! -const Android.Media.TV.TvInputManager.SessionDataTypeTracksChanged = "tracks_changed" -> string! const Android.Media.TV.TvInputManager.SessionDataTypeTrackSelected = "track_selected" -> string! +const Android.Media.TV.TvInputManager.SessionDataTypeTracksChanged = "tracks_changed" -> string! const Android.Media.TV.TvInputManager.SessionDataTypeTuned = "tuned" -> string! const Android.Media.TV.TvInputManager.SessionDataTypeTvMessage = "tv_message" -> string! const Android.Media.TV.TvInputManager.SessionDataTypeVideoAvailable = "video_available" -> string! @@ -3201,12 +3225,12 @@ const Android.Provider.MediaStore.Downloads.InterfaceConsts.OemMetadata = "oem_m const Android.Provider.MediaStore.ExtraPickerPreSelectionUris = "android.provider.extra.PICKER_PRE_SELECTION_URIS" -> string! const Android.Provider.MediaStore.Files.FileColumns.InferredDate = "inferred_date" -> string! const Android.Provider.MediaStore.Files.FileColumns.OemMetadata = "oem_metadata" -> string! +const Android.Provider.MediaStore.IMediaColumns.InferredDate = "inferred_date" -> string! +const Android.Provider.MediaStore.IMediaColumns.OemMetadata = "oem_metadata" -> string! const Android.Provider.MediaStore.Images.ImageColumns.InferredDate = "inferred_date" -> string! const Android.Provider.MediaStore.Images.ImageColumns.OemMetadata = "oem_metadata" -> string! const Android.Provider.MediaStore.Images.Media.InterfaceConsts.InferredDate = "inferred_date" -> string! const Android.Provider.MediaStore.Images.Media.InterfaceConsts.OemMetadata = "oem_metadata" -> string! -const Android.Provider.MediaStore.IMediaColumns.InferredDate = "inferred_date" -> string! -const Android.Provider.MediaStore.IMediaColumns.OemMetadata = "oem_metadata" -> string! const Android.Provider.MediaStore.MediaColumns.InferredDate = "inferred_date" -> string! const Android.Provider.MediaStore.MediaColumns.OemMetadata = "oem_metadata" -> string! const Android.Provider.MediaStore.QueryArgMediaStandardSortOrder = "android:query-arg-media-standard-sort-order" -> string! @@ -3371,8 +3395,8 @@ const Android.Service.Carrier.CarrierMessagingService.SendStatusResultErrorNullP const Android.Service.Carrier.CarrierMessagingService.SendStatusResultErrorShortCodeNeverAllowed = Android.Service.Carrier.SendStatusResultType.ErrorShortCodeNeverAllowed -> Android.Service.Carrier.SendStatusResultType const Android.Service.Carrier.CarrierMessagingService.SendStatusResultErrorShortCodeNotAllowed = Android.Service.Carrier.SendStatusResultType.ErrorShortCodeNotAllowed -> Android.Service.Carrier.SendStatusResultType const Android.Service.Carrier.CarrierMessagingService.SendStatusResultInvalidArguments = Android.Service.Carrier.SendStatusResultType.InvalidArguments -> Android.Service.Carrier.SendStatusResultType -const Android.Service.Carrier.CarrierMessagingService.SendStatusResultInvalidSmscAddress = Android.Service.Carrier.SendStatusResultType.InvalidSmscAddress -> Android.Service.Carrier.SendStatusResultType const Android.Service.Carrier.CarrierMessagingService.SendStatusResultInvalidSmsFormat = Android.Service.Carrier.SendStatusResultType.InvalidSmsFormat -> Android.Service.Carrier.SendStatusResultType +const Android.Service.Carrier.CarrierMessagingService.SendStatusResultInvalidSmscAddress = Android.Service.Carrier.SendStatusResultType.InvalidSmscAddress -> Android.Service.Carrier.SendStatusResultType const Android.Service.Carrier.CarrierMessagingService.SendStatusResultInvalidState = Android.Service.Carrier.SendStatusResultType.InvalidState -> Android.Service.Carrier.SendStatusResultType const Android.Service.Carrier.CarrierMessagingService.SendStatusResultNetworkError = Android.Service.Carrier.SendStatusResultType.NetworkError -> Android.Service.Carrier.SendStatusResultType const Android.Service.Carrier.CarrierMessagingService.SendStatusResultNetworkReject = Android.Service.Carrier.SendStatusResultType.NetworkReject -> Android.Service.Carrier.SendStatusResultType @@ -3398,20 +3422,6 @@ const Android.Service.Settings.Preferences.MetadataResult.InterfaceConsts.Parcel const Android.Service.Settings.Preferences.MetadataResult.ResultInternalError = Android.Service.Settings.Preferences.MetadataResultType.InternalError -> Android.Service.Settings.Preferences.MetadataResultType const Android.Service.Settings.Preferences.MetadataResult.ResultOk = Android.Service.Settings.Preferences.MetadataResultType.Ok -> Android.Service.Settings.Preferences.MetadataResultType const Android.Service.Settings.Preferences.MetadataResult.ResultUnsupported = Android.Service.Settings.Preferences.MetadataResultType.Unsupported -> Android.Service.Settings.Preferences.MetadataResultType -const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.DeeplinkOnly = Android.Service.Settings.Preferences.SettingsPreferenceMetadataType.DeeplinkOnly -> Android.Service.Settings.Preferences.SettingsPreferenceMetadataType -const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.ExpectPostConfirmation = Android.Service.Settings.Preferences.SettingsPreferenceMetadataType.ExpectPostConfirmation -> Android.Service.Settings.Preferences.SettingsPreferenceMetadataType -const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.InterfaceConsts.ContentsFileDescriptor = 1 -> int -const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.InterfaceConsts.ParcelableWriteReturnValue = Android.OS.ParcelableWriteFlags.ReturnValue -> Android.OS.ParcelableWriteFlags -const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.NoDirectAccess = Android.Service.Settings.Preferences.SettingsPreferenceMetadataType.NoDirectAccess -> Android.Service.Settings.Preferences.SettingsPreferenceMetadataType -const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.NoSensitivity = Android.Service.Settings.Preferences.SettingsPreferenceMetadataType.NoSensitivity -> Android.Service.Settings.Preferences.SettingsPreferenceMetadataType -const Android.Service.Settings.Preferences.SettingsPreferenceService.ActionPreferenceService = "android.service.settings.preferences.action.PREFERENCE_SERVICE" -> string! -const Android.Service.Settings.Preferences.SettingsPreferenceValue.InterfaceConsts.ContentsFileDescriptor = 1 -> int -const Android.Service.Settings.Preferences.SettingsPreferenceValue.InterfaceConsts.ParcelableWriteReturnValue = Android.OS.ParcelableWriteFlags.ReturnValue -> Android.OS.ParcelableWriteFlags -const Android.Service.Settings.Preferences.SettingsPreferenceValue.TypeBoolean = Android.Service.Settings.Preferences.SettingsPreferenceValueType.Boolean -> Android.Service.Settings.Preferences.SettingsPreferenceValueType -const Android.Service.Settings.Preferences.SettingsPreferenceValue.TypeDouble = Android.Service.Settings.Preferences.SettingsPreferenceValueType.Double -> Android.Service.Settings.Preferences.SettingsPreferenceValueType -const Android.Service.Settings.Preferences.SettingsPreferenceValue.TypeInt = Android.Service.Settings.Preferences.SettingsPreferenceValueType.Int -> Android.Service.Settings.Preferences.SettingsPreferenceValueType -const Android.Service.Settings.Preferences.SettingsPreferenceValue.TypeLong = Android.Service.Settings.Preferences.SettingsPreferenceValueType.Long -> Android.Service.Settings.Preferences.SettingsPreferenceValueType -const Android.Service.Settings.Preferences.SettingsPreferenceValue.TypeString = Android.Service.Settings.Preferences.SettingsPreferenceValueType.String -> Android.Service.Settings.Preferences.SettingsPreferenceValueType const Android.Service.Settings.Preferences.SetValueRequest.InterfaceConsts.ContentsFileDescriptor = 1 -> int const Android.Service.Settings.Preferences.SetValueRequest.InterfaceConsts.ParcelableWriteReturnValue = Android.OS.ParcelableWriteFlags.ReturnValue -> Android.OS.ParcelableWriteFlags const Android.Service.Settings.Preferences.SetValueResult.InterfaceConsts.ContentsFileDescriptor = 1 -> int @@ -3426,6 +3436,20 @@ const Android.Service.Settings.Preferences.SetValueResult.ResultRequireUserConse const Android.Service.Settings.Preferences.SetValueResult.ResultRestricted = Android.Service.Settings.Preferences.SetValueResultType.Restricted -> Android.Service.Settings.Preferences.SetValueResultType const Android.Service.Settings.Preferences.SetValueResult.ResultUnavailable = Android.Service.Settings.Preferences.SetValueResultType.Unavailable -> Android.Service.Settings.Preferences.SetValueResultType const Android.Service.Settings.Preferences.SetValueResult.ResultUnsupported = Android.Service.Settings.Preferences.SetValueResultType.Unsupported -> Android.Service.Settings.Preferences.SetValueResultType +const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.DeeplinkOnly = Android.Service.Settings.Preferences.SettingsPreferenceMetadataType.DeeplinkOnly -> Android.Service.Settings.Preferences.SettingsPreferenceMetadataType +const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.ExpectPostConfirmation = Android.Service.Settings.Preferences.SettingsPreferenceMetadataType.ExpectPostConfirmation -> Android.Service.Settings.Preferences.SettingsPreferenceMetadataType +const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.InterfaceConsts.ContentsFileDescriptor = 1 -> int +const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.InterfaceConsts.ParcelableWriteReturnValue = Android.OS.ParcelableWriteFlags.ReturnValue -> Android.OS.ParcelableWriteFlags +const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.NoDirectAccess = Android.Service.Settings.Preferences.SettingsPreferenceMetadataType.NoDirectAccess -> Android.Service.Settings.Preferences.SettingsPreferenceMetadataType +const Android.Service.Settings.Preferences.SettingsPreferenceMetadata.NoSensitivity = Android.Service.Settings.Preferences.SettingsPreferenceMetadataType.NoSensitivity -> Android.Service.Settings.Preferences.SettingsPreferenceMetadataType +const Android.Service.Settings.Preferences.SettingsPreferenceService.ActionPreferenceService = "android.service.settings.preferences.action.PREFERENCE_SERVICE" -> string! +const Android.Service.Settings.Preferences.SettingsPreferenceValue.InterfaceConsts.ContentsFileDescriptor = 1 -> int +const Android.Service.Settings.Preferences.SettingsPreferenceValue.InterfaceConsts.ParcelableWriteReturnValue = Android.OS.ParcelableWriteFlags.ReturnValue -> Android.OS.ParcelableWriteFlags +const Android.Service.Settings.Preferences.SettingsPreferenceValue.TypeBoolean = Android.Service.Settings.Preferences.SettingsPreferenceValueType.Boolean -> Android.Service.Settings.Preferences.SettingsPreferenceValueType +const Android.Service.Settings.Preferences.SettingsPreferenceValue.TypeDouble = Android.Service.Settings.Preferences.SettingsPreferenceValueType.Double -> Android.Service.Settings.Preferences.SettingsPreferenceValueType +const Android.Service.Settings.Preferences.SettingsPreferenceValue.TypeInt = Android.Service.Settings.Preferences.SettingsPreferenceValueType.Int -> Android.Service.Settings.Preferences.SettingsPreferenceValueType +const Android.Service.Settings.Preferences.SettingsPreferenceValue.TypeLong = Android.Service.Settings.Preferences.SettingsPreferenceValueType.Long -> Android.Service.Settings.Preferences.SettingsPreferenceValueType +const Android.Service.Settings.Preferences.SettingsPreferenceValue.TypeString = Android.Service.Settings.Preferences.SettingsPreferenceValueType.String -> Android.Service.Settings.Preferences.SettingsPreferenceValueType const Android.Telephony.CarrierConfigManager.Gps.KeyEnableNiSuplMessageInjectionBool = "gps.enable_ni_supl_message_injection_bool" -> string! const Android.Telephony.CarrierConfigManager.KeyCarrierRoamingNtnEmergencyCallToSatelliteHandoverTypeInt = "carrier_roaming_ntn_emergency_call_to_satellite_handover_type_int" -> string! const Android.Telephony.CarrierConfigManager.KeySatelliteEsosSupportedBool = "satellite_esos_supported_bool" -> string! @@ -3496,24 +3520,8 @@ const Android.Widget.PhotoPicker.EmbeddedPhotoPickerFeatureInfo.InterfaceConsts. const Android.Widget.PhotoPicker.EmbeddedPhotoPickerFeatureInfo.InterfaceConsts.ParcelableWriteReturnValue = Android.OS.ParcelableWriteFlags.ReturnValue -> Android.OS.ParcelableWriteFlags const Android.Window.BackEvent.EdgeNone = Android.Window.BackEventEdge.None -> Android.Window.BackEventEdge const Android.Window.IOnBackInvokedDispatcher.PrioritySystemNavigationObserver = -2 -> int -Java.Lang.Invoke.StringConcatException -Java.Lang.Invoke.StringConcatException.StringConcatException(nint javaReference, Android.Runtime.JniHandleOwnership transfer) -> void -Java.Lang.Invoke.StringConcatException.StringConcatException(string? msg) -> void -Java.Lang.Invoke.StringConcatException.StringConcatException(string? msg, Java.Lang.Throwable? cause) -> void -Java.Lang.MatchException -Java.Lang.MatchException.MatchException(string? message, Java.Lang.Throwable? cause) -> void -Java.Lang.Runtimes.SwitchBootstraps -Java.Lang.Runtimes.SwitchBootstraps.SwitchBootstraps(nint javaReference, Android.Runtime.JniHandleOwnership transfer) -> void -Java.Lang.Thread.IsVirtual.get -> bool -Java.Lang.Thread.ThreadId() -> long -Java.Util.Concurrent.ForkJoinTask.QuietlyJoin(long timeout, Java.Util.Concurrent.TimeUnit? unit) -> bool -Java.Util.Concurrent.ForkJoinTask.QuietlyJoinUninterruptibly(long timeout, Java.Util.Concurrent.TimeUnit? unit) -> bool -Java.Util.Concurrent.ForkJoinWorkerThread.ForkJoinWorkerThread(Java.Lang.ThreadGroup? group, Java.Util.Concurrent.ForkJoinPool? pool, bool preserveThreadLocals) -> void -Java.Util.Concurrent.IExecutorService.Close() -> void -Java.Util.Concurrent.IFuture.ExceptionNow() -> Java.Lang.Throwable? -Java.Util.Concurrent.IFuture.InvokeState() -> Java.Util.Concurrent.IFuture.State? -Java.Util.Concurrent.IFuture.ResultNow() -> Java.Lang.Object? -Java.Util.Concurrent.IFuture.State +const Java.Interop.JavaPeerCallbackFormatAttribute.ConnectorDelegates = 1 -> int +const Java.Interop.JavaPeerCallbackFormatAttribute.UnmanagedCallersOnlyCallbacks = 2 -> int override Android.AdServices.AdSelection.PerBuyerConfiguration.Builder.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.AdServices.AdSelection.PerBuyerConfiguration.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.AdServices.AdSelection.SellerConfiguration.Builder.JniPeerMembers.get -> Java.Interop.JniPeerMembers! @@ -3777,6 +3785,10 @@ override Android.Service.Settings.Preferences.MetadataRequest.Builder.JniPeerMem override Android.Service.Settings.Preferences.MetadataRequest.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.Service.Settings.Preferences.MetadataResult.Builder.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.Service.Settings.Preferences.MetadataResult.JniPeerMembers.get -> Java.Interop.JniPeerMembers! +override Android.Service.Settings.Preferences.SetValueRequest.Builder.JniPeerMembers.get -> Java.Interop.JniPeerMembers! +override Android.Service.Settings.Preferences.SetValueRequest.JniPeerMembers.get -> Java.Interop.JniPeerMembers! +override Android.Service.Settings.Preferences.SetValueResult.Builder.JniPeerMembers.get -> Java.Interop.JniPeerMembers! +override Android.Service.Settings.Preferences.SetValueResult.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.Service.Settings.Preferences.SettingsPreferenceMetadata.Builder.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.Service.Settings.Preferences.SettingsPreferenceMetadata.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.Service.Settings.Preferences.SettingsPreferenceService.JniPeerMembers.get -> Java.Interop.JniPeerMembers! @@ -3787,10 +3799,6 @@ override Android.Service.Settings.Preferences.SettingsPreferenceServiceClient.Th override Android.Service.Settings.Preferences.SettingsPreferenceServiceClient.ThresholdType.get -> System.Type! override Android.Service.Settings.Preferences.SettingsPreferenceValue.Builder.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.Service.Settings.Preferences.SettingsPreferenceValue.JniPeerMembers.get -> Java.Interop.JniPeerMembers! -override Android.Service.Settings.Preferences.SetValueRequest.Builder.JniPeerMembers.get -> Java.Interop.JniPeerMembers! -override Android.Service.Settings.Preferences.SetValueRequest.JniPeerMembers.get -> Java.Interop.JniPeerMembers! -override Android.Service.Settings.Preferences.SetValueResult.Builder.JniPeerMembers.get -> Java.Interop.JniPeerMembers! -override Android.Service.Settings.Preferences.SetValueResult.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.Telephony.Satellite.SatelliteManager.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.Text.Style.NoWritingToolsSpan.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.Text.Style.TtsSpan.DurationBuilder.JniPeerMembers.get -> Java.Interop.JniPeerMembers! @@ -3955,20 +3963,81 @@ static Android.Ranging.Uwb.UwbRangingCapabilities.Creator.get -> Android.OS.IPar static Android.Ranging.Uwb.UwbRangingParams.Creator.get -> Android.OS.IParcelableCreator! static Android.Ranging.Wifi.Rtt.RttRangingCapabilities.Creator.get -> Android.OS.IParcelableCreator! static Android.Ranging.Wifi.Rtt.RttRangingParams.Creator.get -> Android.OS.IParcelableCreator! +static Android.Runtime.JNIEnv.BridgeProcessingGeneration.get -> int static Android.Service.Settings.Preferences.GetValueRequest.Creator.get -> Android.OS.IParcelableCreator! static Android.Service.Settings.Preferences.GetValueResult.Creator.get -> Android.OS.IParcelableCreator! static Android.Service.Settings.Preferences.MetadataRequest.Creator.get -> Android.OS.IParcelableCreator! static Android.Service.Settings.Preferences.MetadataResult.Creator.get -> Android.OS.IParcelableCreator! -static Android.Service.Settings.Preferences.SettingsPreferenceMetadata.Creator.get -> Android.OS.IParcelableCreator! -static Android.Service.Settings.Preferences.SettingsPreferenceValue.Creator.get -> Android.OS.IParcelableCreator! static Android.Service.Settings.Preferences.SetValueRequest.Creator.get -> Android.OS.IParcelableCreator! static Android.Service.Settings.Preferences.SetValueResult.Creator.get -> Android.OS.IParcelableCreator! +static Android.Service.Settings.Preferences.SettingsPreferenceMetadata.Creator.get -> Android.OS.IParcelableCreator! +static Android.Service.Settings.Preferences.SettingsPreferenceValue.Creator.get -> Android.OS.IParcelableCreator! static Android.Text.Style.NoWritingToolsSpan.Creator.get -> Android.OS.IParcelableCreator! static Android.Views.Accessibility.AccessibilityNodeInfo.RangeInfo.Indeterminate.get -> Android.Views.Accessibility.AccessibilityNodeInfo.RangeInfo! static Android.Widget.PhotoPicker.EmbeddedPhotoPickerFeatureInfo.Creator.get -> Android.OS.IParcelableCreator! static Android.Widget.PhotoPicker.EmbeddedPhotoPickerProviderFactory.Create(Android.Content.Context! context) -> Android.Widget.PhotoPicker.IEmbeddedPhotoPickerProvider! static Android.Window.SystemOnBackInvokedCallbacks.FinishAndRemoveTaskCallback(Android.App.Activity! activity) -> Android.Window.IOnBackInvokedCallback! static Android.Window.SystemOnBackInvokedCallbacks.MoveTaskToBackCallback(Android.App.Activity! activity) -> Android.Window.IOnBackInvokedCallback! +static Java.Interop.JniMarshalTyped.Invoke_O(nint jnienv, nint self, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OO(nint jnienv, nint self, nint native_p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOO(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOO(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOS(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOOX(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOS(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSO(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOSS(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSX(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOX(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OS(nint jnienv, nint self, nint native_p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSO(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOO(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOS(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSOX(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSS(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSO(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSSS(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSX(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSX(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OX(nint jnienv, nint self, nint native_p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_S(nint jnienv, nint self, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SO(nint jnienv, nint self, T0 p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOO(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOO(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOS(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOOX(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOS(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSO(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOSS(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSX(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOX(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SS(nint jnienv, nint self, T0 p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSO(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOO(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOS(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSOX(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSS(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSX(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SX(nint jnienv, nint self, T0 p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_X(nint jnienv, nint self, delegate* body) -> void static Java.Lang.Character.IsEmoji(int codePoint) -> bool static Java.Lang.Character.IsEmojiComponent(int codePoint) -> bool static Java.Lang.Character.IsEmojiModifier(int codePoint) -> bool @@ -4200,8 +4269,8 @@ virtual Android.Media.TV.Ads.TvAdService.Session.OnStartAdService() -> void virtual Android.Media.TV.Ads.TvAdService.Session.OnStopAdService() -> void virtual Android.Media.TV.Ads.TvAdService.Session.OnSurfaceChanged(int format, int width, int height) -> void virtual Android.Media.TV.Ads.TvAdService.Session.OnTouchEvent(Android.Views.MotionEvent! e) -> bool -virtual Android.Media.TV.Ads.TvAdService.Session.OnTrackballEvent(Android.Views.MotionEvent! e) -> bool virtual Android.Media.TV.Ads.TvAdService.Session.OnTrackInfoList(System.Collections.Generic.IList! tracks) -> void +virtual Android.Media.TV.Ads.TvAdService.Session.OnTrackballEvent(Android.Views.MotionEvent! e) -> bool virtual Android.Media.TV.Ads.TvAdService.Session.OnTvInputSessionData(string! type, Android.OS.Bundle! data) -> void virtual Android.Media.TV.Ads.TvAdService.Session.OnTvMessage(int type, Android.OS.Bundle! data) -> void virtual Android.Media.TV.Ads.TvAdService.Session.RequestCurrentChannelUri() -> void @@ -4400,6 +4469,3 @@ virtual Java.Util.Concurrent.FutureTask.ResultNow() -> Java.Lang.Object? virtual Java.Util.Concurrent.FutureTask.State() -> Java.Util.Concurrent.IFuture.State? virtual Java.Util.IdentityHashMap.Remove(Java.Lang.Object? key, Java.Lang.Object? value) -> bool virtual Java.Util.IdentityHashMap.Replace(Java.Lang.Object? key, Java.Lang.Object? oldValue, Java.Lang.Object? newValue) -> bool -Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.get -> bool -Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.set -> void -Java.Interop.BaseExportAttribute diff --git a/src/Mono.Android/PublicAPI/API-37.1/PublicAPI.Unshipped.txt b/src/Mono.Android/PublicAPI/API-37.1/PublicAPI.Unshipped.txt index ae1d14901c7..1dfe40f2978 100644 --- a/src/Mono.Android/PublicAPI/API-37.1/PublicAPI.Unshipped.txt +++ b/src/Mono.Android/PublicAPI/API-37.1/PublicAPI.Unshipped.txt @@ -1,4 +1,70 @@ #nullable enable Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.get -> bool Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.set -> void +Java.Interop.JavaPeerCallbackFormatAttribute +Java.Interop.JavaPeerCallbackFormatAttribute.JavaPeerCallbackFormatAttribute(int version) -> void +Java.Interop.JavaPeerCallbackFormatAttribute.Version.get -> int +Java.Interop.JniMarshalTyped +const Java.Interop.JavaPeerCallbackFormatAttribute.ConnectorDelegates = 1 -> int +const Java.Interop.JavaPeerCallbackFormatAttribute.UnmanagedCallersOnlyCallbacks = 2 -> int static Android.Runtime.JNIEnv.BridgeProcessingGeneration.get -> int +static Java.Interop.JniMarshalTyped.Invoke_O(nint jnienv, nint self, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OO(nint jnienv, nint self, nint native_p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOO(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOO(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOS(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOOX(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOS(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSO(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOSS(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSX(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOX(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OS(nint jnienv, nint self, nint native_p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSO(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOO(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOS(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSOX(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSS(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSO(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSSS(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSX(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSX(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OX(nint jnienv, nint self, nint native_p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_S(nint jnienv, nint self, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SO(nint jnienv, nint self, T0 p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOO(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOO(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOS(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOOX(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOS(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSO(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOSS(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSX(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOX(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SS(nint jnienv, nint self, T0 p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSO(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOO(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOS(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSOX(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSS(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSX(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SX(nint jnienv, nint self, T0 p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_X(nint jnienv, nint self, delegate* body) -> void diff --git a/src/Mono.Android/PublicAPI/API-37.2/PublicAPI.Unshipped.txt b/src/Mono.Android/PublicAPI/API-37.2/PublicAPI.Unshipped.txt index 4f7e6a01587..95ca6d20035 100644 --- a/src/Mono.Android/PublicAPI/API-37.2/PublicAPI.Unshipped.txt +++ b/src/Mono.Android/PublicAPI/API-37.2/PublicAPI.Unshipped.txt @@ -1,3 +1,69 @@ #nullable enable Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.get -> bool Android.App.ApplicationAttribute.EnableOnBackInvokedCallback.set -> void +Java.Interop.JavaPeerCallbackFormatAttribute +Java.Interop.JavaPeerCallbackFormatAttribute.JavaPeerCallbackFormatAttribute(int version) -> void +Java.Interop.JavaPeerCallbackFormatAttribute.Version.get -> int +Java.Interop.JniMarshalTyped +const Java.Interop.JavaPeerCallbackFormatAttribute.ConnectorDelegates = 1 -> int +const Java.Interop.JavaPeerCallbackFormatAttribute.UnmanagedCallersOnlyCallbacks = 2 -> int +static Java.Interop.JniMarshalTyped.Invoke_O(nint jnienv, nint self, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OO(nint jnienv, nint self, nint native_p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOO(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOO(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOS(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOOX(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOS(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSO(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOSS(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSX(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOX(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OS(nint jnienv, nint self, nint native_p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSO(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOO(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOS(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSOX(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSS(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSO(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSSS(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSX(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSX(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OX(nint jnienv, nint self, nint native_p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_S(nint jnienv, nint self, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SO(nint jnienv, nint self, T0 p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOO(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOO(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOS(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOOX(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOS(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSO(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOSS(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSX(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOX(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SS(nint jnienv, nint self, T0 p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSO(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOO(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOS(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSOX(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSS(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSX(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SX(nint jnienv, nint self, T0 p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_X(nint jnienv, nint self, delegate* body) -> void diff --git a/src/Mono.Android/PublicAPI/API-37/PublicAPI.Unshipped.txt b/src/Mono.Android/PublicAPI/API-37/PublicAPI.Unshipped.txt index 61a2234c60d..d021c0b9666 100644 --- a/src/Mono.Android/PublicAPI/API-37/PublicAPI.Unshipped.txt +++ b/src/Mono.Android/PublicAPI/API-37/PublicAPI.Unshipped.txt @@ -2349,10 +2349,14 @@ Java.Interop.IAndroidCallableWrapper.RegisterNatives(Java.Interop.JniType! nativ Java.Interop.JavaPeerAliasesAttribute Java.Interop.JavaPeerAliasesAttribute.Aliases.get -> string![]! Java.Interop.JavaPeerAliasesAttribute.JavaPeerAliasesAttribute(params string![]! aliases) -> void +Java.Interop.JavaPeerCallbackFormatAttribute +Java.Interop.JavaPeerCallbackFormatAttribute.JavaPeerCallbackFormatAttribute(int version) -> void +Java.Interop.JavaPeerCallbackFormatAttribute.Version.get -> int Java.Interop.JavaPeerProxy Java.Interop.JavaPeerProxy.JavaPeerProxy(string! jniName, System.Type! targetType) -> void Java.Interop.JavaPeerProxy.JniName.get -> string! Java.Interop.JavaPeerProxy.TargetType.get -> System.Type! +Java.Interop.JniMarshalTyped Java.Lang.ICharSequence.GetChars(int srcBegin, int srcEnd, char[]! dst, int dstBegin) -> void Java.Lang.IllegalCallerException Java.Lang.IllegalCallerException.IllegalCallerException() -> void @@ -3848,6 +3852,8 @@ const Android.Widget.PhotoPicker.PhotoPickerUiCustomizationParams.AspectRatioSqu const Android.Widget.PhotoPicker.PhotoPickerUiCustomizationParams.AspectRatioUndefined = Android.Widget.Photopicker.AspectRatio.Undefined -> Android.Widget.Photopicker.AspectRatio const Android.Widget.PhotoPicker.PhotoPickerUiCustomizationParams.InterfaceConsts.ContentsFileDescriptor = 1 -> int const Android.Widget.PhotoPicker.PhotoPickerUiCustomizationParams.InterfaceConsts.ParcelableWriteReturnValue = Android.OS.ParcelableWriteFlags.ReturnValue -> Android.OS.ParcelableWriteFlags +const Java.Interop.JavaPeerCallbackFormatAttribute.ConnectorDelegates = 1 -> int +const Java.Interop.JavaPeerCallbackFormatAttribute.UnmanagedCallersOnlyCallbacks = 2 -> int override Android.App.AnrTypes.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.App.AnrWarningResult.JniPeerMembers.get -> Java.Interop.JniPeerMembers! override Android.App.AppFunctions.AppFunctionActivityId.JniPeerMembers.get -> Java.Interop.JniPeerMembers! @@ -4378,6 +4384,66 @@ static Java.Interop.JavaPeerProxy.GetActivationPeer(nint jniSelf) -> Java.Intero static Java.Interop.JavaPeerProxy.MarkActivationPeerReplaceable(nint jniSelf) -> void static Java.Interop.JavaPeerProxy.SetActivationPeerReference(Java.Interop.IJavaPeerable! peer, nint jniSelf) -> void static Java.Interop.JavaPeerProxy.ShouldSkipActivation(nint jniSelf) -> bool +static Java.Interop.JniMarshalTyped.Invoke_O(nint jnienv, nint self, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OO(nint jnienv, nint self, nint native_p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOO(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOO(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOOS(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOOX(nint jnienv, nint self, nint native_p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOS(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSO(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OOSS(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OOSX(nint jnienv, nint self, nint native_p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OOX(nint jnienv, nint self, nint native_p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OS(nint jnienv, nint self, nint native_p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSO(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOO(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSOS(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSOX(nint jnienv, nint self, nint native_p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSS(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSO(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_OSSS(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_OSSX(nint jnienv, nint self, nint native_p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OSX(nint jnienv, nint self, nint native_p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_OX(nint jnienv, nint self, nint native_p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_S(nint jnienv, nint self, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SO(nint jnienv, nint self, T0 p0, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOO(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOO(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOOS(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOOX(nint jnienv, nint self, T0 p0, nint native_p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOS(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSO(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SOSS(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SOSX(nint jnienv, nint self, T0 p0, nint native_p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SOX(nint jnienv, nint self, T0 p0, nint native_p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SS(nint jnienv, nint self, T0 p0, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSO(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOO(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSOS(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSOX(nint jnienv, nint self, T0 p0, T1 p1, nint native_p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSS(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSO(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> nint +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSS(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> TResult +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, T3 p3, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSSX(nint jnienv, nint self, T0 p0, T1 p1, T2 p2, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SSX(nint jnienv, nint self, T0 p0, T1 p1, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_SX(nint jnienv, nint self, T0 p0, delegate* body) -> void +static Java.Interop.JniMarshalTyped.Invoke_X(nint jnienv, nint self, delegate* body) -> void static Java.Lang.Character.UnicodeBlock.CjkUnifiedIdeographsExtensionI.get -> Java.Lang.Character.UnicodeBlock? static Java.Lang.Character.UnicodeBlock.EgyptianHieroglyphsExtendedA.get -> Java.Lang.Character.UnicodeBlock? static Java.Lang.Character.UnicodeBlock.Garay.get -> Java.Lang.Character.UnicodeBlock? diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets index 37047bc3904..ff29657c0fd 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets @@ -120,6 +120,7 @@ It is shared between "legacy" binding projects and .NET 5 projects. EnableBindingInterfaceConstants="$(AndroidBoundInterfacesContainConstants)" EnableRestrictToAttributes="$(AndroidEnableRestrictToAttributes)" EnableObsoleteOverrideInheritance="$(AndroidEnableObsoleteOverrideInheritance)" + EnableUnmanagedCallersOnlyCallbacks="$(_AndroidEnableUnmanagedCallersOnlyCallbacks)" Nullable="$(Nullable)" NamespaceTransforms="@(AndroidNamespaceReplacement)" /> diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets index 0ec86571c9a..c7d13825cf7 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets @@ -51,6 +51,15 @@ true true true + + + <_AndroidEnableUnmanagedCallersOnlyCallbacks Condition=" '$(_AndroidEnableUnmanagedCallersOnlyCallbacks)' == '' ">false obsolete true diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs index 64594d09ffa..81b58f075c7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs @@ -55,6 +55,14 @@ public class BindingsGenerator : AndroidDotnetToolTask public bool EnableBindingInterfaceConstants { get; set; } public string? EnableRestrictToAttributes { get; set; } public bool EnableObsoleteOverrideInheritance { get; set; } + + /// + /// Experimental, for internal use: emit each supported non-generic n_* binding + /// callback as an [UnmanagedCallersOnly] method which forwards to a shared typed + /// marshaling helper, and omit the cb_* delegate cache fields and + /// Get*Handler () connector methods. Requires the trimmable typemap. + /// + public bool EnableUnmanagedCallersOnlyCallbacks { get; set; } public string? Nullable { get; set; } public ITaskItem[]? TransformFiles { get; set; } @@ -231,6 +239,9 @@ protected override string GenerateCommandLineCommands () if (string.Equals (Nullable, "enable", StringComparison.OrdinalIgnoreCase)) features.Add ("nullable-reference-types"); + if (EnableUnmanagedCallersOnlyCallbacks) + features.Add ("unmanaged-callers-only-callbacks"); + if (features.Any ()) WriteLine (sw, $"--lang-features={string.Join (",", features)}"); } diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/FixtureTestBase.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/FixtureTestBase.cs index dd12967da2f..c48b7be3308 100644 --- a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/FixtureTestBase.cs +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/FixtureTestBase.cs @@ -200,6 +200,22 @@ private protected static bool ILContainsNewobjToken (byte[] ilBytes, int token) return ILContainsOpcodeToken (ilBytes, token, (byte) ILOpCode.Newobj); } + private protected static List ReadLdftnTokens (byte [] ilBytes) + { + var tokens = new List (); + for (int i = 0; i < ilBytes.Length - 5; i++) { + if (ilBytes [i] != 0xFE || ilBytes [i + 1] != 0x06) { + continue; + } + + tokens.Add (ilBytes [i + 2] | + (ilBytes [i + 3] << 8) | + (ilBytes [i + 4] << 16) | + (ilBytes [i + 5] << 24)); + } + return tokens; + } + static bool ILContainsOpcodeToken (byte[] ilBytes, int token, params byte[] opcodes) { byte t0 = (byte)(token & 0xFF); diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/TypeMapAssemblyGeneratorTests.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/TypeMapAssemblyGeneratorTests.cs index dafa0b1f59f..e20005ce126 100644 --- a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/TypeMapAssemblyGeneratorTests.cs +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/TypeMapAssemblyGeneratorTests.cs @@ -1254,11 +1254,6 @@ static List FindMethodDefinitions (MetadataReader reader .ToList (); } - static List ReadLdftnTokens (byte [] ilBytes) - { - return ReadInlineMethodTokens (ilBytes, 0xFE, 0x06); - } - static List ReadCallTokens (byte [] ilBytes) { return ReadInlineMethodTokens (ilBytes, 0x28); @@ -1280,22 +1275,6 @@ static List ReadInlineMethodTokens (byte [] ilBytes, byte opcode) return tokens; } - static List ReadInlineMethodTokens (byte [] ilBytes, byte opcodePrefix, byte opcode) - { - var tokens = new List (); - for (int i = 0; i < ilBytes.Length - 5; i++) { - if (ilBytes [i] != opcodePrefix || ilBytes [i + 1] != opcode) { - continue; - } - - tokens.Add (ilBytes [i + 2] | - (ilBytes [i + 3] << 8) | - (ilBytes [i + 4] << 16) | - (ilBytes [i + 5] << 24)); - } - return tokens; - } - static JavaPeerInfo MakeInheritedOverridePeer (string jniName, string managedName, string declaringTypeName = "MyApp.AbstractBase") { diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests.csproj b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests.csproj index 0586a0b1b95..4ecc09d732a 100644 --- a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests.csproj +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests.csproj @@ -15,6 +15,7 @@ + @@ -32,6 +33,9 @@ false + + false + @@ -39,8 +43,11 @@ <_TestFixtureFiles Include="TestFixtures\bin\$(Configuration)\$(DotNetStableTargetFramework)\TestFixtures.dll" /> <_TestFixtureFiles Include="TestAttributeFixtures\bin\$(Configuration)\$(DotNetStableTargetFramework)\TestAttributeFixtures.dll" /> + <_TestFixtureFiles Include="TestUcoFixtures\bin\$(Configuration)\$(DotNetStableTargetFramework)\TestUcoFixtures.dll" /> + diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Scanner/UnmanagedCallersOnlyCallbackTests.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Scanner/UnmanagedCallersOnlyCallbackTests.cs new file mode 100644 index 00000000000..c9c5a2539cb --- /dev/null +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Scanner/UnmanagedCallersOnlyCallbackTests.cs @@ -0,0 +1,406 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Reflection.PortableExecutable; +using System.Text; +using Xunit; + +namespace Microsoft.Android.Sdk.TrimmableTypeMap.Tests; + +/// +/// Covers the experimental [UnmanagedCallersOnly] binding callback format: a binding +/// assembly marked with [assembly: JavaPeerCallbackFormat (2)] emits n_* callbacks +/// that are themselves [UnmanagedCallersOnly] and have no Get*Handler () connector. +/// Such callbacks must be bound by RegisterNatives directly, because a generated forwarding +/// wrapper would have to managed-call them, which the runtime forbids. +/// +public class UnmanagedCallersOnlyCallbackTests : FixtureTestBase +{ + static string UcoFixtureAssemblyPath { + get { + var dir = Path.GetDirectoryName (typeof (UnmanagedCallersOnlyCallbackTests).Assembly.Location) + ?? throw new InvalidOperationException ("Cannot determine test assembly directory"); + var path = Path.Combine (dir, "TestUcoFixtures.dll"); + Assert.True (File.Exists (path), $"TestUcoFixtures.dll not found at {path}."); + return path; + } + } + + static readonly Lazy> _ucoPeers = new (() => { + using var scanner = new JavaPeerScanner (); + using var ucoReader = new PEReader (File.OpenRead (UcoFixtureAssemblyPath)); + using var fixtureReader = new PEReader (File.OpenRead (TestFixtureAssemblyPath)); + return scanner.Scan (new [] { + MakeInput (ucoReader), + MakeInput (fixtureReader), + }); + }); + + static AssemblyInput MakeInput (PEReader peReader) + { + var reader = peReader.GetMetadataReader (); + return new AssemblyInput (reader.GetString (reader.GetAssemblyDefinition ().Name), "", peReader); + } + + static List UcoPeers => _ucoPeers.Value; + + static JavaPeerInfo FindPeer (string managedName) => + UcoPeers.FirstOrDefault (p => p.ManagedTypeName == managedName) + ?? throw new InvalidOperationException ($"Peer '{managedName}' was not scanned."); + + static MarshalMethodInfo FindMarshalMethod (JavaPeerInfo peer, string nativeCallbackName) => + peer.MarshalMethods.FirstOrDefault (m => m.NativeCallbackName == nativeCallbackName) + ?? throw new InvalidOperationException ( + $"'{nativeCallbackName}' not found on {peer.ManagedTypeName}; found: " + + string.Join (", ", peer.MarshalMethods.Select (m => m.NativeCallbackName))); + + const string UcoWidget = "Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.MyWidget"; + const string LegacyWidget = "Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.MyLegacyWidget"; + + [Fact] + public void Scanner_DetectsUnmanagedCallersOnlyCallbacks () + { + var peer = FindPeer (UcoWidget); + Assert.True (FindMarshalMethod (peer, "n_OnLayout_ZIIII").IsUnmanagedCallersOnlyCallback); + Assert.True (FindMarshalMethod (peer, "n_GetCount").IsUnmanagedCallersOnlyCallback); + } + + [Fact] + public void Scanner_LeavesLegacyConnectorCallbacksAlone () + { + var peer = FindPeer (LegacyWidget); + Assert.False (FindMarshalMethod (peer, "n_GetFlags").IsUnmanagedCallersOnlyCallback); + } + + [Fact] + public void Scanner_CapturesCallbackSignatureForMarkedAssemblies () + { + // The marker forces unconditional n_* resolution, so even an unambiguous signature + // (which the scanner would normally skip) has its CLR types captured. + var method = FindMarshalMethod (FindPeer (UcoWidget), "n_OnLayout_ZIIII"); + Assert.NotNull (method.NativeCallbackParameterTypeNames); + var parameterTypes = method.NativeCallbackParameterTypeNames; + Assert.NotNull (parameterTypes); + Assert.Equal (new [] { "System.SByte", "System.Int32", "System.Int32", "System.Int32", "System.Int32" }, parameterTypes); + Assert.Equal ("System.Void", method.NativeCallbackReturnTypeName); + } + + [Fact] + public void Scanner_UnmarkedAssemblies_AreNotTreatedAsUnmanagedCallersOnly () + { + // The regular (unmarked) fixture assembly must be completely unaffected. + foreach (var peer in ScanFixtures ()) { + foreach (var method in peer.MarshalMethods) { + Assert.False (method.IsUnmanagedCallersOnlyCallback, + $"{peer.ManagedTypeName}.{method.NativeCallbackName} should not be [UnmanagedCallersOnly]."); + } + } + } + + [Fact] + public void ModelBuilder_DirectCallbacks_AreNotEmittedAsWrappers () + { + var model = ModelBuilder.Build (UcoPeers, "TestUcoTypeMap.dll", "TestUcoTypeMap"); + var proxy = FindProxy (model, UcoWidget); + + Assert.DoesNotContain (proxy.UcoMethods, u => u.CallbackMethodName == "n_OnLayout_ZIIII"); + Assert.DoesNotContain (proxy.UcoMethods, u => u.CallbackMethodName == "n_GetCount"); + + var registration = proxy.NativeRegistrations.Single (r => r.JniMethodName == "n_OnLayout_ZIIII"); + Assert.NotNull (registration.DirectCallback); + var direct = registration.DirectCallback; + Assert.NotNull (direct); + Assert.True (direct.IsDirectUnmanagedCallersOnlyCallback); + Assert.Equal ("n_OnLayout_ZIIII", direct.CallbackMethodName); + } + + [Fact] + public void ModelBuilder_LegacyCallbacks_StillGetWrappers () + { + var model = ModelBuilder.Build (UcoPeers, "TestUcoTypeMap.dll", "TestUcoTypeMap"); + var proxy = FindProxy (model, LegacyWidget); + + Assert.Contains (proxy.UcoMethods, u => u.CallbackMethodName == "n_GetFlags"); + var registration = proxy.NativeRegistrations.Single (r => r.JniMethodName == "n_GetFlags"); + Assert.Null (registration.DirectCallback); + } + + [Fact] + public void Emitter_DirectCallbacks_AreLdftnThroughAMemberRef () + { + using var stream = new MemoryStream (); + new TypeMapAssemblyGenerator (new Version (11, 0, 0, 0)).Generate (UcoPeers, stream, "TestUcoTypeMap"); + stream.Position = 0; + + using var peReader = new PEReader (stream); + var reader = peReader.GetMetadataReader (); + + // Wrapper names are derived from the JNI method name: n_{jniName}_uco_{i}. + var wrapperNames = reader.MethodDefinitions + .Select (h => reader.GetString (reader.GetMethodDefinition (h).Name)) + .Where (n => n.Contains ("_uco", StringComparison.Ordinal)) + .ToList (); + + // No forwarding wrapper was emitted for the [UnmanagedCallersOnly] callbacks… + Assert.DoesNotContain (wrapperNames, n => n.StartsWith ("n_onLayout_uco", StringComparison.Ordinal)); + Assert.DoesNotContain (wrapperNames, n => n.StartsWith ("n_getCount_uco", StringComparison.Ordinal)); + + // …but the legacy connector callback still has one. + Assert.Contains (wrapperNames, n => n.StartsWith ("n_getFlags_uco", StringComparison.Ordinal)); + + // A MemberRef to the external callback exists, so RegisterNatives can ldftn it. + var memberRefNames = Enumerable.Range (1, reader.GetTableRowCount (TableIndex.MemberRef)) + .Select (MetadataTokens.MemberReferenceHandle) + .Select (h => reader.GetString (reader.GetMemberReference (h).Name)) + .ToList (); + Assert.Contains ("n_OnLayout_ZIIII", memberRefNames); + Assert.Contains ("n_GetCount", memberRefNames); + } + + [Fact] + public void Emitter_ProducesAVerifiablyLoadableAssembly () + { + using var stream = new MemoryStream (); + new TypeMapAssemblyGenerator (new Version (11, 0, 0, 0)).Generate (UcoPeers, stream, "TestUcoTypeMap"); + stream.Position = 0; + + using var peReader = new PEReader (stream); + var reader = peReader.GetMetadataReader (); + Assert.True (reader.IsAssembly); + + // IgnoresAccessChecksTo is required: n_* callbacks are private statics in another assembly. + // The attribute type is synthesized into the generated assembly itself. + var typeNames = reader.TypeDefinitions + .Select (h => reader.GetString (reader.GetTypeDefinition (h).Name)) + .ToList (); + Assert.Contains ("IgnoresAccessChecksToAttribute", typeNames); + + // Every direct registration ldftn's a MemberRef whose declaring type lives in the + // binding assembly, not in the generated typemap assembly. + var callbackRefs = Enumerable.Range (1, reader.GetTableRowCount (TableIndex.MemberRef)) + .Select (MetadataTokens.MemberReferenceHandle) + .Select (h => reader.GetMemberReference (h)) + .Where (mr => reader.GetString (mr.Name) == "n_OnLayout_ZIIII") + .ToList (); + var callbackRef = Assert.Single (callbackRefs); + Assert.Equal (HandleKind.TypeReference, callbackRef.Parent.Kind); + Assert.Equal ("UcoWidget", reader.GetString (reader.GetTypeReference ((TypeReferenceHandle) callbackRef.Parent).Name)); + } + + const string CompactWidget = "Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.MyCompactWidget"; + const string QualifiedWidget = "Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.MyQualifiedWidget"; + const string CallbackHost = "Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.CallbackHost"; + + [Fact] + public void Scanner_ReadsCompactCallbackNamesFromTheConnector () + { + // A compact connector *is* the callback name, so it must be taken verbatim rather than + // being rewritten from Get*Handler or guessed as n_{managedName}. Guessing would collapse + // both overloads onto "n_Remove". + var peer = FindPeer (CompactWidget); + + Assert.True (FindMarshalMethod (peer, "n_Remove").IsUnmanagedCallersOnlyCallback); + Assert.True (FindMarshalMethod (peer, "n_Remove_1").IsUnmanagedCallersOnlyCallback); + } + + [Fact] + public void Scanner_CompactConnector_KeepsItsOwnerQualifier () + { + // Only the segment before ':' is the callback name; the owner qualifier after it is left + // untouched so the existing declaring-type resolution keeps working unchanged. + var peer = FindPeer (QualifiedWidget); + var method = FindMarshalMethod (peer, "n_Handle"); + + Assert.Equal ("n_Handle", method.NativeCallbackName); + Assert.StartsWith ("n_Handle:", method.Connector); + Assert.Contains ("TestUcoFixtures.CallbackHost, TestUcoFixtures", method.Connector); + Assert.True (method.IsUnmanagedCallersOnlyCallback); + Assert.Equal (CallbackHost, method.DeclaringTypeName); + Assert.Equal ("TestUcoFixtures", method.DeclaringAssemblyName); + } + + [Theory] + [InlineData ("n_Handle")] + [InlineData ("n_HandleTypeOnly")] + [InlineData ("n_Count")] + [InlineData ("n_IsEnabled")] + [InlineData ("n_SetEnabled")] + public void QualifiedCallbacks_ResolveOwnerThroughRegistration (string callbackName) + { + var peer = FindPeer (QualifiedWidget); + var method = FindMarshalMethod (peer, callbackName); + Assert.True (method.IsUnmanagedCallersOnlyCallback); + Assert.Equal (CallbackHost, method.DeclaringTypeName); + Assert.Equal ("TestUcoFixtures", method.DeclaringAssemblyName); + Assert.NotNull (method.DeclaringType); + Assert.Equal (CallbackHost, method.DeclaringType.ManagedTypeName); + + var model = ModelBuilder.Build (UcoPeers, "TestUcoTypeMap.dll", "TestUcoTypeMap"); + var proxy = FindProxy (model, QualifiedWidget); + Assert.DoesNotContain (proxy.UcoMethods, u => u.CallbackMethodName == callbackName); + var registration = Assert.Single (proxy.NativeRegistrations, r => r.JniMethodName == callbackName); + Assert.NotNull (registration.DirectCallback); + Assert.Equal (CallbackHost, registration.DirectCallback.CallbackType.ManagedTypeName); + + using var stream = new MemoryStream (); + new TypeMapAssemblyGenerator (new Version (11, 0, 0, 0)).Generate (UcoPeers, stream, "TestUcoTypeMap"); + stream.Position = 0; + using var pe = new PEReader (stream); + var reader = pe.GetMetadataReader (); + var callbackRefHandle = Assert.Single (reader.MemberReferences, + h => reader.GetString (reader.GetMemberReference (h).Name) == callbackName); + var callbackRef = reader.GetMemberReference (callbackRefHandle); + var owner = reader.GetTypeReference ((TypeReferenceHandle) callbackRef.Parent); + Assert.Equal ("CallbackHost", reader.GetString (owner.Name)); + Assert.Equal ("TestUcoFixtures", reader.GetString (reader.GetAssemblyReference ((AssemblyReferenceHandle) owner.ResolutionScope).Name)); + var signature = callbackRef.DecodeMethodSignature (SignatureTypeProvider.Instance, null); + Assert.Equal (method.NativeCallbackReturnTypeName, signature.ReturnType); + Assert.Equal (method.NativeCallbackParameterTypeNames, signature.ParameterTypes.Skip (2)); + + var proxyDef = Assert.Single (reader.TypeDefinitions, + h => reader.GetString (reader.GetTypeDefinition (h).Name) == proxy.TypeName); + var registerDef = reader.GetMethodDefinition (Assert.Single (reader.GetTypeDefinition (proxyDef).GetMethods (), + h => reader.GetString (reader.GetMethodDefinition (h).Name) == "RegisterNatives")); + var il = pe.GetMethodBody (registerDef.RelativeVirtualAddress).GetILBytes (); + Assert.NotNull (il); + Assert.Contains (MetadataTokens.GetToken (callbackRefHandle), ReadLdftnTokens (il)); + } + + [Fact] + public void Scanner_ReferenceAssembly_RejectsUnresolvedUcoCallback () + { + var path = Path.ChangeExtension (UcoFixtureAssemblyPath, ".ref.dll"); + using var pe = new PEReader (File.OpenRead (path)); + var reader = pe.GetMetadataReader (); + Assert.DoesNotContain (reader.MethodDefinitions, + h => reader.GetString (reader.GetMethodDefinition (h).Name) == "n_OnLayout_ZIIII"); + + using var scanner = new JavaPeerScanner (); + using var fixtures = new PEReader (File.OpenRead (TestFixtureAssemblyPath)); + var error = Assert.Throws (() => scanner.Scan (new [] { MakeInput (pe), MakeInput (fixtures) })); + Assert.Contains ("UcoWidget.n_OnLayout_ZIIII", error.Message); + Assert.Contains ("JNI signature '(ZIIII)V'", error.Message); + Assert.Contains ("assembly 'TestUcoFixtures'", error.Message); + Assert.Contains ("implementation assembly rather than a reference assembly", error.Message); + } + + [Fact] + public void Scanner_QualifiedLegacyOwner_DoesNotRequireUcoMetadata () + { + const string name = "Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.MyQualifiedLegacyWidget"; + var method = FindMarshalMethod (FindPeer (name), "n_DoSomething"); + Assert.False (method.IsUnmanagedCallersOnlyCallback); + Assert.Equal ("MyApp.MyHelper", method.DeclaringTypeName); + Assert.Equal ("TestFixtures", method.DeclaringAssemblyName); + Assert.Null (method.NativeCallbackReturnTypeName); + + var model = ModelBuilder.Build (UcoPeers, "TestUcoTypeMap.dll", "TestUcoTypeMap"); + var proxy = FindProxy (model, name); + var wrapper = Assert.Single (proxy.UcoMethods, u => u.CallbackMethodName == "n_DoSomething"); + Assert.Equal ("TestFixtures", wrapper.CallbackType.AssemblyName); + Assert.Null (Assert.Single (proxy.NativeRegistrations, r => r.JniMethodName == "n_DoSomething").DirectCallback); + } + + [Fact] + public void Scanner_DirectManagedDispatch_DoesNotRequireCallbackMetadata () + { + var peer = FindPeer ("Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.DirectWidget"); + var method = FindMarshalMethod (peer, "n_Direct"); + Assert.True (method.CallManagedMethodDirectly); + Assert.False (method.IsUnmanagedCallersOnlyCallback); + Assert.Null (method.NativeCallbackReturnTypeName); + } + + [Fact] + public void AbstractPropertyOverride_ReusesQualifiedLegacyCallback () + { + const string name = "Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.MyLegacyOverrideWidget"; + var method = FindMarshalMethod (FindPeer (name), "n_GetFlags"); + Assert.False (method.IsUnmanagedCallersOnlyCallback); + Assert.Equal ("Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.LegacyWidget", method.DeclaringTypeName); + Assert.Equal ("System.Int32", method.NativeCallbackReturnTypeName); + + var model = ModelBuilder.Build (UcoPeers, "TestUcoTypeMap.dll", "TestUcoTypeMap"); + var proxy = FindProxy (model, name); + var wrapper = Assert.Single (proxy.UcoMethods, u => u.CallbackMethodName == "n_GetFlags"); + Assert.False (wrapper.IsDirectUnmanagedCallersOnlyCallback); + Assert.Equal (method.DeclaringTypeName, wrapper.CallbackType.ManagedTypeName); + } + + [Theory] + [InlineData (false)] + [InlineData (true)] + public void Scanner_UnresolvedQualifiedCallback_FailsWithOwnerDetails (bool missingOwner) + { + var contents = File.ReadAllBytes (UcoFixtureAssemblyPath); + using (var original = new PEReader (new MemoryStream (contents))) { + var reader = original.GetMetadataReader (); + var name = missingOwner + ? reader.GetTypeDefinition (Assert.Single (reader.TypeDefinitions, + h => reader.GetString (reader.GetTypeDefinition (h).Name) == "CallbackHost")).Name + : reader.GetMethodDefinition (Assert.Single (reader.MethodDefinitions, + h => reader.GetString (reader.GetMethodDefinition (h).Name) == "n_Handle")).Name; + // Change only #Strings: the connector in the custom attribute's #Blob stays intact. + var offset = original.PEHeaders.MetadataStartOffset + reader.GetHeapMetadataOffset (HeapIndex.String) + MetadataTokens.GetHeapOffset (name); + Encoding.UTF8.GetBytes (missingOwner ? "MissingHostX" : "x_Handle").CopyTo (contents, offset); + } + + using var scanner = new JavaPeerScanner (); + using var pe = new PEReader (new MemoryStream (contents)); + using var fixtures = new PEReader (File.OpenRead (TestFixtureAssemblyPath)); + var error = Assert.Throws (() => scanner.Scan (new [] { MakeInput (pe), MakeInput (fixtures) })); + Assert.Contains ($"{CallbackHost}.n_Handle", error.Message); + Assert.Contains ("JNI signature '()V'", error.Message); + Assert.Contains ("assembly 'TestUcoFixtures'", error.Message); + } + + [Fact] + public void ModelBuilder_CompactCallbacks_AreRegisteredDirectly () + { + var model = ModelBuilder.Build (UcoPeers, "TestUcoTypeMap.dll", "TestUcoTypeMap"); + var proxy = FindProxy (model, CompactWidget); + + Assert.DoesNotContain (proxy.UcoMethods, u => u.CallbackMethodName == "n_Remove"); + Assert.DoesNotContain (proxy.UcoMethods, u => u.CallbackMethodName == "n_Remove_1"); + + // Two distinct Java overloads of the same name must stay distinct all the way through. + var names = proxy.NativeRegistrations + .Select (r => r.DirectCallback?.CallbackMethodName) + .Where (n => n is not null) + .ToList (); + Assert.Contains ("n_Remove", names); + Assert.Contains ("n_Remove_1", names); + } + + [Fact] + public void Emitter_CompactCallbacks_AreReferencedByName () + { + using var stream = new MemoryStream (); + new TypeMapAssemblyGenerator (new Version (11, 0, 0, 0)).Generate (UcoPeers, stream, "TestUcoTypeMap"); + stream.Position = 0; + + using var peReader = new PEReader (stream); + var reader = peReader.GetMetadataReader (); + + var memberRefNames = Enumerable.Range (1, reader.GetTableRowCount (TableIndex.MemberRef)) + .Select (MetadataTokens.MemberReferenceHandle) + .Select (h => reader.GetString (reader.GetMemberReference (h).Name)) + .ToList (); + + Assert.Contains ("n_Remove", memberRefNames); + Assert.Contains ("n_Remove_1", memberRefNames); + } + + static JavaPeerProxyData FindProxy (TypeMapAssemblyData model, string managedTypeName) + { + var shortName = managedTypeName.Substring (managedTypeName.LastIndexOf ('.') + 1); + return model.ProxyTypes.FirstOrDefault (p => p.TargetType?.ManagedTypeName == managedTypeName) + ?? model.ProxyTypes.FirstOrDefault (p => p.TypeName.Contains (shortName, StringComparison.Ordinal)) + ?? throw new InvalidOperationException ( + $"Proxy for '{managedTypeName}' not found; found: " + + string.Join (", ", model.ProxyTypes.Select (p => p.TypeName))); + } +} diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestUcoFixtures/TestUcoFixtures.csproj b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestUcoFixtures/TestUcoFixtures.csproj new file mode 100644 index 00000000000..942337b482a --- /dev/null +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestUcoFixtures/TestUcoFixtures.csproj @@ -0,0 +1,20 @@ + + + + $(DotNetStableTargetFramework) + latest + enable + true + true + true + Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures + + false + true + + + + + + + diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestUcoFixtures/UcoTypes.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestUcoFixtures/UcoTypes.cs new file mode 100644 index 00000000000..63985e41c5b --- /dev/null +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestUcoFixtures/UcoTypes.cs @@ -0,0 +1,233 @@ +using System; +using System.Runtime.InteropServices; +using Android.Runtime; +using Java.Interop; + +// Marks this assembly as using the experimental [UnmanagedCallersOnly] binding callback format. +// The trimmable typemap uses this marker to opt into resolving every n_* callback so it can +// discover which ones must be registered directly instead of through a generated wrapper. +[assembly: JavaPeerCallbackFormat (JavaPeerCallbackFormatAttribute.UnmanagedCallersOnlyCallbacks)] + +namespace Java.Interop +{ + [AttributeUsage (AttributeTargets.Assembly, AllowMultiple = false)] + public sealed class JavaPeerCallbackFormatAttribute : Attribute + { + public const int ConnectorDelegates = 1; + public const int UnmanagedCallersOnlyCallbacks = 2; + + public JavaPeerCallbackFormatAttribute (int version) => Version = version; + + public int Version { get; } + } +} + +namespace Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures +{ + /// + /// Models a binding generated with --lang-features=unmanaged-callers-only-callbacks: + /// the n_* callbacks are [UnmanagedCallersOnly] and there are no + /// Get*Handler () connector methods, so managed code can never call them. + /// + [Register ("com/example/uco/UcoWidget", DoNotGenerateAcw = true)] + public class UcoWidget : Java.Lang.Object + { + public UcoWidget (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + [Register ("onLayout", "(ZIIII)V", "GetOnLayout_ZIIIIHandler")] + public virtual void OnLayout (bool changed, int left, int top, int right, int bottom) { } + + [UnmanagedCallersOnly] + static void n_OnLayout_ZIIII (IntPtr jnienv, IntPtr native__this, sbyte native_changed, int left, int top, int right, int bottom) { } + + [Register ("getCount", "()I", "GetGetCountHandler")] + public virtual int Count => 0; + + [UnmanagedCallersOnly] + static int n_GetCount (IntPtr jnienv, IntPtr native__this) => 0; + } + + /// + /// Models a binding in the same marked assembly whose callback is *not* eligible for + /// [UnmanagedCallersOnly] (here: a generic declaring type). It keeps the legacy + /// connector shape, so the typemap must still emit a forwarding wrapper for it. + /// + [Register ("com/example/uco/LegacyWidget", DoNotGenerateAcw = true)] + public class LegacyWidget : Java.Lang.Object + { + public LegacyWidget (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + [Register ("getFlags", "()I", "GetGetFlagsHandler")] + public virtual int Flags => 0; + + static int n_GetFlags (IntPtr jnienv, IntPtr native__this) => 0; + } + + /// + /// A user (ACW) subclass overriding a binding method whose callback is + /// [UnmanagedCallersOnly]. RegisterNatives must ldftn the base + /// n_OnLayout_ZIIII directly — a generated forwarder would be an illegal managed call. + /// + [Register ("com/example/uco/MyWidget")] + public class MyWidget : UcoWidget + { + public MyWidget (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + public override void OnLayout (bool changed, int left, int top, int right, int bottom) { } + + public override int Count => 1; + } + + /// + /// Models the compact callback names a marked assembly emits: the callback is named after the + /// managed member instead of its Java signature, and duplicate base names are numbered. With + /// no connector method left to name, the connector stores the callback name itself. + /// + [Register ("com/example/uco/CompactWidget", DoNotGenerateAcw = true)] + public class CompactWidget : Java.Lang.Object + { + public CompactWidget (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + [Register ("remove", "(I)V", "n_Remove")] + public virtual void Remove (int index) { } + + [UnmanagedCallersOnly] + static void n_Remove (IntPtr jnienv, IntPtr native__this, int index) { } + + [Register ("remove", "(J)V", "n_Remove_1")] + public virtual void Remove (long id) { } + + [UnmanagedCallersOnly] + static void n_Remove_1 (IntPtr jnienv, IntPtr native__this, long id) { } + } + + /// + /// A compact connector which also carries the owner qualifier an interface invoker or default + /// interface method needs. Both halves have to survive: the qualifier still resolves the + /// declaring type, and the callback name is read verbatim from the segment before it. + /// + [Register ("com/example/uco/QualifiedWidget", DoNotGenerateAcw = true)] + public class QualifiedWidget : Java.Lang.Object + { + public QualifiedWidget (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + [Register ("handle", "()V", "n_Handle:Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.CallbackHost, TestUcoFixtures")] + public virtual void Handle () { } + + [Register ("handleTypeOnly", "()V", "n_HandleTypeOnly:Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.CallbackHost")] + public virtual void HandleTypeOnly () { } + + [Register ("getCount", "()I", "n_Count:Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.CallbackHost, TestUcoFixtures")] + public virtual int Count => 0; + + public virtual bool Enabled { + [Register ("isEnabled", "()Z", "n_IsEnabled:Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.CallbackHost, TestUcoFixtures")] + get => false; + [Register ("setEnabled", "(Z)V", "n_SetEnabled:Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.CallbackHost, TestUcoFixtures")] + set { } + } + } + + /// + /// Stands in for the invoker type an owner-qualified connector points at. + /// + [Register ("com/example/uco/CallbackHost", DoNotGenerateAcw = true)] + public class CallbackHost : Java.Lang.Object + { + public CallbackHost (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + [UnmanagedCallersOnly] + internal static void n_Handle (IntPtr jnienv, IntPtr native__this) { } + + [UnmanagedCallersOnly] + static void n_HandleTypeOnly (IntPtr jnienv, IntPtr native__this) { } + + [UnmanagedCallersOnly] + static int n_Count (IntPtr jnienv, IntPtr native__this) => 0; + + [UnmanagedCallersOnly] + static sbyte n_IsEnabled (IntPtr jnienv, IntPtr native__this) => 0; + + [UnmanagedCallersOnly] + static void n_SetEnabled (IntPtr jnienv, IntPtr native__this, sbyte enabled) { } + } + + /// + /// ACW subclasses of the compact-format bindings. + /// + [Register ("com/example/uco/MyCompactWidget")] + public class MyCompactWidget : CompactWidget + { + public MyCompactWidget (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + public override void Remove (int index) { } + + public override void Remove (long id) { } + } + + [Register ("com/example/uco/MyQualifiedWidget")] + public class MyQualifiedWidget : QualifiedWidget + { + public MyQualifiedWidget (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + public override void Handle () { } + + public override void HandleTypeOnly () { } + + public override int Count => 1; + + public override bool Enabled { get; set; } + } + + /// + /// A user (ACW) subclass overriding a legacy connector-style binding method in the same + /// marked assembly. It must keep the generated forwarding wrapper. + /// + [Register ("com/example/uco/MyLegacyWidget")] + public class MyLegacyWidget : LegacyWidget + { + public MyLegacyWidget (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + public override int Flags => 2; + } + + [Register ("com/example/uco/LegacyOverrideWidget", DoNotGenerateAcw = true)] + public abstract class LegacyOverrideWidget : LegacyWidget + { + public LegacyOverrideWidget (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + public abstract override int Flags { + [Register ("getFlags", "()I", "GetGetFlagsHandler:Microsoft.Android.Sdk.TrimmableTypeMap.Tests.TestUcoFixtures.LegacyWidget, TestUcoFixtures")] + get; + } + } + + [Register ("com/example/uco/MyLegacyOverrideWidget")] + public class MyLegacyOverrideWidget : LegacyOverrideWidget + { + public MyLegacyOverrideWidget (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } + + public override int Flags => 3; + } + + [Register ("com/example/uco/QualifiedLegacyWidget", DoNotGenerateAcw = true)] + public class QualifiedLegacyWidget : MyApp.MyHelper + { + // MyHelper models legacy reference metadata without its private callback. + [Register ("doSomething", "()V", "GetDoSomethingHandler:MyApp.MyHelper, TestFixtures")] + public override void DoSomething () { } + } + + [Register ("com/example/uco/MyQualifiedLegacyWidget")] + public class MyQualifiedLegacyWidget : QualifiedLegacyWidget + { + public override void DoSomething () { } + } + + [Register ("com/example/uco/DirectWidget")] + public class DirectWidget : Java.Lang.Object + { + [Register ("direct", "()I", "")] + public int Direct () => 42; + } +}