From 0a6f9bd8466c490dedfc808821b81bbbe8643580 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 22 Sep 2021 10:57:33 -0500 Subject: [PATCH] [One .NET] Prefer /manifest/@package over $(ApplicationId) (#6304) Fixes: https://github.com/xamarin/xamarin-android/issues/6302 If you try to use both the `$(ApplicationId)` MSBuild property and the `/manifest/@package` attribute within `AndroidManifest.xml` at the same time, you hit errors during deployment: Xamarin.Android.Common.Debugging.targets(611,5): error XA0132: The package was not installed. Please check you do not have it installed under any other user. If the package does show up on the device, try manually uninstalling it then try again. You should be able to uninstall the app via the Settings app on the device. From the spec, the `AndroidManifest.xml` value is *supposed* to be preferred. I found that the `` MSBuild task is accidentally preferring the `$(ApplicationId)` MSBuild property. I reordered the logic and only use the property when no value is found in the `AndroidManifest.xml`. I could reproduce the issue in a test, which now passes. --- .../Tasks/GetAndroidPackageName.cs | 16 ++++++------- .../Tests/InstallAndRunTests.cs | 24 +++++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GetAndroidPackageName.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GetAndroidPackageName.cs index 5f6ab4b65c9..915db6f458b 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GetAndroidPackageName.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GetAndroidPackageName.cs @@ -49,23 +49,23 @@ public class GetAndroidPackageName : AndroidTask public override bool RunTask () { - if (!string.IsNullOrEmpty (PackageName)) { - PackageName = AndroidAppManifest.CanonicalizePackageName (PackageName); - } else if (!string.IsNullOrEmpty (ManifestFile) && File.Exists (ManifestFile)) { + if (!string.IsNullOrEmpty (ManifestFile) && File.Exists (ManifestFile)) { using var stream = File.OpenRead (ManifestFile); using var reader = XmlReader.Create (stream); if (reader.MoveToContent () == XmlNodeType.Element) { var package = reader.GetAttribute ("package"); if (!string.IsNullOrEmpty (package)) { - package = ManifestDocument.ReplacePlaceholders (ManifestPlaceholders, package); - PackageName = AndroidAppManifest.CanonicalizePackageName (package); + PackageName = ManifestDocument.ReplacePlaceholders (ManifestPlaceholders, package); } } } - // If we don't have a manifest, default to using the assembly name - // If the assembly doesn't have a period in it, duplicate it so it does - if (string.IsNullOrEmpty (PackageName)) { + if (!string.IsNullOrEmpty (PackageName)) { + // PackageName may be passed in via $(ApplicationId) and missing from AndroidManifest.xml + PackageName = AndroidAppManifest.CanonicalizePackageName (PackageName); + } else { + // If we don't have a manifest, default to using the assembly name + // If the assembly doesn't have a period in it, duplicate it so it does PackageName = AndroidAppManifest.CanonicalizePackageName (AssemblyName); } diff --git a/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs b/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs index 90de28622fb..8052f1e7c60 100644 --- a/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs +++ b/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs @@ -626,5 +626,29 @@ public void RunWithInterpreterEnabled ([Values (false, true)] bool isRelease) Assert.IsTrue (didStart, "Activity should have started."); } + [Test] + public void SingleProject_ApplicationId () + { + AssertHasDevices (); + + proj = new XamarinAndroidApplicationProject (); + proj.SetProperty ("ApplicationId", "com.i.should.get.overridden.by.the.manifest"); + + var abis = new string [] { "armeabi-v7a", "arm64-v8a", "x86", "x86_64" }; + proj.SetAndroidSupportedAbis (abis); + builder = CreateApkBuilder (); + Assert.IsTrue (builder.Install (proj), "Install should have succeeded."); + + if (Builder.UseDotNet) + Assert.True (builder.RunTarget (proj, "Run"), "Project should have run."); + else if (CommercialBuildAvailable) + Assert.True (builder.RunTarget (proj, "_Run"), "Project should have run."); + else + AdbStartActivity ($"{proj.PackageName}/{proj.JavaPackageName}.MainActivity"); + + var didStart = WaitForActivityToStart (proj.PackageName, "MainActivity", + Path.Combine (Root, builder.ProjectDirectory, "startup-logcat.log")); + Assert.IsTrue (didStart, "Activity should have started."); + } } }