Android: Rewrite waitForAvd()

Now takes a QFutureInterface to enable canceling and beautify the code
by splitting it up.

Change-Id: Ifedf19c3ad1a37a9b7cb6b7db8ec799ceebc5392
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
This commit is contained in:
Daniel Teske
2013-11-13 16:35:29 +01:00
parent adc25d1e02
commit e79cdc1690
3 changed files with 41 additions and 24 deletions

View File

@@ -659,32 +659,45 @@ QString AndroidConfigurations::findAvd(int apiLevel, const QString &cpuAbi) cons
return QString(); return QString();
} }
QString AndroidConfigurations::waitForAvd(int apiLevel, const QString &cpuAbi) const bool AndroidConfigurations::isConnected(const QString &serialNumber) const
{
QVector<AndroidDeviceInfo> devices = connectedDevices();
foreach (AndroidDeviceInfo device, devices) {
if (device.serialNumber == serialNumber)
return true;
}
return false;
}
bool AndroidConfigurations::waitForBooted(const QString &serialNumber, const QFutureInterface<bool> &fi) const
{
// found a serial number, now wait until it's done booting...
for (int i = 0; i < 60; ++i) {
if (fi.isCanceled())
return false;
if (hasFinishedBooting(serialNumber)) {
return true;
} else {
Utils::sleep(2000);
if (!isConnected(serialNumber)) // device was disconnected
return false;
}
}
return false;
}
QString AndroidConfigurations::waitForAvd(int apiLevel, const QString &cpuAbi, const QFutureInterface<bool> &fi) const
{ {
// we cannot use adb -e wait-for-device, since that doesn't work if a emulator is already running // we cannot use adb -e wait-for-device, since that doesn't work if a emulator is already running
// 60 rounds of 2s sleeping, two minutes for the avd to start
// 15 rounds of 8s sleeping, a minute for the avd to start
QString serialNumber; QString serialNumber;
for (int i = 0; i < 15; ++i) { for (int i = 0; i < 60; ++i) {
QVector<AndroidDeviceInfo> devices = connectedDevices(); if (fi.isCanceled())
foreach (AndroidDeviceInfo device, devices) {
if (!device.serialNumber.startsWith(QLatin1String("emulator")))
continue;
if (!device.cpuAbi.contains(cpuAbi))
continue;
if (device.sdk != apiLevel)
continue;
serialNumber = device.serialNumber;
// found a serial number, now wait until it's done booting...
for (int i = 0; i < 15; ++i) {
if (hasFinishedBooting(serialNumber))
return serialNumber;
else
Utils::sleep(8000);
}
return QString(); return QString();
} serialNumber = findAvd(apiLevel, cpuAbi);
Utils::sleep(8000); if (!serialNumber.isEmpty())
return waitForBooted(serialNumber, fi) ? serialNumber : QString();
Utils::sleep(2000);
} }
return QString(); return QString();
} }

View File

@@ -36,6 +36,7 @@
#include <QVector> #include <QVector>
#include <QHash> #include <QHash>
#include <QMap> #include <QMap>
#include <QFutureInterface>
#include <projectexplorer/abi.h> #include <projectexplorer/abi.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
@@ -107,7 +108,8 @@ public:
QString startAVD(const QString &name, int apiLevel, QString cpuAbi) const; QString startAVD(const QString &name, int apiLevel, QString cpuAbi) const;
bool startAVDAsync(const QString &avdName) const; bool startAVDAsync(const QString &avdName) const;
QString findAvd(int apiLevel, const QString &cpuAbi) const; QString findAvd(int apiLevel, const QString &cpuAbi) const;
QString waitForAvd(int apiLevel, const QString &cpuAbi) const; QString waitForAvd(int apiLevel, const QString &cpuAbi, const QFutureInterface<bool> &fi = QFutureInterface<bool>()) const;
// special version for AndroidDeployQt::run
QString bestNdkPlatformMatch(const QString &targetAPI) const; QString bestNdkPlatformMatch(const QString &targetAPI) const;
QStringList makeExtraSearchDirectories() const; QStringList makeExtraSearchDirectories() const;
@@ -121,6 +123,8 @@ public:
QString getProductModel(const QString &device) const; QString getProductModel(const QString &device) const;
bool hasFinishedBooting(const QString &device) const; bool hasFinishedBooting(const QString &device) const;
bool waitForBooted(const QString &serialNumber, const QFutureInterface<bool> &fi) const;
bool isConnected(const QString &serialNumber) const;
AndroidDeviceInfo showDeviceDialog(ProjectExplorer::Project *project, int apiLevel, const QString &abi); AndroidDeviceInfo showDeviceDialog(ProjectExplorer::Project *project, int apiLevel, const QString &abi);
void setDefaultDevice(ProjectExplorer::Project *project, const QString &abi, const QString &serialNumber); // serial number or avd name void setDefaultDevice(ProjectExplorer::Project *project, const QString &abi, const QString &serialNumber); // serial number or avd name

View File

@@ -295,7 +295,7 @@ bool AndroidDeployQtStep::init()
void AndroidDeployQtStep::run(QFutureInterface<bool> &fi) void AndroidDeployQtStep::run(QFutureInterface<bool> &fi)
{ {
if (!m_avdName.isEmpty()) { if (!m_avdName.isEmpty()) {
QString serialNumber = AndroidConfigurations::instance().waitForAvd(m_deviceAPILevel, m_targetArch); QString serialNumber = AndroidConfigurations::instance().waitForAvd(m_deviceAPILevel, m_targetArch, fi);
if (serialNumber.isEmpty()) { if (serialNumber.isEmpty()) {
fi.reportResult(false); fi.reportResult(false);
return; return;