Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,55 @@
using System.Collections.Generic;
using System.Threading;

using Microsoft.Build.Framework;

namespace Xamarin.Android.Tools.BootstrapTasks
{
public class WaitForAndroidEmulator : Adb
{
int bootCompleted = -1;
bool pmReady;

public override bool Execute ()
{
// The timeout is shared between both phases (boot_completed and
// Package Manager readiness), so the total wall-clock time for
// the entire method is bounded by a single Timeout period.
var endTime = DateTime.UtcNow.AddMilliseconds (Timeout);

// Phase 1: wait for sys.boot_completed
while (DateTime.UtcNow < endTime && bootCompleted != 1) {
base.Execute ();
if (bootCompleted == 1)
break;
Thread.Sleep (3000);
}

if (bootCompleted != 1) {
Log.LogError ($"Emulator '{AdbTarget}' did not finish launching in {Timeout} ms.");
return false;
}

// Phase 2: wait for Package Manager to be ready.
// sys.boot_completed fires before PM is fully initialized, and
// subsequent adb checks that query PM can fail if we return too
// early, causing a second emulator to be launched on the same
// port (see CheckAdbTarget).
Log.LogMessage (MessageImportance.Normal, "Boot completed, waiting for Package Manager...");
while (DateTime.UtcNow < endTime && !pmReady) {
base.Execute ();
if (pmReady)
break;
Thread.Sleep (3000);
}

if (!pmReady) {
Log.LogError ($"Emulator '{AdbTarget}' Package Manager did not become ready in {Timeout} ms.");
return false;
}

Log.LogMessage (MessageImportance.Normal, "Package Manager is ready.");

return !Log.HasLoggedErrors;
}

Expand All @@ -28,6 +59,14 @@ public override bool Execute ()
return new List <CommandInfo> {
new CommandInfo {
ArgumentsString = $"{AdbTarget} shell getprop sys.boot_completed",
ShouldRun = () => bootCompleted != 1,
},
new CommandInfo {
ArgumentsString = $"{AdbTarget} shell pm path com.android.shell",
IgnoreExitCode = true,
LogIgnoredExitCodeAsWarning = false,
MergeStdoutAndStderr = false,
ShouldRun = () => bootCompleted == 1,
},
};
}
Expand All @@ -37,10 +76,14 @@ protected override void ProcessStdout (string line)
if (string.IsNullOrEmpty (line))
return;

if (!int.TryParse (line, out int bootCompletedPropValue))
return;

bootCompleted = bootCompletedPropValue;
if (bootCompleted != 1) {
if (int.TryParse (line, out int value))
bootCompleted = value;
} else {
if (line.StartsWith ("package:", StringComparison.Ordinal))
pmReady = true;
}
}

}
}
Loading