ProjectExplorer: Introduce generic application runner.

This class aims to be a flexible worker class for SSH-based
run controls. It supersedes AbstractRemoteLinuxApplicationRunner
as well as all of its derived classes, while having no
RemoteLinux dependencies itself.

Change-Id: If24f03a32126b36fc3d0b253a1615ad0af5f2b46
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
Christian Kandeler
2012-07-26 09:02:34 +02:00
committed by hjk
parent 93756975e1
commit 1d85d8e706
40 changed files with 1063 additions and 1753 deletions

View File

@@ -45,6 +45,7 @@
#include <qt4projectmanager/qt-s60/s60devicedebugruncontrol.h>
#include <qt4projectmanager/qt-s60/s60devicerunconfiguration.h>
#include <qmldebug/qmloutputparser.h>
#include <remotelinux/remotelinuxrunconfiguration.h>
#include <QMainWindow>
#include <QMessageBox>
@@ -370,6 +371,7 @@ void QmlProfilerEngine::profilerStateChanged()
case QmlProfilerStateManager::Idle : {
// When all the profiling is done, delete the profiler runner
// (a new one will be created at start)
d->m_noDebugOutputTimer.stop();
if (d->m_runner) {
delete d->m_runner;
d->m_runner = 0;

View File

@@ -27,15 +27,18 @@
**
**
**************************************************************************/
#include "remotelinuxqmlprofilerrunner.h"
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/devicesupport/deviceapplicationrunner.h>
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
#include <projectexplorer/profileinformation.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <remotelinux/remotelinuxapplicationrunner.h>
#include <projectexplorer/target.h>
#include <remotelinux/remotelinuxrunconfiguration.h>
#include <remotelinux/remotelinuxutils.h>
#include <utils/portlist.h>
#include <utils/qtcassert.h>
using namespace ExtensionSystem;
using namespace ProjectExplorer;
using namespace QmlProfiler::Internal;
using namespace RemoteLinux;
@@ -43,55 +46,43 @@ using namespace RemoteLinux;
RemoteLinuxQmlProfilerRunner::RemoteLinuxQmlProfilerRunner(
RemoteLinuxRunConfiguration *runConfiguration, QObject *parent)
: AbstractQmlProfilerRunner(parent)
, m_portsGatherer(new DeviceUsedPortsGatherer(this))
, m_runner(new DeviceApplicationRunner(this))
, m_device(DeviceProfileInformation::device(runConfiguration->target()->profile()))
, m_remoteExecutable(runConfiguration->remoteExecutableFilePath())
, m_arguments(runConfiguration->arguments())
, m_commandPrefix(runConfiguration->commandPrefix())
, m_port(0)
, m_runControl(0)
{
// find run control factory
IRunControlFactory *runControlFactory = 0;
QList<IRunControlFactory*> runControlFactories
= PluginManager::getObjects<IRunControlFactory>();
foreach (IRunControlFactory *factory, runControlFactories) {
if (factory->canRun(runConfiguration, NormalRunMode)) {
runControlFactory = factory;
break;
}
}
QTC_ASSERT(runControlFactory, return);
// create run control
RunControl *runControl = runControlFactory->create(runConfiguration, NormalRunMode);
m_runControl = qobject_cast<AbstractRemoteLinuxRunControl*>(runControl);
QTC_ASSERT(m_runControl, return);
connect(runner(), SIGNAL(readyForExecution()), this, SLOT(getPorts()));
connect(runner(), SIGNAL(error(QString)), this, SLOT(handleError(QString)));
connect(runner(), SIGNAL(remoteErrorOutput(QByteArray)), this, SLOT(handleStdErr(QByteArray)));
connect(runner(), SIGNAL(remoteOutput(QByteArray)), this, SLOT(handleStdOut(QByteArray)));
connect(runner(), SIGNAL(remoteProcessStarted()), this, SLOT(handleRemoteProcessStarted()));
connect(runner(), SIGNAL(remoteProcessFinished(qint64)),
this, SLOT(handleRemoteProcessFinished(qint64)));
connect(runner(), SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
connect(m_runner, SIGNAL(reportError(QString)), this, SLOT(handleError(QString)));
connect(m_runner, SIGNAL(remoteStderr(QByteArray)), this, SLOT(handleStdErr(QByteArray)));
connect(m_runner, SIGNAL(remoteStdout(QByteArray)), this, SLOT(handleStdOut(QByteArray)));
connect(m_runner, SIGNAL(finished(bool)), SLOT(handleRemoteProcessFinished(bool)));
connect(m_runner, SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
connect(m_portsGatherer, SIGNAL(error(QString)), SLOT(handlePortsGathererError(QString)));
connect(m_portsGatherer, SIGNAL(portListReady()), SLOT(handlePortListReady()));
}
RemoteLinuxQmlProfilerRunner::~RemoteLinuxQmlProfilerRunner()
{
delete m_runControl;
stop();
}
void RemoteLinuxQmlProfilerRunner::start()
{
QTC_ASSERT(runner(), return);
runner()->start();
QTC_ASSERT(m_port == 0, return);
m_portsGatherer->start(m_device);
emit started();
}
void RemoteLinuxQmlProfilerRunner::stop()
{
QTC_ASSERT(runner(), return);
runner()->stop();
if (m_port == 0)
m_portsGatherer->stop();
else
m_runner->stop(RemoteLinuxUtils::killApplicationCommandLine(m_remoteExecutable).toUtf8());
m_port = 0;
}
quint16 RemoteLinuxQmlProfilerRunner::debugPort() const
@@ -99,26 +90,37 @@ quint16 RemoteLinuxQmlProfilerRunner::debugPort() const
return m_port;
}
void RemoteLinuxQmlProfilerRunner::handlePortsGathererError(const QString &message)
{
emit appendMessage(tr("Gathering ports failed: %1").arg(message), Utils::ErrorMessageFormat);
m_port = 0;
emit stopped();
}
void RemoteLinuxQmlProfilerRunner::handlePortListReady()
{
getPorts();
}
void RemoteLinuxQmlProfilerRunner::getPorts()
{
QTC_ASSERT(runner(), return);
m_port = runner()->freePorts()->getNext();
if (m_port == 0) {
Utils::PortList portList = m_device->freePorts();
m_port = m_portsGatherer->getNextFreePort(&portList);
if (m_port == -1) {
emit appendMessage(tr("Not enough free ports on device for analyzing.\n"),
Utils::ErrorMessageFormat);
runner()->stop();
m_port = 0;
emit stopped();
} else {
emit appendMessage(tr("Starting remote process ...\n"), Utils::NormalMessageFormat);
QString arguments = runner()->arguments();
QString arguments = m_arguments;
if (!arguments.isEmpty())
arguments.append(QLatin1Char(' '));
arguments.append(QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_port));
runner()->startExecution(QString::fromLatin1("%1 %2 %3")
.arg(runner()->commandPrefix())
.arg(runner()->remoteExecutable())
.arg(arguments).toUtf8());
const QString commandLine = QString::fromLatin1("%1 %2 %3")
.arg(m_commandPrefix, m_remoteExecutable, arguments);
m_runner->start(m_device, commandLine.toUtf8());
}
}
@@ -137,18 +139,11 @@ void RemoteLinuxQmlProfilerRunner::handleStdOut(const QByteArray &msg)
emit appendMessage(QString::fromUtf8(msg), Utils::StdOutFormat);
}
void RemoteLinuxQmlProfilerRunner::handleRemoteProcessStarted()
void RemoteLinuxQmlProfilerRunner::handleRemoteProcessFinished(bool success)
{
emit started();
}
void RemoteLinuxQmlProfilerRunner::handleRemoteProcessFinished(qint64 exitCode)
{
if (exitCode != AbstractRemoteLinuxApplicationRunner::InvalidExitCode) {
appendMessage(tr("Finished running remote process. Exit code was %1.\n")
.arg(exitCode), Utils::NormalMessageFormat);
}
if (!success)
appendMessage(tr("Failure running remote process."), Utils::NormalMessageFormat);
m_port = 0;
emit stopped();
}
@@ -156,11 +151,3 @@ void RemoteLinuxQmlProfilerRunner::handleProgressReport(const QString &progressS
{
appendMessage(progressString + QLatin1Char('\n'), Utils::NormalMessageFormat);
}
AbstractRemoteLinuxApplicationRunner *RemoteLinuxQmlProfilerRunner::runner() const
{
if (!m_runControl)
return 0;
return m_runControl->runner();
}

View File

@@ -32,8 +32,16 @@
#define REMOTELINUXQMLPROFILERRUNNER_H
#include "abstractqmlprofilerrunner.h"
#include <remotelinux/remotelinuxrunconfiguration.h>
#include <remotelinux/remotelinuxruncontrol.h>
#include <projectexplorer/devicesupport/idevice.h>
#include <QString>
namespace ProjectExplorer {
class DeviceApplicationRunner;
class DeviceUsedPortsGatherer;
}
namespace RemoteLinux { class RemoteLinuxRunConfiguration; }
namespace QmlProfiler {
namespace Internal {
@@ -54,19 +62,24 @@ public:
virtual quint16 debugPort() const;
private slots:
void getPorts();
void handleError(const QString &msg);
void handleStdErr(const QByteArray &msg);
void handleStdOut(const QByteArray &msg);
void handleRemoteProcessStarted();
void handleRemoteProcessFinished(qint64);
void handleRemoteProcessFinished(bool success);
void handleProgressReport(const QString &progressString);
void handlePortsGathererError(const QString &message);
void handlePortListReady();
private:
RemoteLinux::AbstractRemoteLinuxApplicationRunner *runner() const;
void getPorts();
quint16 m_port;
RemoteLinux::AbstractRemoteLinuxRunControl *m_runControl;
ProjectExplorer::DeviceUsedPortsGatherer * const m_portsGatherer;
ProjectExplorer::DeviceApplicationRunner * const m_runner;
const ProjectExplorer::IDevice::ConstPtr m_device;
const QString m_remoteExecutable;
const QString m_arguments;
const QString m_commandPrefix;
int m_port;
};
} // namespace Internal