diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index e6e2e7a6ab0..9db1a4f8640 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -659,32 +659,45 @@ QString AndroidConfigurations::findAvd(int apiLevel, const QString &cpuAbi) cons return QString(); } -QString AndroidConfigurations::waitForAvd(int apiLevel, const QString &cpuAbi) const +bool AndroidConfigurations::isConnected(const QString &serialNumber) const +{ + QVector devices = connectedDevices(); + foreach (AndroidDeviceInfo device, devices) { + if (device.serialNumber == serialNumber) + return true; + } + return false; +} + +bool AndroidConfigurations::waitForBooted(const QString &serialNumber, const QFutureInterface &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 &fi) const { // we cannot use adb -e wait-for-device, since that doesn't work if a emulator is already running - - // 15 rounds of 8s sleeping, a minute for the avd to start + // 60 rounds of 2s sleeping, two minutes for the avd to start QString serialNumber; - for (int i = 0; i < 15; ++i) { - QVector devices = connectedDevices(); - 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); - } + for (int i = 0; i < 60; ++i) { + if (fi.isCanceled()) return QString(); - } - Utils::sleep(8000); + serialNumber = findAvd(apiLevel, cpuAbi); + if (!serialNumber.isEmpty()) + return waitForBooted(serialNumber, fi) ? serialNumber : QString(); + Utils::sleep(2000); } return QString(); } diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index faa6518541b..c858cb2d900 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -107,7 +108,8 @@ public: QString startAVD(const QString &name, int apiLevel, QString cpuAbi) const; bool startAVDAsync(const QString &avdName) 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 &fi = QFutureInterface()) const; + // special version for AndroidDeployQt::run QString bestNdkPlatformMatch(const QString &targetAPI) const; QStringList makeExtraSearchDirectories() const; @@ -121,6 +123,8 @@ public: QString getProductModel(const QString &device) const; bool hasFinishedBooting(const QString &device) const; + bool waitForBooted(const QString &serialNumber, const QFutureInterface &fi) const; + bool isConnected(const QString &serialNumber) const; 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 diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index 37ebf3f918b..642ca00b3a6 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -295,7 +295,7 @@ bool AndroidDeployQtStep::init() void AndroidDeployQtStep::run(QFutureInterface &fi) { 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()) { fi.reportResult(false); return;