Skip to content

Commit 7acc857

Browse files
[Xamarin.Android.Build.Tasks] support for $(AdbTarget) (#4166)
Fixes: https://developercommunity.visualstudio.com/content/problem/854863/unable-to-deploy-to-physical-device-when-emulator.html Fixes: http://work.azdo.io/1056857 We got some reports that our App Bundle MSBuild tasks fail when you have multiple devices/emulators connected to adb. We were not using the `$(AdbTarget)` MSBuild property at all, which is actually a slightly different parameter for `bundletool`: --device-id: (Optional) Device serial name. If absent, this uses the ANDROID_SERIAL environment variable. Either this flag or the environment variable is required when more than one device or emulator is connected. Used only if connected-device flag is set. It appears that only a value such as `-s emulator-5554` would work for the `--device-id` switch. To make things compatible, I think we should just look for a space character and use the text as-is after it. I added some tests that validate the generated command-line for `bundletool`-related MSBuild tasks.
1 parent ae70967 commit 7acc857

File tree

8 files changed

+97
-27
lines changed

8 files changed

+97
-27
lines changed

src/Xamarin.Android.Build.Tasks/Tasks/BuildApkSet.cs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Xamarin.Android.Tasks
1111
///
1212
/// Usage: bundletool build-apks --bundle=foo.aab --output=foo.apks
1313
/// </summary>
14-
public class BuildApkSet : BundleTool
14+
public class BuildApkSet : BundleToolAdbTask
1515
{
1616
public override string TaskPrefix => "BAS";
1717

@@ -21,16 +21,6 @@ public class BuildApkSet : BundleTool
2121
[Required]
2222
public string Output { get; set; }
2323

24-
/// <summary>
25-
/// This is used to detect the attached device and generate an APK set specifically for it
26-
/// </summary>
27-
[Required]
28-
public string AdbToolPath { get; set; }
29-
30-
public string AdbToolExe { get; set; }
31-
32-
public string AdbToolName => OS.IsWindows ? "adb.exe" : "adb";
33-
3424
[Required]
3525
public string Aapt2ToolPath { get; set; }
3626

@@ -72,17 +62,16 @@ void AddStorePass (CommandLineBuilder cmd, string cmdLineSwitch, string value)
7262
}
7363
}
7464

75-
protected override CommandLineBuilder GetCommandLineBuilder ()
65+
internal override CommandLineBuilder GetCommandLineBuilder ()
7666
{
77-
var adb = string.IsNullOrEmpty (AdbToolExe) ? AdbToolName : AdbToolExe;
7867
var aapt2 = string.IsNullOrEmpty (Aapt2ToolExe) ? Aapt2ToolName : Aapt2ToolExe;
7968
var cmd = base.GetCommandLineBuilder ();
8069
cmd.AppendSwitch ("build-apks");
8170
cmd.AppendSwitch ("--connected-device");
8271
cmd.AppendSwitchIfNotNull ("--bundle ", AppBundle);
8372
cmd.AppendSwitchIfNotNull ("--output ", Output);
8473
cmd.AppendSwitchIfNotNull ("--mode ", "default");
85-
cmd.AppendSwitchIfNotNull ("--adb ", Path.Combine (AdbToolPath, adb));
74+
AppendAdbOptions (cmd);
8675
cmd.AppendSwitchIfNotNull ("--aapt2 ", Path.Combine (Aapt2ToolPath, aapt2));
8776
cmd.AppendSwitchIfNotNull ("--ks ", KeyStore);
8877
cmd.AppendSwitchIfNotNull ("--ks-key-alias ", KeyAlias);

src/Xamarin.Android.Build.Tasks/Tasks/BuildAppBundle.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public override bool RunTask ()
118118
return !Log.HasLoggedErrors;
119119
}
120120

