Uh oh!
There was an error while loading. Please reload this page.
[typemap] Honor explicit interface invokers - #12565
Conversation
Track Java.Interop InvokerType metadata and its owning assembly through scanner, model, associations, and emitted proxy references. Add constructor activation regression coverage for interface, inherited interface, abstract, identity, and cross-assembly invoker shapes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remove speculative cross-assembly invoker support and retain same-assembly Xamarin.Android and Java.Interop constructor activation coverage. Prefer the explicitly requested interface or abstract proxy before hierarchy fallbacks so trimmable lookup matches reflection behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Parse serialized invoker type names and accept only local/default assembly ownership. Ignore unsupported cross-assembly metadata and resolve activation constructors solely from the target assembly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
Review tier: Lite
Findings: 1
New issues introduced by this change (1)
| Severity | Finding |
|---|---|
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestFixtures/InvokerFixtures.cs — 💡 suggestion: The explicit invoker/proxy type should implement the target interface; otherwise this… |
What changed in this PR
This PR closes a TrimmableTypeMap feature-parity gap by honoring explicit invoker metadata (including same-assembly JniTypeSignatureAttribute.InvokerType) and adjusting runtime proxy selection so interface/abstract targets prefer the explicitly validated proxy while concrete targets keep the existing “most-derived” behavior.
Changes:
- Update runtime proxy resolution to prefer explicit proxies for interface/abstract targets while preserving hierarchy-first behavior for concrete targets.
- Extend the trimmable typemap scanner to consume same-assembly explicit invoker metadata and resolve invoker activation constructor style from the declaring assembly (ignoring unsupported cross-assembly invokers).
- Add new device/runtime and scanner coverage for invoker activation, inherited interfaces, abstract targets, and peer identity.
| File | Description |
|---|---|
| tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj | Adds the new invoker activation test file to the device test project. |
| tests/Mono.Android-Tests/Mono.Android-Tests/Java.Interop/InvokerActivationTests.cs | New device tests validating invoker selection, single activation, and identity preservation. |
| tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestFixtures/StubAttributes.cs | Extends the stub JniTypeSignatureAttribute to support interfaces and InvokerType. |
| tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestFixtures/InvokerFixtures.cs | New fixtures for explicit-invoker scanning scenarios (including cross-assembly ignore case). |
| tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Scanner/JavaPeerScannerTests.cs | Adds scanner tests covering explicit invokers and cross-assembly ignore behavior. |
| src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs | Adjusts runtime proxy selection ordering for interface/abstract targets. |
| src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerScanner.cs | Implements same-assembly invoker resolution + assembly-scoped activation ctor style lookup. |
| src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/AssemblyIndex.cs | Captures InvokerType from JniTypeSignature into RegisterInfo for scanner consumption. |
Suppressed comments (1)
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestFixtures/InvokerFixtures.cs:23
- 💡 suggestion: Same as above: the proxy type used as an explicit invoker should implement the interface it is meant to represent, so the fixture reflects a valid runtime invoker shape.
public sealed class InheritedJavaInteropListProxy : Java.Lang.Object
Uh oh!
There was an error while loading. Please reload this page.
Ensure explicit invoker fixtures implement the interfaces they represent so their scanner metadata reflects valid runtime invoker shapes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival
commented
Sep 2, 2026
/review |
✅ Android PR Reviewer completed successfully! Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "azcliprod.blob.core.windows.net"See Network Configuration for more information.
|
There was a problem hiding this comment.
⚠️ Needs Changes
Found 1 error: the new interface/abstract target-first lookup can lose Java peer identity when callers request the same object first through an interface and later through its concrete class. The inline comment includes the failure sequence and requested regression coverage.
The scanner-side same-assembly validation and explicit-invoker fixture coverage are well targeted. CI is currently red in dotnet-android (Package Tests macOS > Tests > APKs 2); the remaining checks passed, but the Azure failure details were unavailable from this run because the Azure CLI requires authentication.
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
azcliprod.blob.core.windows.net
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "azcliprod.blob.core.windows.net"See Network Configuration for more information.
Generated by Android PR Reviewer for #12565 · gpt56 · 292.7 AIC · ⌖ 8.93 AIC · ⊞ 25.7K
Comment /review to run again
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Prefer compatible hierarchy proxies before explicit target invokers so subsequent concrete lookups reuse the registered Java peer. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Mark the Xamarin-style interface fixture as an existing Java peer so the legacy typemap does not generate a duplicate java.util.List type. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.

Summary
JniTypeSignatureAttribute.InvokerTypemetadataTDD matrix
Before the fix, the unchanged explicit-invoker test passed with llvm-ir but selected the wrong proxy under both trimmable runtimes. After the fix:
Microsoft.Android.Sdk.TrimmableTypeMap.Tests: 774/774.Part of #12561