Ios: Use QtConcurrent invocation for async run

Change-Id: I1d02a7a0467864a702bed8f73793f8f21832762b
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Jarek Kobus
2023-03-09 18:07:26 +01:00
parent 8709ab5ee5
commit 4a121833b1
3 changed files with 69 additions and 73 deletions

View File

@@ -12,6 +12,7 @@
#include <debugger/debuggerconstants.h> #include <debugger/debuggerconstants.h>
#include <utils/asynctask.h>
#include <utils/filepath.h> #include <utils/filepath.h>
#include <utils/futuresynchronizer.h> #include <utils/futuresynchronizer.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -63,22 +64,22 @@ class LogTailFiles : public QObject
Q_OBJECT Q_OBJECT
public: public:
void exec(QFutureInterface<void> &fi, std::shared_ptr<QTemporaryFile> stdoutFile, void exec(QPromise<void> &promise, std::shared_ptr<QTemporaryFile> stdoutFile,
std::shared_ptr<QTemporaryFile> stderrFile) std::shared_ptr<QTemporaryFile> stderrFile)
{ {
if (fi.isCanceled()) if (promise.isCanceled())
return; return;
// The future is canceled when app on simulator is stoped. // The future is canceled when app on simulator is stoped.
QEventLoop loop; QEventLoop loop;
QFutureWatcher<void> watcher; QFutureWatcher<void> watcher;
connect(&watcher, &QFutureWatcher<void>::canceled, &loop, [&] { loop.quit(); }); connect(&watcher, &QFutureWatcher<void>::canceled, &loop, [&] { loop.quit(); });
watcher.setFuture(fi.future()); watcher.setFuture(promise.future());
// Process to print the console output while app is running. // Process to print the console output while app is running.
auto logProcess = [&](QProcess *tailProcess, std::shared_ptr<QTemporaryFile> file) { auto logProcess = [&](QProcess *tailProcess, std::shared_ptr<QTemporaryFile> file) {
QObject::connect(tailProcess, &QProcess::readyReadStandardOutput, &loop, [=] { QObject::connect(tailProcess, &QProcess::readyReadStandardOutput, &loop, [&, tailProcess] {
if (!fi.isCanceled()) if (!promise.isCanceled())
emit logMessage(QString::fromLocal8Bit(tailProcess->readAll())); emit logMessage(QString::fromLocal8Bit(tailProcess->readAll()));
}); });
tailProcess->start(QStringLiteral("tail"), {"-f", file->fileName()}); tailProcess->start(QStringLiteral("tail"), {"-f", file->fileName()});
@@ -931,17 +932,17 @@ void IosSimulatorToolHandlerPrivate::launchAppOnSimulator(const QStringList &ext
"Install Xcode 8 or later.").arg(bundleId)); "Install Xcode 8 or later.").arg(bundleId));
} }
auto monitorPid = [this](QFutureInterface<void> &fi, qint64 pid) { auto monitorPid = [this](QPromise<void> &promise, qint64 pid) {
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
do { do {
// Poll every 1 sec to check whether the app is running. // Poll every 1 sec to check whether the app is running.
QThread::msleep(1000); QThread::msleep(1000);
} while (!fi.isCanceled() && kill(pid, 0) == 0); } while (!promise.isCanceled() && kill(pid, 0) == 0);
#else #else
Q_UNUSED(pid) Q_UNUSED(pid)
#endif #endif
// Future is cancelled if the app is stopped from the qt creator. // Future is cancelled if the app is stopped from the qt creator.
if (!fi.isCanceled()) if (!promise.isCanceled())
stop(0); stop(0);
}; };
@@ -953,9 +954,9 @@ void IosSimulatorToolHandlerPrivate::launchAppOnSimulator(const QStringList &ext
gotInferiorPid(m_bundlePath, m_deviceId, response.pID); gotInferiorPid(m_bundlePath, m_deviceId, response.pID);
didStartApp(m_bundlePath, m_deviceId, Ios::IosToolHandler::Success); didStartApp(m_bundlePath, m_deviceId, Ios::IosToolHandler::Success);
// Start monitoring app's life signs. // Start monitoring app's life signs.
futureSynchronizer.addFuture(Utils::runAsync(monitorPid, response.pID)); futureSynchronizer.addFuture(Utils::asyncRun(monitorPid, response.pID));
if (captureConsole) if (captureConsole)
futureSynchronizer.addFuture(Utils::runAsync(&LogTailFiles::exec, &outputLogger, futureSynchronizer.addFuture(Utils::asyncRun(&LogTailFiles::exec, &outputLogger,
stdoutFile, stderrFile)); stdoutFile, stderrFile));
} else { } else {
m_pid = -1; m_pid = -1;

View File

@@ -5,9 +5,10 @@
#include "iosconfigurations.h" #include "iosconfigurations.h"
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/runextensions.h> #include <utils/asynctask.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/runextensions.h>
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
@@ -162,30 +163,30 @@ static SimulatorInfo deviceInfo(const QString &simUdid);
static QString bundleIdentifier(const Utils::FilePath &bundlePath); static QString bundleIdentifier(const Utils::FilePath &bundlePath);
static QString bundleExecutable(const Utils::FilePath &bundlePath); static QString bundleExecutable(const Utils::FilePath &bundlePath);
static void startSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, static void startSimulator(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid); const QString &simUdid);
static void installApp(QFutureInterface<SimulatorControl::ResponseData> &fi, static void installApp(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid, const QString &simUdid,
const Utils::FilePath &bundlePath); const Utils::FilePath &bundlePath);
static void launchApp(QFutureInterface<SimulatorControl::ResponseData> &fi, static void launchApp(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid, const QString &simUdid,
const QString &bundleIdentifier, const QString &bundleIdentifier,
bool waitForDebugger, bool waitForDebugger,
const QStringList &extraArgs, const QStringList &extraArgs,
const QString &stdoutPath, const QString &stdoutPath,
const QString &stderrPath); const QString &stderrPath);
static void deleteSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, static void deleteSimulator(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid); const QString &simUdid);
static void resetSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, static void resetSimulator(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid); const QString &simUdid);
static void renameSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, static void renameSimulator(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid, const QString &simUdid,
const QString &newName); const QString &newName);
static void createSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, static void createSimulator(QPromise<SimulatorControl::ResponseData> &promise,
const QString &name, const QString &name,
const DeviceTypeInfo &deviceType, const DeviceTypeInfo &deviceType,
const RuntimeInfo &runtime); const RuntimeInfo &runtime);
static void takeSceenshot(QFutureInterface<SimulatorControl::ResponseData> &fi, static void takeSceenshot(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid, const QString &simUdid,
const QString &filePath); const QString &filePath);
@@ -234,9 +235,9 @@ static QList<SimulatorInfo> getAvailableSimulators()
return availableDevices; return availableDevices;
} }
QFuture<QList<DeviceTypeInfo> > SimulatorControl::updateDeviceTypes() QFuture<QList<DeviceTypeInfo>> SimulatorControl::updateDeviceTypes()
{ {
QFuture< QList<DeviceTypeInfo> > future = Utils::runAsync(getAvailableDeviceTypes); QFuture<QList<DeviceTypeInfo>> future = Utils::asyncRun(getAvailableDeviceTypes);
Utils::onResultReady(future, [](const QList<DeviceTypeInfo> &deviceTypes) { Utils::onResultReady(future, [](const QList<DeviceTypeInfo> &deviceTypes) {
s_availableDeviceTypes = deviceTypes; s_availableDeviceTypes = deviceTypes;
}); });
@@ -248,18 +249,18 @@ QList<RuntimeInfo> SimulatorControl::availableRuntimes()
return s_availableRuntimes; return s_availableRuntimes;
} }
QFuture<QList<RuntimeInfo> > SimulatorControl::updateRuntimes() QFuture<QList<RuntimeInfo>> SimulatorControl::updateRuntimes()
{ {
QFuture< QList<RuntimeInfo> > future = Utils::runAsync(getAvailableRuntimes); QFuture<QList<RuntimeInfo>> future = Utils::asyncRun(getAvailableRuntimes);
Utils::onResultReady(future, [](const QList<RuntimeInfo> &runtimes) { Utils::onResultReady(future, [](const QList<RuntimeInfo> &runtimes) {
s_availableRuntimes = runtimes; s_availableRuntimes = runtimes;
}); });
return future; return future;
} }
QFuture< QList<SimulatorInfo> > SimulatorControl::updateAvailableSimulators() QFuture<QList<SimulatorInfo>> SimulatorControl::updateAvailableSimulators()
{ {
QFuture< QList<SimulatorInfo> > future = Utils::runAsync(getAvailableSimulators); QFuture<QList<SimulatorInfo>> future = Utils::asyncRun(getAvailableSimulators);
Utils::onResultReady(future, Utils::onResultReady(future,
[](const QList<SimulatorInfo> &devices) { s_availableDevices = devices; }); [](const QList<SimulatorInfo> &devices) { s_availableDevices = devices; });
return future; return future;
@@ -284,13 +285,13 @@ QString SimulatorControl::bundleExecutable(const Utils::FilePath &bundlePath)
QFuture<SimulatorControl::ResponseData> SimulatorControl::startSimulator(const QString &simUdid) QFuture<SimulatorControl::ResponseData> SimulatorControl::startSimulator(const QString &simUdid)
{ {
return Utils::runAsync(Internal::startSimulator, simUdid); return Utils::asyncRun(Internal::startSimulator, simUdid);
} }
QFuture<SimulatorControl::ResponseData> SimulatorControl::installApp( QFuture<SimulatorControl::ResponseData> SimulatorControl::installApp(
const QString &simUdid, const Utils::FilePath &bundlePath) const QString &simUdid, const Utils::FilePath &bundlePath)
{ {
return Utils::runAsync(Internal::installApp, simUdid, bundlePath); return Utils::asyncRun(Internal::installApp, simUdid, bundlePath);
} }
QFuture<SimulatorControl::ResponseData> SimulatorControl::launchApp(const QString &simUdid, QFuture<SimulatorControl::ResponseData> SimulatorControl::launchApp(const QString &simUdid,
@@ -300,7 +301,7 @@ QFuture<SimulatorControl::ResponseData> SimulatorControl::launchApp(const QStrin
const QString &stdoutPath, const QString &stdoutPath,
const QString &stderrPath) const QString &stderrPath)
{ {
return Utils::runAsync(Internal::launchApp, return Utils::asyncRun(Internal::launchApp,
simUdid, simUdid,
bundleIdentifier, bundleIdentifier,
waitForDebugger, waitForDebugger,
@@ -311,18 +312,18 @@ QFuture<SimulatorControl::ResponseData> SimulatorControl::launchApp(const QStrin
QFuture<SimulatorControl::ResponseData> SimulatorControl::deleteSimulator(const QString &simUdid) QFuture<SimulatorControl::ResponseData> SimulatorControl::deleteSimulator(const QString &simUdid)
{ {
return Utils::runAsync(Internal::deleteSimulator, simUdid); return Utils::asyncRun(Internal::deleteSimulator, simUdid);
} }
QFuture<SimulatorControl::ResponseData> SimulatorControl::resetSimulator(const QString &simUdid) QFuture<SimulatorControl::ResponseData> SimulatorControl::resetSimulator(const QString &simUdid)
{ {
return Utils::runAsync(Internal::resetSimulator, simUdid); return Utils::asyncRun(Internal::resetSimulator, simUdid);
} }
QFuture<SimulatorControl::ResponseData> SimulatorControl::renameSimulator(const QString &simUdid, QFuture<SimulatorControl::ResponseData> SimulatorControl::renameSimulator(const QString &simUdid,
const QString &newName) const QString &newName)
{ {
return Utils::runAsync(Internal::renameSimulator, simUdid, newName); return Utils::asyncRun(Internal::renameSimulator, simUdid, newName);
} }
QFuture<SimulatorControl::ResponseData> QFuture<SimulatorControl::ResponseData>
@@ -330,13 +331,13 @@ SimulatorControl::createSimulator(const QString &name,
const DeviceTypeInfo &deviceType, const DeviceTypeInfo &deviceType,
const RuntimeInfo &runtime) const RuntimeInfo &runtime)
{ {
return Utils::runAsync(Internal::createSimulator, name, deviceType, runtime); return Utils::asyncRun(Internal::createSimulator, name, deviceType, runtime);
} }
QFuture<SimulatorControl::ResponseData> SimulatorControl::takeSceenshot(const QString &simUdid, QFuture<SimulatorControl::ResponseData> SimulatorControl::takeSceenshot(const QString &simUdid,
const QString &filePath) const QString &filePath)
{ {
return Utils::runAsync(Internal::takeSceenshot, simUdid, filePath); return Utils::asyncRun(Internal::takeSceenshot, simUdid, filePath);
} }
// Static members // Static members
@@ -392,7 +393,7 @@ QString bundleExecutable(const Utils::FilePath &bundlePath)
return executable; return executable;
} }
void startSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid) void startSimulator(QPromise<SimulatorControl::ResponseData> &promise, const QString &simUdid)
{ {
SimulatorControl::ResponseData response(simUdid); SimulatorControl::ResponseData response(simUdid);
SimulatorInfo simInfo = deviceInfo(simUdid); SimulatorInfo simInfo = deviceInfo(simUdid);
@@ -420,7 +421,7 @@ void startSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, const
if (simInfo.isShutdown()) { if (simInfo.isShutdown()) {
if (launchSimulator(simUdid)) { if (launchSimulator(simUdid)) {
if (fi.isCanceled()) if (promise.isCanceled())
return; return;
// At this point the sim device exists, available and was not running. // At this point the sim device exists, available and was not running.
// So the simulator is started and we'll wait for it to reach to a state // So the simulator is started and we'll wait for it to reach to a state
@@ -429,13 +430,11 @@ void startSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, const
SimulatorInfo info; SimulatorInfo info;
do { do {
info = deviceInfo(simUdid); info = deviceInfo(simUdid);
if (fi.isCanceled()) if (promise.isCanceled())
return; return;
} while (!info.isBooted() } while (!info.isBooted() && !checkForTimeout(start, simulatorStartTimeout));
&& !checkForTimeout(start, simulatorStartTimeout)); if (info.isBooted())
if (info.isBooted()) {
response.success = true; response.success = true;
}
} else { } else {
qCDebug(simulatorLog) << "Error starting simulator."; qCDebug(simulatorLog) << "Error starting simulator.";
} }
@@ -444,14 +443,12 @@ void startSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, const
<< simInfo; << simInfo;
} }
if (!fi.isCanceled()) { if (!promise.isCanceled())
fi.reportResult(response); promise.addResult(response);
}
} }
void installApp(QFutureInterface<SimulatorControl::ResponseData> &fi, void installApp(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid, const QString &simUdid, const Utils::FilePath &bundlePath)
const Utils::FilePath &bundlePath)
{ {
QTC_CHECK(bundlePath.exists()); QTC_CHECK(bundlePath.exists());
@@ -459,11 +456,11 @@ void installApp(QFutureInterface<SimulatorControl::ResponseData> &fi,
response.success = runSimCtlCommand({"install", simUdid, bundlePath.toString()}, response.success = runSimCtlCommand({"install", simUdid, bundlePath.toString()},
nullptr, nullptr,
&response.commandOutput); &response.commandOutput);
if (!fi.isCanceled()) if (!promise.isCanceled())
fi.reportResult(response); promise.addResult(response);
} }
void launchApp(QFutureInterface<SimulatorControl::ResponseData> &fi, void launchApp(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid, const QString &simUdid,
const QString &bundleIdentifier, const QString &bundleIdentifier,
bool waitForDebugger, bool waitForDebugger,
@@ -472,7 +469,7 @@ void launchApp(QFutureInterface<SimulatorControl::ResponseData> &fi,
const QString &stderrPath) const QString &stderrPath)
{ {
SimulatorControl::ResponseData response(simUdid); SimulatorControl::ResponseData response(simUdid);
if (!bundleIdentifier.isEmpty() && !fi.isCanceled()) { if (!bundleIdentifier.isEmpty() && !promise.isCanceled()) {
QStringList args({"launch", simUdid, bundleIdentifier}); QStringList args({"launch", simUdid, bundleIdentifier});
// simctl usage documentation : Note: Log output is often directed to stderr, not stdout. // simctl usage documentation : Note: Log output is often directed to stderr, not stdout.
@@ -499,30 +496,29 @@ void launchApp(QFutureInterface<SimulatorControl::ResponseData> &fi,
} }
} }
if (!fi.isCanceled()) { if (!promise.isCanceled())
fi.reportResult(response); promise.addResult(response);
}
} }
void deleteSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid) void deleteSimulator(QPromise<SimulatorControl::ResponseData> &promise, const QString &simUdid)
{ {
SimulatorControl::ResponseData response(simUdid); SimulatorControl::ResponseData response(simUdid);
response.success = runSimCtlCommand({"delete", simUdid}, nullptr, &response.commandOutput); response.success = runSimCtlCommand({"delete", simUdid}, nullptr, &response.commandOutput);
if (!fi.isCanceled()) if (!promise.isCanceled())
fi.reportResult(response); promise.addResult(response);
} }
void resetSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, const QString &simUdid) void resetSimulator(QPromise<SimulatorControl::ResponseData> &promise, const QString &simUdid)
{ {
SimulatorControl::ResponseData response(simUdid); SimulatorControl::ResponseData response(simUdid);
response.success = runSimCtlCommand({"erase", simUdid}, nullptr, &response.commandOutput); response.success = runSimCtlCommand({"erase", simUdid}, nullptr, &response.commandOutput);
if (!fi.isCanceled()) if (!promise.isCanceled())
fi.reportResult(response); promise.addResult(response);
} }
void renameSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, void renameSimulator(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid, const QString &simUdid,
const QString &newName) const QString &newName)
{ {
@@ -530,12 +526,11 @@ void renameSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi,
response.success = runSimCtlCommand({"rename", simUdid, newName}, response.success = runSimCtlCommand({"rename", simUdid, newName},
nullptr, nullptr,
&response.commandOutput); &response.commandOutput);
if (!promise.isCanceled())
if (!fi.isCanceled()) promise.addResult(response);
fi.reportResult(response);
} }
void createSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi, void createSimulator(QPromise<SimulatorControl::ResponseData> &promise,
const QString &name, const QString &name,
const DeviceTypeInfo &deviceType, const DeviceTypeInfo &deviceType,
const RuntimeInfo &runtime) const RuntimeInfo &runtime)
@@ -550,11 +545,11 @@ void createSimulator(QFutureInterface<SimulatorControl::ResponseData> &fi,
response.simUdid = response.success ? stdOutput.trimmed() : QString(); response.simUdid = response.success ? stdOutput.trimmed() : QString();
} }
if (!fi.isCanceled()) if (!promise.isCanceled())
fi.reportResult(response); promise.addResult(response);
} }
void takeSceenshot(QFutureInterface<SimulatorControl::ResponseData> &fi, void takeSceenshot(QPromise<SimulatorControl::ResponseData> &promise,
const QString &simUdid, const QString &simUdid,
const QString &filePath) const QString &filePath)
{ {
@@ -562,8 +557,8 @@ void takeSceenshot(QFutureInterface<SimulatorControl::ResponseData> &fi,
response.success = runSimCtlCommand({"io", simUdid, "screenshot", filePath}, response.success = runSimCtlCommand({"io", simUdid, "screenshot", filePath},
nullptr, nullptr,
&response.commandOutput); &response.commandOutput);
if (!fi.isCanceled()) if (!promise.isCanceled())
fi.reportResult(response); promise.addResult(response);
} }
QDebug &operator<<(QDebug &stream, const SimulatorInfo &info) QDebug &operator<<(QDebug &stream, const SimulatorInfo &info)

View File

@@ -65,11 +65,11 @@ public:
public: public:
static QList<DeviceTypeInfo> availableDeviceTypes(); static QList<DeviceTypeInfo> availableDeviceTypes();
static QFuture<QList<DeviceTypeInfo> > updateDeviceTypes(); static QFuture<QList<DeviceTypeInfo>> updateDeviceTypes();
static QList<RuntimeInfo> availableRuntimes(); static QList<RuntimeInfo> availableRuntimes();
static QFuture<QList<RuntimeInfo> > updateRuntimes(); static QFuture<QList<RuntimeInfo>> updateRuntimes();
static QList<SimulatorInfo> availableSimulators(); static QList<SimulatorInfo> availableSimulators();
static QFuture<QList<SimulatorInfo> > updateAvailableSimulators(); static QFuture<QList<SimulatorInfo>> updateAvailableSimulators();
static bool isSimulatorRunning(const QString &simUdid); static bool isSimulatorRunning(const QString &simUdid);
static QString bundleIdentifier(const Utils::FilePath &bundlePath); static QString bundleIdentifier(const Utils::FilePath &bundlePath);
static QString bundleExecutable(const Utils::FilePath &bundlePath); static QString bundleExecutable(const Utils::FilePath &bundlePath);