summaryrefslogtreecommitdiff
path: root/src/plugins/ios
diff options
context:
space:
mode:
authorVikas Pachdha <vikas.pachdha@qt.io>2017-06-02 09:23:46 +0200
committerVikas Pachdha <vikas.pachdha@qt.io>2017-06-02 12:51:43 +0000
commitf9350a5dbd67507b99517a62ccc19939e69dcf8c (patch)
treeceba161902144db28aac8edaab20b73b793e3168 /src/plugins/ios
parentd23f4cff84b4d8d6da37197c1b767bf0ede77168 (diff)
downloadqt-creator-f9350a5dbd67507b99517a62ccc19939e69dcf8c.tar.gz
iOS: Fix isRunning state of the app running on Simulator
Refactored IostoolHandler code and fixed isRunning(..) for Simulator Change-Id: Ib24431fc8e66f8d1be983c2e41d36df2169a9cb4 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'src/plugins/ios')
-rw-r--r--src/plugins/ios/iosrunner.cpp7
-rw-r--r--src/plugins/ios/iostoolhandler.cpp227
-rw-r--r--src/plugins/ios/iostoolhandler.h5
3 files changed, 121 insertions, 118 deletions
diff --git a/src/plugins/ios/iosrunner.cpp b/src/plugins/ios/iosrunner.cpp
index c82183dfbe..5bf8057320 100644
--- a/src/plugins/ios/iosrunner.cpp
+++ b/src/plugins/ios/iosrunner.cpp
@@ -159,13 +159,8 @@ void IosRunner::start()
void IosRunner::stop()
{
- if (m_toolHandler) {
-#ifdef Q_OS_UNIX
- if (m_pid > 0)
- kill(m_pid, SIGKILL);
-#endif
+ if (m_toolHandler && m_toolHandler->isRunning())
m_toolHandler->stop();
- }
}
void IosRunner::handleDidStartApp(IosToolHandler *handler, const QString &bundlePath,
diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp
index 895397ffbe..2a6fea28b5 100644
--- a/src/plugins/ios/iostoolhandler.cpp
+++ b/src/plugins/ios/iostoolhandler.cpp
@@ -184,20 +184,6 @@ struct ParserState {
class IosToolHandlerPrivate
{
public:
- enum State {
- NonStarted,
- Starting,
- StartedInferior,
- XmlEndProcessed,
- Stopped
- };
- enum Op {
- OpNone,
- OpAppTransfer,
- OpDeviceInfo,
- OpAppRun
- };
-
explicit IosToolHandlerPrivate(const IosDeviceType &devType, IosToolHandler *q);
virtual ~IosToolHandlerPrivate();
virtual void requestTransferApp(const QString &bundlePath, const QString &deviceId,
@@ -206,8 +192,7 @@ public:
IosToolHandler::RunKind runKind,
const QString &deviceId, int timeout = 1000) = 0;
virtual void requestDeviceInfo(const QString &deviceId, int timeout = 1000) = 0;
- bool isRunning();
- void start(const QString &exe, const QStringList &args);
+ virtual bool isRunning() const = 0;
virtual void stop(int errorCode) = 0;
// signals
@@ -226,26 +211,28 @@ public:
void toolExited(int code);
protected:
- void killProcess();
-
-protected:
IosToolHandler *q;
- std::shared_ptr<QProcess> process;
- QTimer killTimer;
- QXmlStreamReader outputParser;
- QString deviceId;
- QString bundlePath;
- IosToolHandler::RunKind runKind;
- State state;
- Op op;
- IosDeviceType devType;
- static const int lookaheadSize = 67;
- int iBegin, iEnd, gdbSocket;
- QList<ParserState> stack;
+ QString m_deviceId;
+ QString m_bundlePath;
+ IosToolHandler::RunKind m_runKind;
+ IosDeviceType m_devType;
};
class IosDeviceToolHandlerPrivate : public IosToolHandlerPrivate
{
+ enum State {
+ NonStarted,
+ Starting,
+ StartedInferior,
+ XmlEndProcessed,
+ Stopped
+ };
+ enum Op {
+ OpNone,
+ OpAppTransfer,
+ OpDeviceInfo,
+ OpAppRun
+ };
public:
explicit IosDeviceToolHandlerPrivate(const IosDeviceType &devType, IosToolHandler *q);
~IosDeviceToolHandlerPrivate();
@@ -258,6 +245,8 @@ public:
IosToolHandler::RunKind runKind,
const QString &deviceId, int timeout = 1000) override;
void requestDeviceInfo(const QString &deviceId, int timeout = 1000) override;
+ bool isRunning() const override;
+ void start(const QString &exe, const QStringList &args);
void stop(int errorCode) override;
private:
@@ -265,6 +254,14 @@ private:
void subprocessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void subprocessHasData();
void processXml();
+ void killProcess();
+
+ QTimer killTimer;
+ std::shared_ptr<QProcess> process;
+ State state = NonStarted;
+ Op op = OpNone;
+ QXmlStreamReader outputParser;
+ QList<ParserState> stack;
};
/****************************************************************************
@@ -317,6 +314,7 @@ public:
IosToolHandler::RunKind runKind,
const QString &deviceIdentifier, int timeout = 1000) override;
void requestDeviceInfo(const QString &deviceId, int timeout = 1000) override;
+ bool isRunning() const override;
void stop(int errorCode) override;
private:
@@ -325,6 +323,7 @@ private:
bool isResponseValid(const SimulatorControl::ResponseData &responseData);
private:
+ qint64 m_pid = -1;
SimulatorControl *simCtl;
LogTailFiles outputLogger;
QList<QFuture<void>> futureList;
@@ -333,35 +332,14 @@ private:
IosToolHandlerPrivate::IosToolHandlerPrivate(const IosDeviceType &devType,
Ios::IosToolHandler *q) :
q(q),
- process(nullptr),
- state(NonStarted),
- devType(devType),
- iBegin(0),
- iEnd(0),
- gdbSocket(-1)
+ m_devType(devType)
{
- killTimer.setSingleShot(true);
}
IosToolHandlerPrivate::~IosToolHandlerPrivate()
{
}
-bool IosToolHandlerPrivate::isRunning()
-{
- return process && (process->state() != QProcess::NotRunning);
-}
-
-void IosToolHandlerPrivate::start(const QString &exe, const QStringList &args)
-{
- Q_ASSERT(process);
- QTC_CHECK(state == NonStarted);
- state = Starting;
- qCDebug(toolHandlerLog) << "running " << exe << args;
- process->start(exe, args);
- state = StartedInferior;
-}
-
// signals
void IosToolHandlerPrivate::isTransferringApp(const QString &bundlePath, const QString &deviceId,
int progress, int maxProgress, const QString &info)
@@ -502,7 +480,7 @@ void IosDeviceToolHandlerPrivate::processXml()
status = Ios::IosToolHandler::Success;
else if (statusStr.compare(QLatin1String("failure"), Qt::CaseInsensitive) == 0)
status = Ios::IosToolHandler::Failure;
- didStartApp(bundlePath, deviceId, status);
+ didStartApp(m_bundlePath, m_deviceId, status);
} else if (elName == QLatin1String("app_transfer")) {
stack.append(ParserState(ParserState::AppTransfer));
QXmlStreamAttributes attributes = outputParser.attributes();
@@ -512,7 +490,7 @@ void IosDeviceToolHandlerPrivate::processXml()
status = Ios::IosToolHandler::Success;
else if (statusStr.compare(QLatin1String("failure"), Qt::CaseInsensitive) == 0)
status = Ios::IosToolHandler::Failure;
- emit didTransferApp(bundlePath, deviceId, status);
+ emit didTransferApp(m_bundlePath, m_deviceId, status);
} else if (elName == QLatin1String("device_info") || elName == QLatin1String("deviceinfo")) {
stack.append(ParserState(ParserState::DeviceInfo));
} else if (elName == QLatin1String("inferior_pid")) {
@@ -524,7 +502,7 @@ void IosDeviceToolHandlerPrivate::processXml()
attributes.value(QLatin1String("gdb_server")).toString().toInt());
Utils::Port qmlServerPort(
attributes.value(QLatin1String("qml_server")).toString().toInt());
- gotServerPorts(bundlePath, deviceId, gdbServerPort, qmlServerPort);
+ gotServerPorts(m_bundlePath, m_deviceId, gdbServerPort, qmlServerPort);
} else {
qCWarning(toolHandlerLog) << "unexpected element " << elName;
}
@@ -540,10 +518,10 @@ void IosDeviceToolHandlerPrivate::processXml()
errorMsg(p.chars);
break;
case ParserState::DeviceId:
- if (deviceId.isEmpty())
- deviceId = p.chars;
+ if (m_deviceId.isEmpty())
+ m_deviceId = p.chars;
else
- QTC_CHECK(deviceId.compare(p.chars, Qt::CaseInsensitive) == 0);
+ QTC_CHECK(m_deviceId.compare(p.chars, Qt::CaseInsensitive) == 0);
break;
case ParserState::Key:
stack.last().key = p.chars;
@@ -552,7 +530,7 @@ void IosDeviceToolHandlerPrivate::processXml()
stack.last().value = p.chars;
break;
case ParserState::Status:
- isTransferringApp(bundlePath, deviceId, p.progress, p.maxProgress, p.chars);
+ isTransferringApp(m_bundlePath, m_deviceId, p.progress, p.maxProgress, p.chars);
break;
case ParserState::QueryResult:
state = XmlEndProcessed;
@@ -571,12 +549,12 @@ void IosDeviceToolHandlerPrivate::processXml()
stack.last().info.insert(p.key, p.value);
break;
case ParserState::DeviceInfo:
- deviceInfo(deviceId, p.info);
+ deviceInfo(m_deviceId, p.info);
break;
case ParserState::Exit:
break;
case ParserState::InferiorPid:
- gotInferiorPid(bundlePath, deviceId, p.chars.toLongLong());
+ gotInferiorPid(m_bundlePath, m_deviceId, p.chars.toLongLong());
break;
case ParserState::ServerPorts:
break;
@@ -615,6 +593,12 @@ void IosDeviceToolHandlerPrivate::processXml()
}
}
+void IosDeviceToolHandlerPrivate::killProcess()
+{
+ if (isRunning())
+ process->kill();
+}
+
void IosDeviceToolHandlerPrivate::subprocessHasData()
{
qCDebug(toolHandlerLog) << "subprocessHasData, state:" << state;
@@ -656,6 +640,8 @@ IosDeviceToolHandlerPrivate::IosDeviceToolHandlerPrivate(const IosDeviceType &de
IosToolHandler *q)
: IosToolHandlerPrivate(devType, q)
{
+ killTimer.setSingleShot(true);
+
auto deleter = [](QProcess *p) {
if (p->state() != QProcess::NotRunning) {
p->kill();
@@ -717,8 +703,8 @@ IosDeviceToolHandlerPrivate::~IosDeviceToolHandlerPrivate()
void IosDeviceToolHandlerPrivate::requestTransferApp(const QString &bundlePath,
const QString &deviceId, int timeout)
{
- this->bundlePath = bundlePath;
- this->deviceId = deviceId;
+ m_bundlePath = bundlePath;
+ m_deviceId = deviceId;
QStringList args;
args << QLatin1String("--id") << deviceId << QLatin1String("--bundle")
<< bundlePath << QLatin1String("--timeout") << QString::number(timeout)
@@ -731,9 +717,9 @@ void IosDeviceToolHandlerPrivate::requestRunApp(const QString &bundlePath,
IosToolHandler::RunKind runType,
const QString &deviceId, int timeout)
{
- this->bundlePath = bundlePath;
- this->deviceId = deviceId;
- this->runKind = runType;
+ m_bundlePath = bundlePath;
+ m_deviceId = deviceId;
+ m_runKind = runType;
QStringList args;
args << QLatin1String("--id") << deviceId << QLatin1String("--bundle")
<< bundlePath << QLatin1String("--timeout") << QString::number(timeout);
@@ -752,14 +738,29 @@ void IosDeviceToolHandlerPrivate::requestRunApp(const QString &bundlePath,
void IosDeviceToolHandlerPrivate::requestDeviceInfo(const QString &deviceId, int timeout)
{
- this->deviceId = deviceId;
+ m_deviceId = deviceId;
QStringList args;
- args << QLatin1String("--id") << deviceId << QLatin1String("--device-info")
+ args << QLatin1String("--id") << m_deviceId << QLatin1String("--device-info")
<< QLatin1String("--timeout") << QString::number(timeout);
op = OpDeviceInfo;
start(IosToolHandler::iosDeviceToolPath(), args);
}
+bool IosDeviceToolHandlerPrivate::isRunning() const
+{
+ return process && (process->state() != QProcess::NotRunning);
+}
+
+void IosDeviceToolHandlerPrivate::start(const QString &exe, const QStringList &args)
+{
+ Q_ASSERT(process);
+ QTC_CHECK(state == NonStarted);
+ state = Starting;
+ qCDebug(toolHandlerLog) << "running " << exe << args;
+ process->start(exe, args);
+ state = StartedInferior;
+}
+
void IosDeviceToolHandlerPrivate::stop(int errorCode)
{
@@ -776,10 +777,10 @@ void IosDeviceToolHandlerPrivate::stop(int errorCode)
qCWarning(toolHandlerLog) << "IosToolHandler::stop() when op was OpNone";
break;
case OpAppTransfer:
- didTransferApp(bundlePath, deviceId, IosToolHandler::Failure);
+ didTransferApp(m_bundlePath, m_deviceId, IosToolHandler::Failure);
break;
case OpAppRun:
- didStartApp(bundlePath, deviceId, IosToolHandler::Failure);
+ didStartApp(m_bundlePath, m_deviceId, IosToolHandler::Failure);
break;
case OpDeviceInfo:
break;
@@ -823,9 +824,9 @@ void IosSimulatorToolHandlerPrivate::requestTransferApp(const QString &appBundle
const QString &deviceIdentifier, int timeout)
{
Q_UNUSED(timeout);
- bundlePath = appBundlePath;
- deviceId = deviceIdentifier;
- isTransferringApp(bundlePath, deviceId, 0, 100, "");
+ m_bundlePath = appBundlePath;
+ m_deviceId = deviceIdentifier;
+ isTransferringApp(m_bundlePath, m_deviceId, 0, 100, "");
auto onSimulatorStart = [this](const SimulatorControl::ResponseData &response) {
if (!isResponseValid(response))
@@ -835,15 +836,15 @@ void IosSimulatorToolHandlerPrivate::requestTransferApp(const QString &appBundle
installAppOnSimulator();
} else {
errorMsg(IosToolHandler::tr("Application install on Simulator failed. Simulator not running."));
- didTransferApp(bundlePath, deviceId, IosToolHandler::Failure);
+ didTransferApp(m_bundlePath, m_deviceId, IosToolHandler::Failure);
emit q->finished(q);
}
};
- if (SimulatorControl::isSimulatorRunning(deviceId))
+ if (SimulatorControl::isSimulatorRunning(m_deviceId))
installAppOnSimulator();
else
- futureList << Utils::onResultReady(simCtl->startSimulator(deviceId), onSimulatorStart);
+ futureList << Utils::onResultReady(simCtl->startSimulator(m_deviceId), onSimulatorStart);
}
void IosSimulatorToolHandlerPrivate::requestRunApp(const QString &appBundlePath,
@@ -853,15 +854,15 @@ void IosSimulatorToolHandlerPrivate::requestRunApp(const QString &appBundlePath,
{
Q_UNUSED(timeout);
Q_UNUSED(deviceIdentifier);
- bundlePath = appBundlePath;
- deviceId = devType.identifier;
- runKind = runType;
+ m_bundlePath = appBundlePath;
+ m_deviceId = m_devType.identifier;
+ m_runKind = runType;
- Utils::FileName appBundle = Utils::FileName::fromString(bundlePath);
+ Utils::FileName appBundle = Utils::FileName::fromString(m_bundlePath);
if (!appBundle.exists()) {
errorMsg(IosToolHandler::tr("Application launch on Simulator failed. Invalid Bundle path %1")
- .arg(bundlePath));
- didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Failure);
+ .arg(m_bundlePath));
+ didStartApp(m_bundlePath, m_deviceId, Ios::IosToolHandler::Failure);
return;
}
@@ -872,14 +873,14 @@ void IosSimulatorToolHandlerPrivate::requestRunApp(const QString &appBundlePath,
launchAppOnSimulator(extraArgs);
} else {
errorMsg(IosToolHandler::tr("Application launch on Simulator failed. Simulator not running."));
- didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Failure);
+ didStartApp(m_bundlePath, m_deviceId, Ios::IosToolHandler::Failure);
}
};
- if (SimulatorControl::isSimulatorRunning(deviceId))
+ if (SimulatorControl::isSimulatorRunning(m_deviceId))
launchAppOnSimulator(extraArgs);
else
- futureList << Utils::onResultReady(simCtl->startSimulator(deviceId), onSimulatorStart);
+ futureList << Utils::onResultReady(simCtl->startSimulator(m_deviceId), onSimulatorStart);
}
void IosSimulatorToolHandlerPrivate::requestDeviceInfo(const QString &deviceId, int timeout)
@@ -888,8 +889,22 @@ void IosSimulatorToolHandlerPrivate::requestDeviceInfo(const QString &deviceId,
Q_UNUSED(deviceId);
}
+bool IosSimulatorToolHandlerPrivate::isRunning() const
+{
+#ifdef Q_OS_UNIX
+ return m_pid > 0 && (kill(m_pid, 0) == 0);
+#elif
+ return false;
+#endif
+}
+
void IosSimulatorToolHandlerPrivate::stop(int errorCode)
{
+#ifdef Q_OS_UNIX
+ if (m_pid > 0)
+ kill(m_pid, SIGKILL);
+#endif
+ m_pid = -1;
foreach (auto f, futureList) {
if (!f.isFinished())
f.cancel();
@@ -906,32 +921,32 @@ void IosSimulatorToolHandlerPrivate::installAppOnSimulator()
return;
if (response.success) {
- isTransferringApp(bundlePath, deviceId, 100, 100, "");
- didTransferApp(bundlePath, deviceId, IosToolHandler::Success);
+ isTransferringApp(m_bundlePath, m_deviceId, 100, 100, "");
+ didTransferApp(m_bundlePath, m_deviceId, IosToolHandler::Success);
} else {
errorMsg(IosToolHandler::tr("Application install on Simulator failed. %1")
.arg(QString::fromLocal8Bit(response.commandOutput)));
- didTransferApp(bundlePath, deviceId, IosToolHandler::Failure);
+ didTransferApp(m_bundlePath, m_deviceId, IosToolHandler::Failure);
}
emit q->finished(q);
};
- isTransferringApp(bundlePath, deviceId, 20, 100, "");
- futureList << Utils::onResultReady(simCtl->installApp(deviceId, Utils::FileName::fromString(bundlePath)),
- onResponseAppInstall);
+ isTransferringApp(m_bundlePath, m_deviceId, 20, 100, "");
+ auto installFuture = simCtl->installApp(m_deviceId, Utils::FileName::fromString(m_bundlePath));
+ futureList << Utils::onResultReady(installFuture, onResponseAppInstall);
}
void IosSimulatorToolHandlerPrivate::launchAppOnSimulator(const QStringList &extraArgs)
{
- const Utils::FileName appBundle = Utils::FileName::fromString(bundlePath);
+ const Utils::FileName appBundle = Utils::FileName::fromString(m_bundlePath);
const QString bundleId = SimulatorControl::bundleIdentifier(appBundle);
- const bool debugRun = runKind == IosToolHandler::DebugRun;
+ const bool debugRun = m_runKind == IosToolHandler::DebugRun;
bool captureConsole = IosConfigurations::xcodeVersion() >= QVersionNumber(8);
std::shared_ptr<QTemporaryFile> stdoutFile;
std::shared_ptr<QTemporaryFile> stderrFile;
if (captureConsole) {
- const QString fileTemplate = CONSOLE_PATH_TEMPLATE.arg(deviceId).arg(bundleId);
+ const QString fileTemplate = CONSOLE_PATH_TEMPLATE.arg(m_deviceId).arg(bundleId);
stdoutFile.reset(new QTemporaryFile(fileTemplate + ".stdout"));
stderrFile.reset(new QTemporaryFile(fileTemplate + ".stderr"));
@@ -963,24 +978,26 @@ void IosSimulatorToolHandlerPrivate::launchAppOnSimulator(const QStringList &ext
if (!isResponseValid(response))
return;
if (response.success) {
- gotInferiorPid(bundlePath, deviceId, response.pID);
- didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Success);
+ m_pid = response.pID;
+ gotInferiorPid(m_bundlePath, m_deviceId, response.pID);
+ didStartApp(m_bundlePath, m_deviceId, Ios::IosToolHandler::Success);
// Start monitoring app's life signs.
futureList << Utils::runAsync(monitorPid, response.pID);
if (captureConsole)
futureList << Utils::runAsync(&LogTailFiles::exec, &outputLogger, stdoutFile,
stderrFile);
} else {
+ m_pid = -1;
errorMsg(IosToolHandler::tr("Application launch on Simulator failed. %1")
.arg(QString::fromLocal8Bit(response.commandOutput)));
- didStartApp(bundlePath, deviceId, Ios::IosToolHandler::Failure);
+ didStartApp(m_bundlePath, m_deviceId, Ios::IosToolHandler::Failure);
stop(-1);
q->finished(q);
}
};
futureList << Utils::onResultReady(
- simCtl->launchApp(deviceId, bundleId, debugRun, extraArgs,
+ simCtl->launchApp(m_deviceId, bundleId, debugRun, extraArgs,
captureConsole ? stdoutFile->fileName() : QString(),
captureConsole ? stderrFile->fileName() : QString()),
onResponseAppLaunch);
@@ -988,23 +1005,17 @@ void IosSimulatorToolHandlerPrivate::launchAppOnSimulator(const QStringList &ext
bool IosSimulatorToolHandlerPrivate::isResponseValid(const SimulatorControl::ResponseData &responseData)
{
- if (responseData.simUdid.compare(deviceId) != 0) {
+ if (responseData.simUdid.compare(m_deviceId) != 0) {
errorMsg(IosToolHandler::tr("Invalid simulator response. Device Id mismatch. "
"Device Id = %1 Response Id = %2")
.arg(responseData.simUdid)
- .arg(deviceId));
+ .arg(m_deviceId));
emit q->finished(q);
return false;
}
return true;
}
-void IosToolHandlerPrivate::killProcess()
-{
- if (isRunning())
- process->kill();
-}
-
} // namespace Internal
QString IosToolHandler::iosDeviceToolPath()
@@ -1049,7 +1060,7 @@ void IosToolHandler::requestDeviceInfo(const QString &deviceId, int timeout)
d->requestDeviceInfo(deviceId, timeout);
}
-bool IosToolHandler::isRunning()
+bool IosToolHandler::isRunning() const
{
return d->isRunning();
}
diff --git a/src/plugins/ios/iostoolhandler.h b/src/plugins/ios/iostoolhandler.h
index d2243a932e..5debb3a085 100644
--- a/src/plugins/ios/iostoolhandler.h
+++ b/src/plugins/ios/iostoolhandler.h
@@ -62,7 +62,7 @@ public:
void requestRunApp(const QString &bundlePath, const QStringList &extraArgs, RunKind runType,
const QString &deviceId, int timeout = 1000);
void requestDeviceInfo(const QString &deviceId, int timeout = 1000);
- bool isRunning();
+ bool isRunning() const;
void stop();
signals:
@@ -84,9 +84,6 @@ signals:
void toolExited(Ios::IosToolHandler *handler, int code);
void finished(Ios::IosToolHandler *handler);
-protected:
- void killProcess();
-
private:
friend class Ios::Internal::IosToolHandlerPrivate;
Ios::Internal::IosToolHandlerPrivate *d;