Skip to content

Commit e61a4ea

Browse files
jonathanpeppersjonpryor
authored andcommitted
[Xamarin.Android.Build.Tasks] improve incremental deploy in IDEs (#3555)
When doing some testing in the IDE, I noticed something odd for an incremental deploy: Building target "_BuildApkFastDev" completely. Input file "obj\Debug\90\adb.props" is newer than output file "obj\Debug\90\android\bin\com.companyname.app14.apk". This target took 2.470s in this case. This was the Android App template in VS 2019 (not Xamarin.Forms). I just modified a `.cs` file, how did `adb.props` change??? It turns out that during the `Build` target, `adb.props` is blank, and during the `Install` target, it is properly set. That means that the `Install` target is currently always running the `_BuildApkFastDev` target on incremental deployments. I let the IDE team know, so they can see about sending `$(AdbTarget)` during `Build`. However, they can't do this in every case, due to the way the UI is setup. Depending on the user's selection, current document, focus, etc. the play button in VS may not be enabled or even *know* the current attached device. This leads me to think we should really change something in our MSBuild targets, which currently does: <WriteLinesToFile Condition=" '$(DesignTimeBuild)' != 'True' " File="$(_AdbPropertiesCache)" Lines="AdbTarget=$(AdbTarget);AdbOptions=$(AdbOptions)" Overwrite="true" WriteOnlyWhenDifferent="true" /> If we didn't write this file when `$(AdbTarget)` is blank, the problem would be avoided. However, we also should write the file if it does not exist. If an `Input` to a target doesn't exist, it will run every time. `adb.props` is used as `Inputs` for some targets. I added a test for this to the `MSBuildDeviceIntegration` tests.
1 parent 0eed072 commit e61a4ea

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/DeviceTest.cs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,5 +140,29 @@ protected static void ClickButton (string packageName, string buttonName, string
140140
var bounds = GetControlBounds (packageName, buttonName, buttonText);
141141
RunAdbInput ("input tap", bounds.x + ((bounds.w - bounds.x) / 2), bounds.y + ((bounds.h - bounds.y) / 2));
142142
}
143-
}
144-
}
143+
144+
/// <summary>
145+
/// Returns the first device listed via `adb devices`
146+
///
147+
/// Output is:
148+
/// > adb devices
149+
/// List of devices attached
150+
/// 89RY0AEFA device
151+
/// </summary>
152+
/// <returns></returns>
153+
protected static string GetAttachedDeviceSerial ()
154+
{
155+
var text = RunAdbCommand ("devices");
156+
var lines = text.Split ('\n');
157+
if (lines.Length < 2) {
158+
Assert.Fail ($"Unexpected `adb devices` output: {text}");
159+
}
160+
var serial = lines [1];
161+
var index = serial.IndexOf ('\t');
162+
if (index != -1) {
163+
serial = serial.Substring (0, index);
164+
}
165+
return serial.Trim ();
166+
}
167+
}
168+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ because xbuild doesn't support framework reference assemblies.
12621262
WriteOnlyWhenDifferent="true"
12631263
/>
12641264
<WriteLinesToFile
1265-
Condition=" '$(DesignTimeBuild)' != 'True' "
1265+
Condition=" '$(DesignTimeBuild)' != 'True' And ('$(AdbTarget)' != '' Or !Exists('$(_AdbPropertiesCache)')) "
12661266
File="$(_AdbPropertiesCache)"
12671267
Lines="AdbTarget=$(AdbTarget);AdbOptions=$(AdbOptions)"
12681268
Overwrite="true"

tests/MSBuildDeviceIntegration/Tests/InstallTests.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Xamarin.Android.Build.Tests
1212
[TestFixture]
1313
[NonParallelizable] //These tests deploy to devices
1414
[Category ("Commercial")]
15-
public class InstallTests : BaseTest
15+
public class InstallTests : DeviceTest
1616
{
1717
[Test]
1818
public void ReInstallIfUserUninstalled ([Values (false, true)] bool isRelease)
@@ -298,5 +298,28 @@ public void ToggleFastDev ()
298298
Assert.IsTrue (builder.Install (proj), "Third install should have succeeded.");
299299
}
300300
}
301+
302+
[Test]
303+
public void BlankAdbTarget ()
304+
{
305+
if (!CommercialBuildAvailable) {
306+
Assert.Ignore ("Not required on Open Source Builds");
307+
}
308+
if (!HasDevices) {
309+
Assert.Ignore ("Test Skipped no devices or emulators found.");
310+
}
311+
312+
var serial = GetAttachedDeviceSerial ();
313+
var proj = new XamarinAndroidApplicationProject ();
314+
proj.SetProperty (proj.DebugProperties, "AndroidUseSharedRuntime", true);
315+
proj.SetProperty (proj.DebugProperties, "EmbedAssembliesIntoApk", false);
316+
317+
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
318+
b.Build (proj, parameters: new [] { $"AdbTarget=\"-e {serial}\"" });
319+
// Build again, no $(AdbTarget)
320+
b.Build (proj);
321+
Assert.IsTrue (b.Output.IsTargetSkipped ("_BuildApkFastDev"), "_BuildApkFastDev should be skipped!");
322+
}
323+
}
301324
}
302325
}

0 commit comments

Comments
 (0)