[Microsoft.Android.Sdk.ILLink] fix crash when TZ changes (#7956)
Fixes: https://github.com/xamarin/xamarin-android/issues/7953 Context:11f0e1bf64
When a timezone changes in a `Release` config app, it can crash with: [monodroid] Unable to find Android.Runtime.AndroidEnvironment.NotifyTimeZoneChanged()! In commit11f0e1b
, we removed the line: <?xml version="1.0" encoding="utf-8" ?> <linker> <assembly fullname="Mono.Android"> -- <type fullname="Android.Runtime.AndroidEnvironment" /> Unfortunately, `AndroidEnvironment.NotifyTimeZoneChanged()` is called from non-managed code, via: * The `NotifyTimeZoneChanges` broadcast receiver (in `src/java-runtime/java/mono/android/app/NotifyTimeZoneChanges.java`) which calls- * The `Rutime.notifyTimeZoneChanged()` `native` method (in `src/java-runtime/java/mono/android/Runtime.java`), implemented in- * `Java_mono_android_Runtime_notifyTimeZoneChanged()` (in`src/monodroid/jni/timezones.cc`). The managed linker cannot "see" any of these references, so we need to *always* preserve this method, as it is always callable. Update `src/Microsoft.Android.Sdk.ILLink/PreserveLists/Mono.Android.xml` so that `Android.Runtime.AndroidEnvironment.NotifyTimeZoneChanged()` is always preserved. Added a test for this scenario. TODO: we may want to audit all `mono_class_get_method_from_name()` calls and add more tests cases. I also cleaned up the tests a bit with a `getResource()` local function.
This commit is contained in:
Родитель
82161e07a2
Коммит
59e1e466bc
|
@ -2,6 +2,9 @@
|
|||
<linker>
|
||||
<assembly fullname="Mono.Android">
|
||||
<type fullname="Android.Runtime.AnnotationAttribute" />
|
||||
<type fullname="Android.Runtime.AndroidEnvironment">
|
||||
<method name="NotifyTimeZoneChanged" />
|
||||
</type>
|
||||
<type fullname="Android.Runtime.IJavaObject" />
|
||||
<type fullname="Android.Runtime.InputStreamAdapter" preserve="methods" />
|
||||
<type fullname="Android.Runtime.InputStreamInvoker" preserve="methods" />
|
||||
|
|
|
@ -115,6 +115,9 @@ namespace UnnamedProject
|
|||
// [Test] Post
|
||||
Android.Util.Log.Info(TAG, HttpClientTest.Post ());
|
||||
|
||||
// [Test] MethodsArePreserved
|
||||
Android.Util.Log.Info (TAG, PreserveTest.MethodsArePreserved ());
|
||||
|
||||
// [Test] TextChanged
|
||||
Android.Util.Log.Info (TAG, MaterialTextChanged.TextChanged (this));
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
public class PreserveTest
|
||||
{
|
||||
// [Test]
|
||||
public static string MethodsArePreserved ()
|
||||
{
|
||||
try {
|
||||
// See src/monodroid/jni/timezones.cc for usage
|
||||
var androidEnvironment = Type.GetType ("Android.Runtime.AndroidEnvironment, Mono.Android", throwOnError: true);
|
||||
var notifyTimeZoneChanged = androidEnvironment.GetMethod ("NotifyTimeZoneChanged", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
if (notifyTimeZoneChanged == null) {
|
||||
return $"[FAIL] {nameof (PreserveTest)}.{nameof (MethodsArePreserved)} FAILED: {nameof (notifyTimeZoneChanged)} is null)";
|
||||
}
|
||||
notifyTimeZoneChanged.Invoke (null, null);
|
||||
return $"[PASS] {nameof (PreserveTest)}.{nameof (MethodsArePreserved)}";
|
||||
} catch (Exception ex) {
|
||||
return $"[FAIL] {nameof (PreserveTest)}.{nameof (MethodsArePreserved)} FAILED: {ex}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -400,22 +400,16 @@ namespace Library1 {
|
|||
},
|
||||
Sources = {
|
||||
new BuildItem.Source ("Bug21578.cs") {
|
||||
TextContent = () => {
|
||||
using (var sr = new StreamReader (typeof (InstallAndRunTests).Assembly.GetManifestResourceStream ("Xamarin.Android.Build.Tests.Resources.LinkDescTest.Bug21578.cs")))
|
||||
return sr.ReadToEnd ();
|
||||
},
|
||||
TextContent = () => getResource("Bug21578")
|
||||
},
|
||||
new BuildItem.Source ("Bug35195.cs") {
|
||||
TextContent = () => {
|
||||
using (var sr = new StreamReader (typeof (InstallAndRunTests).Assembly.GetManifestResourceStream ("Xamarin.Android.Build.Tests.Resources.LinkDescTest.Bug35195.cs")))
|
||||
return sr.ReadToEnd ();
|
||||
},
|
||||
TextContent = () => getResource("Bug35195")
|
||||
},
|
||||
new BuildItem.Source ("HttpClientTest.cs") {
|
||||
TextContent = () => {
|
||||
using (var sr = new StreamReader (typeof (InstallAndRunTests).Assembly.GetManifestResourceStream ("Xamarin.Android.Build.Tests.Resources.LinkDescTest.HttpClientTest.cs")))
|
||||
return sr.ReadToEnd ();
|
||||
},
|
||||
TextContent = () => getResource("HttpClientTest")
|
||||
},
|
||||
new BuildItem.Source ("PreserveTest.cs") {
|
||||
TextContent = () => getResource("PreserveTest")
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -424,10 +418,7 @@ namespace Library1 {
|
|||
// DataContractSerializer is not trimming safe
|
||||
// https://github.com/dotnet/runtime/issues/45559
|
||||
lib2.Sources.Add (new BuildItem.Source ("Bug36250.cs") {
|
||||
TextContent = () => {
|
||||
using (var sr = new StreamReader (typeof (InstallAndRunTests).Assembly.GetManifestResourceStream ("Xamarin.Android.Build.Tests.Resources.LinkDescTest.Bug36250.cs")))
|
||||
return sr.ReadToEnd ();
|
||||
},
|
||||
TextContent = () => getResource ("Bug36250")
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -450,10 +441,7 @@ namespace Library1 {
|
|||
},
|
||||
Sources = {
|
||||
new BuildItem.Source ("MaterialTextChanged.cs") {
|
||||
TextContent = () => {
|
||||
using (var sr = new StreamReader (typeof (InstallAndRunTests).Assembly.GetManifestResourceStream ("Xamarin.Android.Build.Tests.Resources.LinkDescTest.MaterialTextChanged.cs")))
|
||||
return sr.ReadToEnd ();
|
||||
},
|
||||
TextContent = () => getResource ("MaterialTextChanged")
|
||||
},
|
||||
},
|
||||
OtherBuildItems = {
|
||||
|
@ -512,6 +500,12 @@ namespace Library1 {
|
|||
StringAssert.Contains ("[LINKALLPASS]", logcatOutput);
|
||||
StringAssert.DoesNotContain ("[LINKALLFAIL]", logcatOutput);
|
||||
}
|
||||
|
||||
string getResource (string name)
|
||||
{
|
||||
using (var sr = new StreamReader (typeof (InstallAndRunTests).Assembly.GetManifestResourceStream ($"Xamarin.Android.Build.Tests.Resources.LinkDescTest.{name}.cs")))
|
||||
return sr.ReadToEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
Загрузка…
Ссылка в новой задаче