Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] fix .aab deploying to different ABIs (#…
Browse files Browse the repository at this point in the history
…6658)

Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1447873

The following breaks in both Xamarin.Android & .NET 6:

1. Deploy a build with `AndroidPackageFormat=aab` to a device
2. Switch the dropdown in the IDE, deploy to an emulator

Fails with:

    HelloWorld.csproj  → Install
    Target _DeployAppBundle
        Task InstallApkSet
        Error [BT Missing APKs for [ABI] dimensions in the module 'base' for the provided device.

I could reproduce this in a test with a blank `$(AdbTarget)`, then set
`$(AdbTarget)` to the connected device. This should simulate what
happens in the IDE when you switch devices.

What happens is this `Condition`:

    Condition="!Exists('$(_ApkSetIntermediate)')"

Just skips if the file exists!

To solve the issue:

1. Move the `<BuildApkSet/>` task to a new `_BuildApkSet` target.

2. Add `Inputs` of `build.props`, `adb.props`, and
   `$(_AppBundleIntermediate)`.

3. Add `Outputs` for `$(_ApkSetIntermediate)`.

4. Add `<Touch Files="$(_ApkSetIntermediate)" />`, just in case!
  • Loading branch information
jonathanpeppers authored Jan 24, 2022
1 parent 98d243e commit 5762b45
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2525,8 +2525,9 @@ because xbuild doesn't support framework reference assemblies.
/>
</Target>

<Target Name="_DeployAppBundle"
Condition=" '$(AndroidPackageFormat)' == 'aab' ">
<Target Name="_BuildApkSet"
Inputs="$(_AndroidBuildPropertiesCache);$(_AdbPropertiesCache);$(_AppBundleIntermediate)"
Outputs="$(_ApkSetIntermediate)">
<BuildApkSet
ToolPath="$(JavaToolPath)"
JavaMaximumHeapSize="$(JavaMaximumHeapSize)"
Expand All @@ -2542,8 +2543,13 @@ because xbuild doesn't support framework reference assemblies.
KeyPass="$(_ApkKeyPass)"
StorePass="$(_ApkStorePass)"
ExtraArgs="$(AndroidBundleToolExtraArgs)"
Condition="!Exists('$(_ApkSetIntermediate)')"
/>
<Touch Files="$(_ApkSetIntermediate)" />
</Target>

<Target Name="_DeployAppBundle"
Condition=" '$(AndroidPackageFormat)' == 'aab' "
DependsOnTargets="_BuildApkSet">
<PropertyGroup>
<_UninstallCommand>&quot;$(AdbToolPath)adb&quot; $(AdbTarget) uninstall -k &quot;$(_AndroidPackage)&quot;</_UninstallCommand>
</PropertyGroup>
Expand Down
28 changes: 28 additions & 0 deletions tests/MSBuildDeviceIntegration/Tests/InstallTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -567,5 +567,33 @@ public void IncrementalFastDeployment ()
$"Fourth unchanged install: '{fourthInstalTime}' should be faster than clean install: '{firstInstallTime}' and incremental install: '{thirdInstallTime}'.");
}
}

[Test]
public void AdbTargetChangesAppBundle ()
{
AssertHasDevices ();

var proj = new XamarinAndroidApplicationProject {
IsRelease = true
};
proj.SetProperty ("AndroidPackageFormat", "aab");
proj.SetAndroidSupportedAbis ("armeabi-v7a", "arm64-v8a", "x86", "x86_64");

using var b = CreateApkBuilder ();
Assert.IsTrue (b.Install (proj), "first build should have succeeded.");

var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
var apkset = Path.Combine (intermediate, "android", "bin", $"{proj.PackageName}.apks");
FileAssert.Exists (apkset);
var before = File.GetLastWriteTimeUtc (apkset);

// Change $(AdbTarget) to not be blank
var serial = GetAttachedDeviceSerial ();
Assert.IsTrue (b.Install (proj, parameters: new [] { $"AdbTarget=\"-e {serial}\"" }), "second build should have succeeded.");

FileAssert.Exists (apkset);
var after = File.GetLastWriteTimeUtc (apkset);
Assert.AreNotEqual (before, after, $"{apkset} should change!");
}
}
}

0 comments on commit 5762b45

Please sign in to comment.