121-
protected override CommandLineBuilder GetCommandLineBuilder ()
121+
internal override CommandLineBuilder GetCommandLineBuilder ()
122122
{
123123
var cmd = base.GetCommandLineBuilder ();
124124
cmd.AppendSwitch ("build-bundle");

src/Xamarin.Android.Build.Tasks/Tasks/BundleTool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ protected override string GenerateCommandLineCommands ()
1414
return GetCommandLineBuilder ().ToString ();
1515
}
1616

17-
protected virtual CommandLineBuilder GetCommandLineBuilder ()
17+
internal virtual CommandLineBuilder GetCommandLineBuilder ()
1818
{
1919
var cmd = new CommandLineBuilder ();
2020

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System.IO;
2+
using Microsoft.Build.Framework;
3+
using Microsoft.Build.Utilities;
4+
using Xamarin.Android.Tools;
5+
6+
namespace Xamarin.Android.Tasks
7+
{
8+
public abstract class BundleToolAdbTask : BundleTool
9+
{
10+
/// <summary>
11+
/// This is used to detect the attached device and generate an APK set specifically for it
12+
/// </summary>
13+
[Required]
14+
public string AdbToolPath { get; set; }
15+
16+
public string AdbToolExe { get; set; }
17+
18+
public string AdbTarget { get; set; }
19+
20+
public string AdbToolName => OS.IsWindows ? "adb.exe" : "adb";
21+
22+
protected void AppendAdbOptions (CommandLineBuilder cmd)
23+
{
24+
var adb = string.IsNullOrEmpty (AdbToolExe) ? AdbToolName : AdbToolExe;
25+
cmd.AppendSwitchIfNotNull ("--adb ", Path.Combine (AdbToolPath, adb));
26+
27+
var adbTarget = AdbTarget;
28+
if (!string.IsNullOrEmpty (adbTarget)) {
29+
// Normally of the form "-s emulator-5554"
30+
int index = adbTarget.IndexOf (' ');
31+
if (index != -1) {
32+
adbTarget = adbTarget.Substring (index + 1, adbTarget.Length - index - 1);
33+
}
34+
cmd.AppendSwitchIfNotNull ("--device-id ", adbTarget);
35+
}
36+
}
37+
}
38+
}

src/Xamarin.Android.Build.Tasks/Tasks/InstallApkSet.cs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,19 @@ namespace Xamarin.Android.Tasks
1010
///
1111
/// Usage: bundletool install-apks --apks=foo.apks
1212
/// </summary>
13-
public class InstallApkSet : BundleTool
13+
public class InstallApkSet : BundleToolAdbTask
1414
{
1515
public override string TaskPrefix => "IAS";
1616

1717
[Required]
1818
public string ApkSet { get; set; }
1919

20-
[Required]
21-
public string AdbToolPath { get; set; }
22-
23-
public string AdbToolExe { get; set; }
24-
25-
public string AdbToolName => OS.IsWindows ? "adb.exe" : "adb";
26-
27-
protected override CommandLineBuilder GetCommandLineBuilder ()
20+
internal override CommandLineBuilder GetCommandLineBuilder ()
2821
{
29-
var adb = string.IsNullOrEmpty (AdbToolExe) ? AdbToolName : AdbToolExe;
3022
var cmd = base.GetCommandLineBuilder ();
3123
cmd.AppendSwitch ("install-apks");
3224
cmd.AppendSwitchIfNotNull ("--apks ", ApkSet);
33-
cmd.AppendSwitchIfNotNull ("--adb ", Path.Combine (AdbToolPath, adb));
25+
AppendAdbOptions (cmd);
3426
cmd.AppendSwitch ("--allow-downgrade");
3527

3628
// --modules: List of modules to be installed, or "_ALL_" for all modules.

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BundleToolTests.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.IO;
55
using System.Linq;
6+
using Xamarin.Android.Tasks;
67
using Xamarin.ProjectTools;
78
using Xamarin.Tools.Zip;
89

@@ -285,5 +286,52 @@ public void ApkSet ()
285286
}
286287
}
287288
}
289+
290+
[Test]
291+
public void BuildAppBundleCommand ()
292+
{
293+
var task = new BuildAppBundle {
294+
BaseZip = "base.zip",
295+
Output = "foo.aab",
296+
};
297+
string cmd = task.GetCommandLineBuilder ().ToString ();
298+
Assert.AreEqual ($"build-bundle --modules base.zip --output foo.aab", cmd);
299+
}
300+
301+
[Test]
302+
public void BuildApkSetCommand ()
303+
{
304+
var task = new BuildApkSet {
305+
AppBundle = "foo.aab",
306+
Output = "foo.apks",
307+
KeyStore = "foo.keystore",
308+
KeyAlias = "alias",
309+
KeyPass = "keypass",
310+
StorePass = "storepass",
311+
Aapt2ToolPath = Path.Combine ("aapt", "with spaces"),
312+
Aapt2ToolExe = "aapt2",
313+
AdbToolPath = Path.Combine ("adb", "with spaces"),
314+
AdbToolExe = "adb",
315+
AdbTarget = "-s emulator-5554"
316+
};
317+
string aapt2 = Path.Combine (task.Aapt2ToolPath, task.Aapt2ToolExe);
318+
string adb = Path.Combine (task.AdbToolPath, task.AdbToolExe);
319+
string cmd = task.GetCommandLineBuilder ().ToString ();
320+
Assert.AreEqual ($"build-apks --connected-device --bundle foo.aab --output foo.apks --mode default --adb \"{adb}\" --device-id emulator-5554 --aapt2 \"{aapt2}\" --ks foo.keystore --ks-key-alias alias --key-pass pass:keypass --ks-pass pass:storepass", cmd);
321+
}
322+
323+
[Test]
324+
public void InstallApkSetCommand ()
325+
{
326+
var task = new InstallApkSet {
327+
ApkSet = "foo.apks",
328+
AdbToolPath = Path.Combine ("path", "with spaces"),
329+
AdbToolExe = "adb",
330+
AdbTarget = "-s emulator-5554"
331+
};
332+
string adb = Path.Combine (task.AdbToolPath, task.AdbToolExe);
333+
string cmd = task.GetCommandLineBuilder ().ToString ();
334+
Assert.AreEqual ($"install-apks --apks foo.apks --adb \"{adb}\" --device-id emulator-5554 --allow-downgrade --modules _ALL_", cmd);
335+
}
288336
}
289337
}

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
<Compile Include="Tasks\BuildAppBundle.cs" />
107107
<Compile Include="Tasks\BundleTool.cs" />
108108
<Compile Include="Tasks\BuildApkSet.cs" />
109+
<Compile Include="Tasks\BundleToolAdbTask.cs" />
109110
<Compile Include="Tasks\InstallApkSet.cs" />
110111
<Compile Include="Tasks\CilStrip.cs" />
111112
<Compile Include="Tasks\ConvertDebuggingFiles.cs" />

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3264,6 +3264,7 @@ because xbuild doesn't support framework reference assemblies.
32643264
JavaOptions="$(JavaOptions)"
32653265
JarPath="$(AndroidBundleToolJarPath)"
32663266
AdbToolPath="$(AdbToolPath)"
3267+
AdbTarget="$(AdbTarget)"
32673268
Aapt2ToolPath="$(Aapt2ToolPath)"
32683269
AppBundle="$(_AppBundleIntermediate)"
32693270
Output="$(_ApkSetIntermediate)"
@@ -3278,6 +3279,7 @@ because xbuild doesn't support framework reference assemblies.
32783279
JavaOptions="$(JavaOptions)"
32793280
JarPath="$(AndroidBundleToolJarPath)"
32803281
AdbToolPath="$(AdbToolPath)"
3282+
AdbTarget="$(AdbTarget)"
32813283
ApkSet="$(_ApkSetIntermediate)"
32823284
/>
32833285
</Target>

0 commit comments

Comments
 (0)