From bd45b6897aae1db854343764a8dfbd30652a59fe Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Tue, 15 Jan 2019 13:38:19 +0000 Subject: [PATCH] [Xamarin.Android.Build.Tasks] Add `directBootAware` if needed. Fixes #2081 If a user needs to use the `directBootAware` attribute on an `application`, `activity` or `service` we also need to include it on the `MonoRuntimeProvider` so that native libraries can be resolved correctly. Not doing so results in the following java.lang.UnsatisfiedLinkError: No implementation found for void mono.android.Runtime.register This commit looks to see if any elements in the manifest contain `directBootAware`. If there are , then we also include it in the `provider`. --- .../ManifestTest.cs | 2 ++ .../Utilities/ManifestDocument.cs | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs index 272584272a5..5b3618ea99e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs @@ -266,6 +266,8 @@ public void DirectBootAwareAttribute () Assert.IsNotNull (le, "no activity element found"); Assert.IsTrue (doc.XPathSelectElements ("//activity[@android:directBootAware='true']", nsResolver).Any (), "'activity' element is not generated as expected."); + Assert.IsTrue (doc.XPathSelectElements ("//provider[@android:name='mono.MonoRuntimeProvider' and @android:directBootAware='true']", nsResolver).Any (), + "'provider' element is not generated as expected."); } } diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs b/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs index 8524dccb6ed..b9405e57ff7 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs @@ -630,10 +630,12 @@ IList AddMonoRuntimeProviders (XElement app) XElement CreateMonoRuntimeProvider (string name, string processName, int initOrder) { + var directBootAware = DirectBootAware (); return new XElement ("provider", new XAttribute (androidNs + "name", name), new XAttribute (androidNs + "exported", "false"), new XAttribute (androidNs + "initOrder", initOrder), + directBootAware ? new XAttribute (androidNs + "directBootAware", "true") : null, processName == null ? null : new XAttribute (androidNs + "process", processName), new XAttribute (androidNs + "authorities", PackageName + "." + name + ".__mono_init__")); } @@ -658,6 +660,22 @@ public bool ExtractNativeLibraries () return true; } + /// + /// Returns true if an element has the @android:directBootAware attribute and its 'true' + /// + public bool DirectBootAware () + { + var processAttrName = androidNs.GetName ("directBootAware"); + foreach (XElement el in app.Elements ()) { + var proc = el.Attribute (processAttrName); + if (proc != null && bool.TryParse (proc.Value, out bool value) && value) + return true; + } + + // If android:directBootAware is omitted, returns false. + return false; + } + XElement ActivityFromTypeDefinition (TypeDefinition type, string name, int targetSdkVersion) { if (name.StartsWith ("_"))