AndroidDeployQtStep: Make it cancelable

And use QFutureInterface for it.

Change-Id: I1145b70b119d92af7316977c813f4f29b1f20b74
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2022-11-09 16:05:25 +01:00
parent 038771051d
commit 1e632d0c25
5 changed files with 34 additions and 23 deletions

View File

@@ -291,20 +291,20 @@ QString AndroidAvdManager::findAvd(const QString &avdName) const
} }
QString AndroidAvdManager::waitForAvd(const QString &avdName, QString AndroidAvdManager::waitForAvd(const QString &avdName,
const std::function<bool()> &cancelChecker) const const QFutureInterfaceBase &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 // 60 rounds of 2s sleeping, two minutes for the avd to start
QString serialNumber; QString serialNumber;
for (int i = 0; i < 60; ++i) { for (int i = 0; i < 60; ++i) {
if (cancelChecker && cancelChecker()) if (fi.isCanceled())
return QString(); return {};
serialNumber = findAvd(avdName); serialNumber = findAvd(avdName);
if (!serialNumber.isEmpty()) if (!serialNumber.isEmpty())
return waitForBooted(serialNumber, cancelChecker) ? serialNumber : QString(); return waitForBooted(serialNumber, fi) ? serialNumber : QString();
QThread::sleep(2); QThread::sleep(2);
} }
return QString(); return {};
} }
bool AndroidAvdManager::isAvdBooted(const QString &device) const bool AndroidAvdManager::isAvdBooted(const QString &device) const
@@ -325,11 +325,11 @@ bool AndroidAvdManager::isAvdBooted(const QString &device) const
} }
bool AndroidAvdManager::waitForBooted(const QString &serialNumber, bool AndroidAvdManager::waitForBooted(const QString &serialNumber,
const std::function<bool()> &cancelChecker) const const QFutureInterfaceBase &fi) const
{ {
// found a serial number, now wait until it's done booting... // found a serial number, now wait until it's done booting...
for (int i = 0; i < 60; ++i) { for (int i = 0; i < 60; ++i) {
if (cancelChecker && cancelChecker()) if (fi.isCanceled())
return false; return false;
if (isAvdBooted(serialNumber)) if (isAvdBooted(serialNumber))
return true; return true;

View File

@@ -22,16 +22,14 @@ public:
QString startAvd(const QString &name) const; QString startAvd(const QString &name) const;
bool startAvdAsync(const QString &avdName) const; bool startAvdAsync(const QString &avdName) const;
QString findAvd(const QString &avdName) const; QString findAvd(const QString &avdName) const;
QString waitForAvd(const QString &avdName, QString waitForAvd(const QString &avdName, const QFutureInterfaceBase &fi = {}) const;
const std::function<bool()> &cancelChecker = {}) const;
bool isAvdBooted(const QString &device) const; bool isAvdBooted(const QString &device) const;
static bool avdManagerCommand(const AndroidConfig &config, static bool avdManagerCommand(const AndroidConfig &config,
const QStringList &args, const QStringList &args,
QString *output); QString *output);
private: private:
bool waitForBooted(const QString &serialNumber, bool waitForBooted(const QString &serialNumber, const QFutureInterfaceBase &fi = {}) const;
const std::function<bool()> &cancelChecker) const;
private: private:
const AndroidConfig &m_config; const AndroidConfig &m_config;

View File

@@ -3,16 +3,14 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#include "androidavdmanager.h" #include "androidavdmanager.h"
#include "androidbuildapkstep.h"
#include "androidconstants.h" #include "androidconstants.h"
#include "androiddeployqtstep.h" #include "androiddeployqtstep.h"
#include "androiddevice.h" #include "androiddevice.h"
#include "androidglobal.h"
#include "androidmanager.h" #include "androidmanager.h"
#include "androidqtversion.h" #include "androidqtversion.h"
#include "androidtr.h" #include "androidtr.h"
#include "androidtr.h" #include "androidtr.h"
#include "certificatesmodel.h"
#include "javaparser.h"
#include <coreplugin/fileutils.h> #include <coreplugin/fileutils.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -35,6 +33,7 @@
#include <utils/layoutbuilder.h> #include <utils/layoutbuilder.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/runextensions.h>
#include <QCheckBox> #include <QCheckBox>
#include <QFileDialog> #include <QFileDialog>
@@ -402,15 +401,16 @@ void AndroidDeployQtStep::slotAskForUninstall(DeployErrorCode errorCode)
m_askForUninstall = button == QMessageBox::Yes; m_askForUninstall = button == QMessageBox::Yes;
} }
bool AndroidDeployQtStep::runImpl() void AndroidDeployQtStep::runImpl(QFutureInterface<bool> &fi)
{ {
if (!m_avdName.isEmpty()) { if (!m_avdName.isEmpty()) {
QString serialNumber = AndroidAvdManager().waitForAvd(m_avdName, cancelChecker()); QString serialNumber = AndroidAvdManager().waitForAvd(m_avdName, fi);
qCDebug(deployStepLog) << "Deploying to AVD:" << m_avdName << serialNumber; qCDebug(deployStepLog) << "Deploying to AVD:" << m_avdName << serialNumber;
if (serialNumber.isEmpty()) { if (serialNumber.isEmpty()) {
reportWarningOrError(Tr::tr("The deployment AVD \"%1\" cannot be started.") reportWarningOrError(Tr::tr("The deployment AVD \"%1\" cannot be started.")
.arg(m_avdName), Task::Error); .arg(m_avdName), Task::Error);
return false; fi.reportResult(false);
return;
} }
m_serialNumber = serialNumber; m_serialNumber = serialNumber;
qCDebug(deployStepLog) << "Deployment device serial number changed:" << serialNumber; qCDebug(deployStepLog) << "Deployment device serial number changed:" << serialNumber;
@@ -445,8 +445,7 @@ bool AndroidDeployQtStep::runImpl()
reportWarningOrError(error, Task::Error); reportWarningOrError(error, Task::Error);
} }
} }
fi.reportResult(returnValue == NoError);
return returnValue == NoError;
} }
void AndroidDeployQtStep::gatherFilesToPull() void AndroidDeployQtStep::gatherFilesToPull()
@@ -480,7 +479,20 @@ void AndroidDeployQtStep::gatherFilesToPull()
void AndroidDeployQtStep::doRun() void AndroidDeployQtStep::doRun()
{ {
m_synchronizer.addFuture(runInThread([this] { return runImpl(); })); auto * const watcher = new QFutureWatcher<bool>(this);
connect(watcher, &QFutureWatcher<bool>::finished, this, [this, watcher] {
const bool success = !watcher->isCanceled() && watcher->result();
emit finished(success);
watcher->deleteLater();
});
auto future = Utils::runAsync(&AndroidDeployQtStep::runImpl, this);
watcher->setFuture(future);
m_synchronizer.addFuture(future);
}
void AndroidDeployQtStep::doCancel()
{
m_synchronizer.cancelAllFutures();
} }
void AndroidDeployQtStep::runCommand(const CommandLine &command) void AndroidDeployQtStep::runCommand(const CommandLine &command)

View File

@@ -4,8 +4,7 @@
#pragma once #pragma once
#include "androidbuildapkstep.h" #include "androiddeviceinfo.h"
#include "androidconfigurations.h"
#include <projectexplorer/abstractprocessstep.h> #include <projectexplorer/abstractprocessstep.h>
#include <qtsupport/baseqtversion.h> #include <qtsupport/baseqtversion.h>
@@ -49,11 +48,12 @@ private:
bool init() override; bool init() override;
void doRun() override; void doRun() override;
void doCancel() override;
void gatherFilesToPull(); void gatherFilesToPull();
DeployErrorCode runDeploy(); DeployErrorCode runDeploy();
void slotAskForUninstall(DeployErrorCode errorCode); void slotAskForUninstall(DeployErrorCode errorCode);
bool runImpl(); void runImpl(QFutureInterface<bool> &fi);
QWidget *createConfigWidget() override; QWidget *createConfigWidget() override;

View File

@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#include "androidconfigurations.h" #include "androidconfigurations.h"
#include "androidbuildapkstep.h"
#include "androidconstants.h" #include "androidconstants.h"
#include "androiddebugsupport.h" #include "androiddebugsupport.h"
#include "androiddeployqtstep.h" #include "androiddeployqtstep.h"