Commit 2a7183a
authored
[Java.Interop] CreatePeer() must satisfy targetType (#1308)
Context: dotnet/android#9747
Context: https://discord.com/channels/732297728826277939/732297837953679412/1339638847864176640
Context: https://discord.com/channels/732297728826277939/732297837953679412/1340011105510101063
While trying to get a MAUI sample running atop NativeAOT, we're
observing the following crash:
E AndroidRuntime: net.dot.jni.internal.JavaProxyThrowable: System.InvalidCastException: Arg_InvalidCastException
E AndroidRuntime: at Java.Lang.Object._GetObject[T](IntPtr, JniHandleOwnership) + 0x64
E AndroidRuntime: at Microsoft.Maui.WindowOverlay.Initialize() + 0x168
Further investigation shows that the crash is from accessing the
`Activity.WindowManager` property:
namespace Android.App;
partial class Activity {
public virtual unsafe Android.Views.IWindowManager? WindowManager {
// Metadata.xml XPath method reference: path="/api/package[@name='android.app']/class[@name='Activity']/method[@name='getWindowManager' and count(parameter)=0]"
[Register ("getWindowManager", "()Landroid/view/WindowManager;", "GetGetWindowManagerHandler")]
get {
const string __id = "getWindowManager.()Landroid/view/WindowManager;";
try {
var __rm = _members.InstanceMethods.InvokeVirtualObjectMethod (__id, this, null);
return global::Java.Lang.Object.GetObject<Android.Views.IWindowManager> (__rm.Handle, JniHandleOwnership.TransferLocalRef);
} finally {
}
}
}
}
`Object.GetObject<T>()` is now a wrapper around
`JniRuntime.JniValueManager.GetPeer()`, so the problem, rephrased,
is that in this:
var peer = JniEnvironment.Runtime.ValueManager.GetPeer (
ref h,
JniObjectReferenceOptions.CopyAndDispose,
targetType:typeof (IWindowManager));
var wm = (IWindowManager) peer;
`peer` is a value which *does not implement* `IWindowManager`.
It was, in fact, returning a `Java.Lang.Object` instance (!).
Consequently, the cast to `IWindowManager` throws.
The cause of the bug is that `JniRuntime.JniValueManager.CreatePeer()`
was not checking that the `Type` returned form
`Runtime.TypeManager.GetType(JniTypeSignature)` was compatible with
`targetType`; instead, it returned the first type in the inheritance
chain that had an activation constructor. This was `Java.Lang.Object`.
Later, when `_GetObject<T>()` tried to cast the return value of
`JniRuntime.JniValueManager.GetPeer()` to `IWindowManager`, it failed.
Fix this by updating `CreatePeer()` to check that the `Type` from
`JniRuntime.JniTypeManager.GetType(JniTypeSignature)` is assignable
to `targetType`. This ensures that we *don't* return a
`Java.Lang.Object` instance, allowing the cast to succeed.
Update `JniRuntimeJniValueManagerContract` to test these new semantics.1 parent d62008d commit 2a7183a
File tree
5 files changed
+76
-3
lines changed- src/Java.Interop/Java.Interop
- tests/Java.Interop-Tests
- Java.Interop
- java/net/dot/jni/test
5 files changed
+76
-3
lines changedLines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
348 | 348 | | |
349 | 349 | | |
350 | 350 | | |
351 | | - | |
| 351 | + | |
352 | 352 | | |
353 | 353 | | |
354 | 354 | | |
| |||
362 | 362 | | |
363 | 363 | | |
364 | 364 | | |
365 | | - | |
| 365 | + | |
366 | 366 | | |
367 | 367 | | |
368 | 368 | | |
| |||
381 | 381 | | |
382 | 382 | | |
383 | 383 | | |
384 | | - | |
| 384 | + | |
385 | 385 | | |
386 | 386 | | |
387 | 387 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
40 | 41 | | |
41 | 42 | | |
42 | 43 | | |
| |||
Lines changed: 58 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
133 | 133 | | |
134 | 134 | | |
135 | 135 | | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
136 | 160 | | |
137 | 161 | | |
138 | 162 | | |
| |||
294 | 318 | | |
295 | 319 | | |
296 | 320 | | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
297 | 355 | | |
Lines changed: 13 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
0 commit comments