summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/madde/madde.pro12
-rw-r--r--src/plugins/madde/madde.qbs10
-rw-r--r--src/plugins/madde/maemoapplicationrunnerhelperactions.cpp148
-rw-r--r--src/plugins/madde/maemoapplicationrunnerhelperactions.h (renamed from src/plugins/madde/maemosshrunner.h)62
-rw-r--r--src/plugins/madde/maemodebugsupport.cpp54
-rw-r--r--src/plugins/madde/maemodebugsupport.h56
-rw-r--r--src/plugins/madde/maemoremotemounter.h2
-rw-r--r--src/plugins/madde/maemorunconfiguration.cpp26
-rw-r--r--src/plugins/madde/maemorunconfiguration.h2
-rw-r--r--src/plugins/madde/maemoruncontrol.cpp66
-rw-r--r--src/plugins/madde/maemoruncontrol.h64
-rw-r--r--src/plugins/madde/maemorunfactories.cpp22
-rw-r--r--src/plugins/madde/maemosshrunner.cpp215
-rw-r--r--src/plugins/projectexplorer/devicesupport/deviceapplicationrunner.cpp339
-rw-r--r--src/plugins/projectexplorer/devicesupport/deviceapplicationrunner.h104
-rw-r--r--src/plugins/projectexplorer/projectexplorer.pro6
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qbs4
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerengine.cpp2
-rw-r--r--src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp125
-rw-r--r--src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.h29
-rw-r--r--src/plugins/qnx/qnx.pro2
-rw-r--r--src/plugins/qnx/qnxapplicationrunner.cpp85
-rw-r--r--src/plugins/qnx/qnxapplicationrunner.h69
-rw-r--r--src/plugins/qnx/qnxdebugsupport.cpp66
-rw-r--r--src/plugins/qnx/qnxdebugsupport.h27
-rw-r--r--src/plugins/qnx/qnxruncontrol.cpp17
-rw-r--r--src/plugins/qnx/qnxruncontrol.h9
-rw-r--r--src/plugins/qnx/qnxutils.cpp8
-rw-r--r--src/plugins/qnx/qnxutils.h1
-rw-r--r--src/plugins/remotelinux/remotelinux.pro2
-rw-r--r--src/plugins/remotelinux/remotelinux.qbs2
-rw-r--r--src/plugins/remotelinux/remotelinuxapplicationrunner.cpp508
-rw-r--r--src/plugins/remotelinux/remotelinuxapplicationrunner.h145
-rw-r--r--src/plugins/remotelinux/remotelinuxdebugsupport.cpp207
-rw-r--r--src/plugins/remotelinux/remotelinuxdebugsupport.h44
-rw-r--r--src/plugins/remotelinux/remotelinuxruncontrol.cpp121
-rw-r--r--src/plugins/remotelinux/remotelinuxruncontrol.h38
-rw-r--r--src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp6
-rw-r--r--src/plugins/remotelinux/remotelinuxutils.cpp9
-rw-r--r--src/plugins/remotelinux/remotelinuxutils.h2
40 files changed, 1013 insertions, 1703 deletions
diff --git a/src/plugins/madde/madde.pro b/src/plugins/madde/madde.pro
index f545b98ac9..178e2f3e4b 100644
--- a/src/plugins/madde/madde.pro
+++ b/src/plugins/madde/madde.pro
@@ -11,7 +11,6 @@ HEADERS += \
debianmanager.h \
maemoconstants.h \
maemorunconfigurationwidget.h \
- maemoruncontrol.h \
maemorunfactories.h \
maemosettingspages.h \
maemopackagecreationstep.h \
@@ -20,8 +19,6 @@ HEADERS += \
maemoqemumanager.h \
maemodeploystepfactory.h \
maemoglobal.h \
- maemosshrunner.h \
- maemodebugsupport.h \
maemoremotemountsmodel.h \
maemomountspecification.h \
maemoremotemounter.h \
@@ -52,13 +49,13 @@ HEADERS += \
maddedevicetester.h \
maddedeviceconfigurationfactory.h \
maddedevice.h \
- rpmmanager.h
+ rpmmanager.h \
+ maemoapplicationrunnerhelperactions.h
SOURCES += \
maddeplugin.cpp \
debianmanager.cpp \
maemorunconfigurationwidget.cpp \
- maemoruncontrol.cpp \
maemorunfactories.cpp \
maemosettingspages.cpp \
maemopackagecreationstep.cpp \
@@ -67,8 +64,6 @@ SOURCES += \
maemoqemumanager.cpp \
maemodeploystepfactory.cpp \
maemoglobal.cpp \
- maemosshrunner.cpp \
- maemodebugsupport.cpp \
maemoremotemountsmodel.cpp \
maemomountspecification.cpp \
maemoremotemounter.cpp \
@@ -98,7 +93,8 @@ SOURCES += \
maddedevicetester.cpp \
maemorunconfiguration.cpp \
maddedevice.cpp \
- rpmmanager.cpp
+ rpmmanager.cpp \
+ maemoapplicationrunnerhelperactions.cpp
FORMS += \
maemopackagecreationwidget.ui \
diff --git a/src/plugins/madde/madde.qbs b/src/plugins/madde/madde.qbs
index 4bf5ad8c0d..7cac61e399 100644
--- a/src/plugins/madde/madde.qbs
+++ b/src/plugins/madde/madde.qbs
@@ -31,8 +31,6 @@ QtcPlugin {
"maddeuploadandinstallpackagesteps.cpp",
"maddeuploadandinstallpackagesteps.h",
"maemoconstants.h",
- "maemodebugsupport.cpp",
- "maemodebugsupport.h",
"maemodeploybymountsteps.cpp",
"maemodeploybymountsteps.h",
"maemodeployconfigurationwidget.cpp",
@@ -108,14 +106,10 @@ QtcPlugin {
"maemorunconfiguration.h",
"maemorunconfigurationwidget.cpp",
"maemorunconfigurationwidget.h",
- "maemoruncontrol.cpp",
- "maemoruncontrol.h",
"maemorunfactories.cpp",
"maemorunfactories.h",
"maemosettingspages.cpp",
"maemosettingspages.h",
- "maemosshrunner.cpp",
- "maemosshrunner.h",
"qt-maemo.qrc",
"qt4maemodeployconfiguration.cpp",
"qt4maemodeployconfiguration.h",
@@ -124,6 +118,8 @@ QtcPlugin {
"debianmanager.h",
"debianmanager.cpp",
"rpmmanager.h",
- "rpmmanager.cpp"
+ "rpmmanager.cpp",
+ "maemoapplicationrunnerhelperactions.h",
+ "maemoapplicationrunnerhelperactions.cpp"
]
}
diff --git a/src/plugins/madde/maemoapplicationrunnerhelperactions.cpp b/src/plugins/madde/maemoapplicationrunnerhelperactions.cpp
new file mode 100644
index 0000000000..2f82e7a545
--- /dev/null
+++ b/src/plugins/madde/maemoapplicationrunnerhelperactions.cpp
@@ -0,0 +1,148 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+#include "maemoapplicationrunnerhelperactions.h"
+
+#include "maemomountspecification.h"
+#include "maemoremotemounter.h"
+
+#include <utils/qtcassert.h>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace Madde {
+namespace Internal {
+
+MaemoPreRunAction::MaemoPreRunAction(const IDevice::ConstPtr &device, const FileName &maddeRoot,
+ const QList<MaemoMountSpecification> &mountSpecs, QObject *parent)
+ : DeviceApplicationHelperAction(parent), m_mounter(new MaemoRemoteMounter(this))
+{
+ m_mounter->setParameters(device, maddeRoot);
+ foreach (const MaemoMountSpecification &m, mountSpecs)
+ m_mounter->addMountSpecification(m, false);
+}
+
+void MaemoPreRunAction::handleMounted()
+{
+ QTC_ASSERT(m_isRunning, return);
+
+ setFinished(true);
+}
+
+void MaemoPreRunAction::handleError(const QString &message)
+{
+ if (!m_isRunning)
+ return;
+
+ emit reportError(message);
+ setFinished(false);
+}
+
+void MaemoPreRunAction::start()
+{
+ QTC_ASSERT(!m_isRunning, return);
+
+ connect(m_mounter, SIGNAL(debugOutput(QString)), SIGNAL(reportProgress(QString)));
+ connect(m_mounter, SIGNAL(reportProgress(QString)), SIGNAL(reportProgress(QString)));
+ connect(m_mounter, SIGNAL(mounted()), SLOT(handleMounted()));
+ connect(m_mounter, SIGNAL(error(QString)), SLOT(handleError(QString)));
+ m_isRunning = true;
+ m_mounter->mount();
+}
+
+void MaemoPreRunAction::stop()
+{
+ QTC_ASSERT(m_isRunning, return);
+
+ m_mounter->stop();
+ setFinished(false);
+}
+
+void MaemoPreRunAction::setFinished(bool success)
+{
+ QTC_ASSERT(m_isRunning, return);
+
+ m_mounter->disconnect(this);
+ m_isRunning = false;
+ emit finished(success);
+}
+
+MaemoPostRunAction::MaemoPostRunAction(MaemoRemoteMounter *mounter, QObject *parent)
+ : DeviceApplicationHelperAction(parent), m_mounter(mounter)
+{
+}
+
+void MaemoPostRunAction::handleUnmounted()
+{
+ QTC_ASSERT(m_isRunning, return);
+
+ setFinished(true);
+}
+
+void MaemoPostRunAction::handleError(const QString &message)
+{
+ if (!m_isRunning)
+ return;
+
+ emit reportError(message);
+ setFinished(false);
+}
+
+void MaemoPostRunAction::start()
+{
+ QTC_ASSERT(!m_isRunning, return);
+
+ connect(m_mounter, SIGNAL(debugOutput(QString)), SIGNAL(reportProgress(QString)));
+ connect(m_mounter, SIGNAL(reportProgress(QString)), SIGNAL(reportProgress(QString)));
+ connect(m_mounter, SIGNAL(unmounted()), SLOT(handleUnmounted()));
+ connect(m_mounter, SIGNAL(error(QString)), SLOT(handleError(QString)));
+ m_isRunning = true;
+ m_mounter->unmount();
+}
+
+void MaemoPostRunAction::stop()
+{
+ QTC_ASSERT(m_isRunning, return);
+
+ m_mounter->stop();
+ setFinished(false);
+}
+
+void MaemoPostRunAction::setFinished(bool success)
+{
+ QTC_ASSERT(m_isRunning, return);
+
+ m_mounter->disconnect(this);
+ m_isRunning = false;
+ emit finished(success);
+}
+
+} // namespace Internal
+} // namespace Madde
diff --git a/src/plugins/madde/maemosshrunner.h b/src/plugins/madde/maemoapplicationrunnerhelperactions.h
index 6e9bd37d22..532ad9ac4b 100644
--- a/src/plugins/madde/maemosshrunner.h
+++ b/src/plugins/madde/maemoapplicationrunnerhelperactions.h
@@ -6,6 +6,7 @@
**
** Contact: http://www.qt-project.org/
**
+**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
@@ -26,54 +27,65 @@
**
**
**************************************************************************/
+#ifndef MAEMOAPPLICATIONRUNNERHELPERACTIONS_H
+#define MAEMOAPPLICATIONRUNNERHELPERACTIONS_H
-#ifndef MAEMOSSHRUNNER_H
-#define MAEMOSSHRUNNER_H
+#include <projectexplorer/devicesupport/deviceapplicationrunner.h>
-#include "maemomountspecification.h"
+#include <QList>
-#include <remotelinux/remotelinuxapplicationrunner.h>
+namespace Utils { class FileName; }
namespace Madde {
namespace Internal {
+class MaemoMountSpecification;
class MaemoRemoteMounter;
-class MaemoRunConfiguration;
-class MaemoSshRunner : public RemoteLinux::AbstractRemoteLinuxApplicationRunner
+class MaemoPreRunAction : public ProjectExplorer::DeviceApplicationHelperAction
{
Q_OBJECT
-
public:
- MaemoSshRunner(QObject *parent, MaemoRunConfiguration *runConfig);
+ MaemoPreRunAction(const ProjectExplorer::IDevice::ConstPtr &device,
+ const Utils::FileName &maddeRoot, const QList<MaemoMountSpecification> &mountSpecs,
+ QObject *parent = 0);
-signals:
- void mountDebugOutput(const QString &output);
+ MaemoRemoteMounter *mounter() const { return m_mounter; }
private slots:
void handleMounted();
- void handleUnmounted();
- void handleMounterError(const QString &errorMsg);
+ void handleError(const QString &message);
private:
- enum MountState { InactiveMountState, InitialUnmounting, Mounting, Mounted, PostRunUnmounting };
+ void start();
+ void stop();
+
+ void setFinished(bool success);
- bool canRun(QString &whyNot) const;
- void doDeviceSetup();
- void doAdditionalInitialCleanup();
- void doAdditionalInitializations();
- void doPostRunCleanup();
- void doAdditionalConnectionErrorHandling();
+ MaemoRemoteMounter * const m_mounter;
+ bool m_isRunning;
+};
+
+class MaemoPostRunAction : public ProjectExplorer::DeviceApplicationHelperAction
+{
+ Q_OBJECT
+public:
+ MaemoPostRunAction(MaemoRemoteMounter *mounter, QObject *parent = 0);
+
+private slots:
+ void handleUnmounted();
+ void handleError(const QString &message);
+
+private:
+ void start();
+ void stop();
- void mount();
- void unmount();
+ void setFinished(bool success);
MaemoRemoteMounter * const m_mounter;
- QList<MaemoMountSpecification> m_mountSpecs;
- MountState m_mountState;
- int m_qtId;
+ bool m_isRunning;
};
} // namespace Internal
} // namespace Madde
-#endif // MAEMOSSHRUNNER_H
+#endif // MAEMOAPPLICATIONRUNNERHELPERACTIONS_H
diff --git a/src/plugins/madde/maemodebugsupport.cpp b/src/plugins/madde/maemodebugsupport.cpp
deleted file mode 100644
index 7ff522f069..0000000000
--- a/src/plugins/madde/maemodebugsupport.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: http://www.qt-project.org/
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**************************************************************************/
-#include "maemodebugsupport.h"
-
-#include "maemorunconfiguration.h"
-#include "maemosshrunner.h"
-
-#include <remotelinux/linuxdeviceconfiguration.h>
-
-using namespace RemoteLinux;
-
-namespace Madde {
-namespace Internal {
-
-MaemoDebugSupport::MaemoDebugSupport(MaemoRunConfiguration *runConfig, Debugger::DebuggerEngine *engine)
- : AbstractRemoteLinuxDebugSupport(runConfig, engine),
- m_runner(new MaemoSshRunner(this, runConfig))
-{
-}
-
-MaemoDebugSupport::~MaemoDebugSupport()
-{
-}
-
-AbstractRemoteLinuxApplicationRunner *MaemoDebugSupport::runner() const { return m_runner; }
-
-} // namespace Internal
-} // namespace Madde
diff --git a/src/plugins/madde/maemodebugsupport.h b/src/plugins/madde/maemodebugsupport.h
deleted file mode 100644
index 0aab12532a..0000000000
--- a/src/plugins/madde/maemodebugsupport.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: http://www.qt-project.org/
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**************************************************************************/
-
-#ifndef MAEMODEBUGSUPPORT_H
-#define MAEMODEBUGSUPPORT_H
-
-#include <remotelinux/remotelinuxdebugsupport.h>
-
-namespace Madde {
-namespace Internal {
-class MaemoRunConfiguration;
-class MaemoSshRunner;
-
-class MaemoDebugSupport : public RemoteLinux::AbstractRemoteLinuxDebugSupport
-{
- Q_OBJECT
-public:
- MaemoDebugSupport(MaemoRunConfiguration *runConfig, Debugger::DebuggerEngine *engine);
- ~MaemoDebugSupport();
-
-private:
- RemoteLinux::AbstractRemoteLinuxApplicationRunner *runner() const;
-
- MaemoSshRunner * const m_runner;
-};
-
-} // namespace Internal
-} // namespace Madde
-
-#endif // MAEMODEBUGSUPPORT_H
diff --git a/src/plugins/madde/maemoremotemounter.h b/src/plugins/madde/maemoremotemounter.h
index dcd2e39eb3..0814e84670 100644
--- a/src/plugins/madde/maemoremotemounter.h
+++ b/src/plugins/madde/maemoremotemounter.h
@@ -59,7 +59,7 @@ public:
~MaemoRemoteMounter();
void setParameters(const ProjectExplorer::IDevice::ConstPtr &devConf,
- const Utils::FileName &fileName);
+ const Utils::FileName &maddeRoot);
void addMountSpecification(const MaemoMountSpecification &mountSpec,
bool mountAsRoot);
bool hasValidMountSpecifications() const;
diff --git a/src/plugins/madde/maemorunconfiguration.cpp b/src/plugins/madde/maemorunconfiguration.cpp
index 6bfbd25748..32ce32763b 100644
--- a/src/plugins/madde/maemorunconfiguration.cpp
+++ b/src/plugins/madde/maemorunconfiguration.cpp
@@ -135,32 +135,6 @@ Utils::PortList MaemoRunConfiguration::freePorts() const
return MaemoGlobal::freePorts(target()->profile());
}
-QString MaemoRunConfiguration::localDirToMountForRemoteGdb() const
-{
- const QString projectDir
- = QDir::fromNativeSeparators(QDir::cleanPath(activeBuildConfiguration()
- ->target()->project()->projectDirectory()));
- const QString execDir
- = QDir::fromNativeSeparators(QFileInfo(localExecutableFilePath()).path());
- const int length = qMin(projectDir.length(), execDir.length());
- int lastSeparatorPos = 0;
- for (int i = 0; i < length; ++i) {
- if (projectDir.at(i) != execDir.at(i))
- return projectDir.left(lastSeparatorPos);
- if (projectDir.at(i) == QLatin1Char('/'))
- lastSeparatorPos = i;
- }
- return projectDir.length() == execDir.length()
- ? projectDir : projectDir.left(lastSeparatorPos);
-}
-
-QString MaemoRunConfiguration::remoteProjectSourcesMountPoint() const
-{
- return MaemoGlobal::homeDirOnDevice(DeviceProfileInformation::device(target()->profile())->sshParameters().userName)
- + QLatin1String("/gdbSourcesDir_")
- + QFileInfo(localExecutableFilePath()).fileName();
-}
-
bool MaemoRunConfiguration::hasEnoughFreePorts(RunMode mode) const
{
const int freePortCount = freePorts().count();
diff --git a/src/plugins/madde/maemorunconfiguration.h b/src/plugins/madde/maemorunconfiguration.h
index dacc187cf1..b816f6682d 100644
--- a/src/plugins/madde/maemorunconfiguration.h
+++ b/src/plugins/madde/maemorunconfiguration.h
@@ -53,8 +53,6 @@ public:
Internal::MaemoRemoteMountsModel *remoteMounts() const { return m_remoteMounts; }
bool hasEnoughFreePorts(ProjectExplorer::RunMode mode) const;
- QString localDirToMountForRemoteGdb() const;
- QString remoteProjectSourcesMountPoint() const;
signals:
void remoteMountsChanged();
diff --git a/src/plugins/madde/maemoruncontrol.cpp b/src/plugins/madde/maemoruncontrol.cpp
deleted file mode 100644
index 74d242bc29..0000000000
--- a/src/plugins/madde/maemoruncontrol.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: http://www.qt-project.org/
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**************************************************************************/
-
-#include "maemoruncontrol.h"
-
-#include "maemoglobal.h"
-#include "maemorunconfiguration.h"
-#include "maemosshrunner.h"
-
-namespace Madde {
-namespace Internal {
-
-using namespace RemoteLinux;
-using ProjectExplorer::RunConfiguration;
-
-MaemoRunControl::MaemoRunControl(RunConfiguration *rc)
- : AbstractRemoteLinuxRunControl(rc)
- , m_runner(new MaemoSshRunner(this, qobject_cast<MaemoRunConfiguration *>(rc)))
-{
-}
-
-MaemoRunControl::~MaemoRunControl()
-{
-}
-
-void MaemoRunControl::start()
-{
- AbstractRemoteLinuxRunControl::start();
- connect(m_runner, SIGNAL(mountDebugOutput(QString)), SLOT(handleMountDebugOutput(QString)));
-}
-
-void MaemoRunControl::handleMountDebugOutput(const QString &output)
-{
- appendMessage(output, Utils::StdErrFormatSameLine);
-}
-
-AbstractRemoteLinuxApplicationRunner *MaemoRunControl::runner() const { return m_runner; }
-
-} // namespace Internal
-} // namespace Madde
diff --git a/src/plugins/madde/maemoruncontrol.h b/src/plugins/madde/maemoruncontrol.h
deleted file mode 100644
index 92d9432429..0000000000
--- a/src/plugins/madde/maemoruncontrol.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: http://www.qt-project.org/
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**************************************************************************/
-
-#ifndef MAEMORUNCONTROL_H
-#define MAEMORUNCONTROL_H
-
-#include <remotelinux/remotelinuxruncontrol.h>
-
-namespace RemoteLinux {
-class RemoteLinuxRunConfiguration;
-}
-
-namespace Madde {
-namespace Internal {
-class MaemoSshRunner;
-
-class MaemoRunControl : public RemoteLinux::AbstractRemoteLinuxRunControl
-{
- Q_OBJECT
-public:
- explicit MaemoRunControl(ProjectExplorer::RunConfiguration *runConfig);
- virtual ~MaemoRunControl();
-
- void start();
-
-private slots:
- void handleMountDebugOutput(const QString &output);
-
-private:
- virtual RemoteLinux::AbstractRemoteLinuxApplicationRunner *runner() const;
-
- MaemoSshRunner * const m_runner;
-};
-
-} // namespace Internal
-} // namespace Madde
-
-#endif // MAEMORUNCONTROL_H
diff --git a/src/plugins/madde/maemorunfactories.cpp b/src/plugins/madde/maemorunfactories.cpp
index 022b0d79d9..02b084b96b 100644
--- a/src/plugins/madde/maemorunfactories.cpp
+++ b/src/plugins/madde/maemorunfactories.cpp
@@ -28,11 +28,11 @@
**************************************************************************/
#include "maemorunfactories.h"
+#include "maemoapplicationrunnerhelperactions.h"
#include "maemoconstants.h"
-#include "maemodebugsupport.h"
+#include "maemoglobal.h"
#include "maemoremotemountsmodel.h"
#include "maemorunconfiguration.h"
-#include "maemoruncontrol.h"
#include <debugger/debuggerconstants.h>
#include <debugger/debuggerstartparameters.h>
@@ -44,6 +44,8 @@
#include <qt4projectmanager/qt4nodes.h>
#include <qt4projectmanager/qt4project.h>
#include <qtsupport/customexecutablerunconfiguration.h>
+#include <remotelinux/remotelinuxdebugsupport.h>
+#include <remotelinux/remotelinuxruncontrol.h>
using namespace Debugger;
using namespace ProjectExplorer;
@@ -169,7 +171,6 @@ QList<RunConfiguration *> MaemoRunConfigurationFactory::runConfigurationsForNode
return result;
}
-// #pragma mark -- MaemoRunControlFactory
MaemoRunControlFactory::MaemoRunControlFactory(QObject *parent)
: IRunControlFactory(parent)
@@ -197,14 +198,21 @@ RunControl* MaemoRunControlFactory::create(RunConfiguration *runConfig, RunMode
Q_ASSERT(rc);
if (mode == NormalRunMode)
- return new MaemoRunControl(rc);
+ return new RemoteLinuxRunControl(rc);
- const DebuggerStartParameters params
- = AbstractRemoteLinuxDebugSupport::startParameters(rc);
+ const DebuggerStartParameters params = LinuxDeviceDebugSupport::startParameters(rc);
DebuggerRunControl * const runControl = DebuggerPlugin::createDebugger(params, rc);
if (!runControl)
return 0;
- MaemoDebugSupport *debugSupport = new MaemoDebugSupport(rc, runControl->engine());
+ LinuxDeviceDebugSupport * const debugSupport
+ = new LinuxDeviceDebugSupport(rc, runControl->engine());
+ const Profile * const profile = runConfig->target()->profile();
+ MaemoPreRunAction * const preRunAction = new MaemoPreRunAction(
+ DeviceProfileInformation::device(profile), MaemoGlobal::maddeRoot(profile),
+ rc->remoteMounts()->mountSpecs(), rc);
+ MaemoPostRunAction * const postRunAction = new MaemoPostRunAction(preRunAction->mounter(), rc);
+ debugSupport->setApplicationRunnerPreRunAction(preRunAction);
+ debugSupport->setApplicationRunnerPostRunAction(postRunAction);
connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished()));
return runControl;
}
diff --git a/src/plugins/madde/maemosshrunner.cpp b/src/plugins/madde/maemosshrunner.cpp
deleted file mode 100644
index 260596b551..0000000000
--- a/src/plugins/madde/maemosshrunner.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: http://www.qt-project.org/
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**************************************************************************/
-#include "maemosshrunner.h"
-
-#include "maemoglobal.h"
-#include "maemoqemumanager.h"
-#include "maemoremotemounter.h"
-#include "maemoremotemountsmodel.h"
-#include "maemorunconfiguration.h"
-
-#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/target.h>
-#include <qtsupport/qtprofileinformation.h>
-#include <utils/qtcassert.h>
-#include <ssh/sshconnection.h>
-
-using namespace ProjectExplorer;
-using namespace QSsh;
-using namespace RemoteLinux;
-
-namespace Madde {
-namespace Internal {
-
-MaemoSshRunner::MaemoSshRunner(QObject *parent, MaemoRunConfiguration *runConfig)
- : AbstractRemoteLinuxApplicationRunner(runConfig, parent),
- m_mounter(new MaemoRemoteMounter(this)),
- m_mountSpecs(runConfig->remoteMounts()->mountSpecs()),
- m_mountState(InactiveMountState)
-{
- const BuildConfiguration * const bc = runConfig->target()->activeBuildConfiguration();
- Profile *profile = bc ? bc->target()->profile() : 0;
- m_qtId = QtSupport::QtProfileInformation::qtVersionId(profile);
- m_mounter->setParameters(devConfig(), MaemoGlobal::maddeRoot(profile));
- connect(m_mounter, SIGNAL(mounted()), this, SLOT(handleMounted()));
- connect(m_mounter, SIGNAL(unmounted()), this, SLOT(handleUnmounted()));
- connect(m_mounter, SIGNAL(error(QString)), this,
- SLOT(handleMounterError(QString)));
- connect(m_mounter, SIGNAL(reportProgress(QString)), this,
- SIGNAL(reportProgress(QString)));
- connect(m_mounter, SIGNAL(debugOutput(QString)), this,
- SIGNAL(mountDebugOutput(QString)));
-}
-
-bool MaemoSshRunner::canRun(QString &whyNot) const
-{
- if (!AbstractRemoteLinuxApplicationRunner::canRun(whyNot))
- return false;
-
- if (devConfig()->machineType() == IDevice::Emulator
- && !MaemoQemuManager::instance().qemuIsRunning()) {
- MaemoQemuRuntime rt;
- if (MaemoQemuManager::instance().runtimeForQtVersion(m_qtId, &rt)) {
- MaemoQemuManager::instance().startRuntime();
- whyNot = tr("Qemu was not running. It has now been started up for you, but it will "
- "take a bit of time until it is ready. Please try again then.");
- } else {
- whyNot = tr("You want to run on Qemu, but it is not enabled for this Qt version.");
- }
- return false;
- }
-
- return true;
-}
-
-void MaemoSshRunner::doDeviceSetup()
-{
- QTC_ASSERT(m_mountState == InactiveMountState, return);
-
- handleDeviceSetupDone(true);
-}
-
-void MaemoSshRunner::doAdditionalInitialCleanup()
-{
- QTC_ASSERT(m_mountState == InactiveMountState, return);
-
- m_mounter->resetMountSpecifications();
- for (int i = 0; i < m_mountSpecs.count(); ++i)
- m_mounter->addMountSpecification(m_mountSpecs.at(i), false);
- m_mountState = InitialUnmounting;
- unmount();
-}
-
-void MaemoSshRunner::doAdditionalInitializations()
-{
- mount();
-}
-
-void MaemoSshRunner::doPostRunCleanup()
-{
- QTC_ASSERT(m_mountState == Mounted, return);
-
- m_mountState = PostRunUnmounting;
- unmount();
-}
-
-void MaemoSshRunner::handleUnmounted()
-{
- QTC_ASSERT(m_mountState == InitialUnmounting || m_mountState == PostRunUnmounting, return);
-
- switch (m_mountState) {
- case InitialUnmounting:
- m_mountState = InactiveMountState;
- handleInitialCleanupDone(true);
- break;
- case PostRunUnmounting:
- m_mountState = InactiveMountState;
- handlePostRunCleanupDone();
- break;
- default:
- break;
- }
- m_mountState = InactiveMountState;
-}
-
-void MaemoSshRunner::doAdditionalConnectionErrorHandling()
-{
- m_mountState = InactiveMountState;
-}
-
-void MaemoSshRunner::handleMounted()
-{
- QTC_ASSERT(m_mountState == Mounting, return);
-
- if (m_mountState == Mounting) {
- m_mountState = Mounted;
- handleInitializationsDone(true);
- }
-}
-
-void MaemoSshRunner::handleMounterError(const QString &errorMsg)
-{
- QTC_ASSERT(m_mountState == InitialUnmounting || m_mountState == Mounting
- || m_mountState == PostRunUnmounting, return);
-
- const MountState oldMountState = m_mountState;
- m_mountState = InactiveMountState;
- emit error(errorMsg);
- switch (oldMountState) {
- case InitialUnmounting:
- handleInitialCleanupDone(false);
- break;
- case Mounting:
- handleInitializationsDone(false);
- break;
- case PostRunUnmounting:
- handlePostRunCleanupDone();
- break;
- default:
- break;
- }
-}
-
-void MaemoSshRunner::mount()
-{
- m_mountState = Mounting;
- if (m_mounter->hasValidMountSpecifications()) {
- emit reportProgress(tr("Mounting host directories..."));
- m_mounter->mount();
- } else {
- handleMounted();
- }
-}
-
-void MaemoSshRunner::unmount()
-{
- QTC_ASSERT(m_mountState == InitialUnmounting || m_mountState == PostRunUnmounting, return);
-
- if (m_mounter->hasValidMountSpecifications()) {
- QString message;
- switch (m_mountState) {
- case InitialUnmounting:
- message = tr("Potentially unmounting left-over host directory mounts...");
- break;
- case PostRunUnmounting:
- message = tr("Unmounting host directories...");
- break;
- default:
- break;
- }
- emit reportProgress(message);
- m_mounter->unmount();
- } else {
- handleUnmounted();
- }
-}
-
-} // namespace Internal
-} // namespace Madde
-
diff --git a/src/plugins/projectexplorer/devicesupport/deviceapplicationrunner.cpp b/src/plugins/projectexplorer/devicesupport/deviceapplicationrunner.cpp
new file mode 100644
index 0000000000..0638b9a7ba
--- /dev/null
+++ b/src/plugins/projectexplorer/devicesupport/deviceapplicationrunner.cpp
@@ -0,0 +1,339 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+#include "deviceapplicationrunner.h"
+
+#include <ssh/sshconnection.h>
+#include <ssh/sshconnectionmanager.h>
+#include <ssh/sshremoteprocess.h>
+#include <utils/qtcassert.h>
+
+#include <QTimer>
+
+using namespace QSsh;
+
+namespace ProjectExplorer {
+
+namespace {
+enum State { Inactive, Connecting, PreRun, Run, PostRun };
+} // anonymous namespace
+
+class DeviceApplicationRunner::DeviceApplicationRunnerPrivate
+{
+public:
+ SshConnection *connection;
+ DeviceApplicationHelperAction *preRunAction;
+ DeviceApplicationHelperAction *postRunAction;
+ IDevice::ConstPtr device;
+ SshRemoteProcess::Ptr remoteApp;
+ QTimer stopTimer;
+ QByteArray commandLine;
+ State state;
+ bool stopRequested;
+ bool success;
+};
+
+
+DeviceApplicationHelperAction::DeviceApplicationHelperAction(QObject *parent) : QObject(parent)
+{
+}
+
+DeviceApplicationHelperAction::~DeviceApplicationHelperAction()
+{
+}
+
+
+DeviceApplicationRunner::DeviceApplicationRunner(QObject *parent) :
+ QObject(parent), d(new DeviceApplicationRunnerPrivate)
+{
+ d->preRunAction = 0;
+ d->postRunAction = 0;
+ d->connection = 0;
+ d->state = Inactive;
+
+ d->stopTimer.setSingleShot(true);
+ connect(&d->stopTimer, SIGNAL(timeout()), SLOT(handleStopTimeout()));
+}
+
+DeviceApplicationRunner::~DeviceApplicationRunner()
+{
+ setFinished();
+ delete d;
+}
+
+void DeviceApplicationRunner::start(const IDevice::ConstPtr &device,
+ const QByteArray &commandLine)
+{
+ QTC_ASSERT(d->state == Inactive, return);
+
+ d->device = device;
+ d->commandLine = commandLine;
+ d->stopRequested = false;
+ d->success = true;
+
+ connectToServer();
+}
+
+void DeviceApplicationRunner::stop(const QByteArray &stopCommand)
+{
+ QTC_ASSERT(d->state != Inactive, return);
+
+ if (d->stopRequested)
+ return;
+ d->stopRequested = true;
+ d->success = false;
+ emit reportProgress(tr("User requested stop. Shutting down..."));
+ switch (d->state) {
+ case Connecting:
+ setFinished();
+ break;
+ case PreRun:
+ d->preRunAction->stop();
+ break;
+ case Run:
+ d->stopTimer.start(10000);
+ d->connection->createRemoteProcess(stopCommand)->start();
+ break;
+ case PostRun:
+ d->postRunAction->stop();
+ break;
+ case Inactive:
+ break;
+ }
+}
+
+void DeviceApplicationRunner::setPreRunAction(DeviceApplicationHelperAction *action)
+{
+ addAction(d->preRunAction, action);
+}
+
+void DeviceApplicationRunner::setPostRunAction(DeviceApplicationHelperAction *action)
+{
+ addAction(d->postRunAction, action);
+}
+
+void DeviceApplicationRunner::connectToServer()
+{
+ QTC_CHECK(!d->connection);
+
+ d->state = Connecting;
+
+ if (!d->device) {
+ emit reportError(tr("Cannot run: No device."));
+ setFinished();
+ return;
+ }
+
+ d->connection = SshConnectionManager::instance().acquireConnection(d->device->sshParameters());
+ connect(d->connection, SIGNAL(error(QSsh::SshError)), SLOT(handleConnectionFailure()));
+ if (d->connection->state() == SshConnection::Connected) {
+ handleConnected();
+ } else {
+ emit reportProgress(tr("Connecting to device..."));
+ connect(d->connection, SIGNAL(connected()), SLOT(handleConnected()));
+ if (d->connection->state() == QSsh::SshConnection::Unconnected)
+ d->connection->connectToHost();
+ }
+}
+
+void DeviceApplicationRunner::executePreRunAction()
+{
+ QTC_ASSERT(d->state == Connecting, return);
+
+ d->state = PreRun;
+ if (d->preRunAction)
+ d->preRunAction->start();
+ else
+ runApplication();
+}
+
+void DeviceApplicationRunner::executePostRunAction()
+{
+ QTC_ASSERT(d->state == PreRun || d->state == Run, return);
+
+ d->state = PostRun;
+ if (d->postRunAction)
+ d->postRunAction->start();
+ else
+ setFinished();
+}
+
+void DeviceApplicationRunner::setFinished()
+{
+ if (d->state == Inactive)
+ return;
+
+ if (d->remoteApp) {
+ d->remoteApp->disconnect(this);
+ d->remoteApp->close();
+ d->remoteApp.clear();
+ }
+ if (d->connection) {
+ d->connection->disconnect(this);
+ SshConnectionManager::instance().releaseConnection(d->connection);
+ d->connection = 0;
+ }
+
+ d->state = Inactive;
+ emit finished(d->success);
+}
+
+void DeviceApplicationRunner::handleConnected()
+{
+ QTC_ASSERT(d->state == Connecting, return);
+
+ if (d->stopRequested) {
+ setFinished();
+ return;
+ }
+
+ executePreRunAction();
+}
+
+void DeviceApplicationRunner::handleConnectionFailure()
+{
+ QTC_ASSERT(d->state != Inactive, return);
+
+ emit reportError(tr("SSH connection failed: %1").arg(d->connection->errorString()));
+ d->success = false;
+ switch (d->state) {
+ case Inactive:
+ break; // Can't happen.
+ case Connecting:
+ setFinished();
+ break;
+ case PreRun:
+ d->preRunAction->stop();
+ break;
+ case Run:
+ d->stopTimer.stop();
+ d->remoteApp->disconnect(this);
+ executePostRunAction();
+ break;
+ case PostRun:
+ d->postRunAction->stop();
+ break;
+ }
+}
+
+void DeviceApplicationRunner::handleHelperActionFinished(bool success)
+{
+ switch (d->state) {
+ case Inactive:
+ break;
+ case PreRun:
+ if (success && d->success) {
+ runApplication();
+ } else if (success && !d->success) {
+ executePostRunAction();
+ } else {
+ d->success = false;
+ setFinished();
+ }
+ break;
+ case PostRun:
+ if (!success)
+ d->success = false;
+ setFinished();
+ break;
+ default:
+ QTC_CHECK(false);
+ }
+}
+
+void DeviceApplicationRunner::addAction(DeviceApplicationHelperAction *&target,
+ DeviceApplicationHelperAction *source)
+{
+ QTC_ASSERT(d->state == Inactive, return);
+
+ if (target)
+ disconnect(target, 0, this, 0);
+ target = source;
+ if (target) {
+ connect(target, SIGNAL(finished(bool)), SLOT(handleHelperActionFinished(bool)));
+ connect(target, SIGNAL(reportProgress(QString)), SIGNAL(reportProgress(QString)));
+ connect(target, SIGNAL(reportError(QString)), SIGNAL(reportError(QString)));
+ }
+}
+
+void DeviceApplicationRunner::handleStopTimeout()
+{
+ QTC_ASSERT(d->stopRequested && d->state == Run, return);
+
+ emit reportError(tr("Application did not finish in time, aborting."));
+ d->success = false;
+ setFinished();
+}
+
+void DeviceApplicationRunner::handleApplicationFinished(int exitStatus)
+{
+ QTC_ASSERT(d->state == Run, return);
+
+ d->stopTimer.stop();
+ if (exitStatus == SshRemoteProcess::CrashExit) {
+ emit reportError(tr("Remote application crashed: %1").arg(d->remoteApp->errorString()));
+ d->success = false;
+ } else {
+ const int exitCode = d->remoteApp->exitCode();
+ if (exitCode != 0) {
+ emit reportError(tr("Remote application finished with exit code %1.").arg(exitCode));
+ d->success = false;
+ } else {
+ emit reportProgress(tr("Remote application finished with exit code 0."));
+ }
+ }
+ executePostRunAction();
+}
+
+void DeviceApplicationRunner::handleRemoteStdout()
+{
+ QTC_ASSERT(d->state == Run, return);
+ emit remoteStdout(d->remoteApp->readAllStandardOutput());
+}
+
+void DeviceApplicationRunner::handleRemoteStderr()
+{
+ QTC_ASSERT(d->state == Run, return);
+ emit remoteStderr(d->remoteApp->readAllStandardError());
+}
+
+void DeviceApplicationRunner::runApplication()
+{
+ QTC_ASSERT(d->state == PreRun, return);
+
+ d->state = Run;
+ d->remoteApp = d->connection->createRemoteProcess(d->commandLine);
+ connect(d->remoteApp.data(), SIGNAL(started()), SIGNAL(remoteProcessStarted()));
+ connect(d->remoteApp.data(), SIGNAL(readyReadStandardOutput()), SLOT(handleRemoteStdout()));
+ connect(d->remoteApp.data(), SIGNAL(readyReadStandardError()), SLOT(handleRemoteStderr()));
+ connect(d->remoteApp.data(), SIGNAL(closed(int)), SLOT(handleApplicationFinished(int)));
+ d->remoteApp->start();
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/deviceapplicationrunner.h b/src/plugins/projectexplorer/devicesupport/deviceapplicationrunner.h
new file mode 100644
index 0000000000..2b19f0783c
--- /dev/null
+++ b/src/plugins/projectexplorer/devicesupport/deviceapplicationrunner.h
@@ -0,0 +1,104 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**************************************************************************/
+#ifndef ONDEVICEAPPLICATIONRUNNER_H
+#define ONDEVICEAPPLICATIONRUNNER_H
+
+#include "idevice.h"
+
+#include "../projectexplorer_export.h"
+
+#include <QObject>
+
+namespace ProjectExplorer {
+
+class PROJECTEXPLORER_EXPORT DeviceApplicationHelperAction : public QObject
+{
+ Q_OBJECT
+public:
+ ~DeviceApplicationHelperAction();
+ virtual void start() = 0;
+ virtual void stop() = 0;
+signals:
+ void reportProgress(const QString &progressOutput);
+ void reportError(const QString &errorOutput);
+ void finished(bool success);
+
+protected:
+ DeviceApplicationHelperAction(QObject *parent = 0);
+};
+
+class PROJECTEXPLORER_EXPORT DeviceApplicationRunner : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DeviceApplicationRunner(QObject *parent = 0);
+ virtual ~DeviceApplicationRunner();
+
+ void start(const IDevice::ConstPtr &device, const QByteArray &commandLine);
+ void stop(const QByteArray &stopCommand);
+
+ // Use these if you need to do something before and after the application is run, respectively.
+ // Typically, the post-run action reverts the effects of the pre-run action.
+ // If you only have a pre-run action, you probably want a deploy step instead.
+ void setPreRunAction(DeviceApplicationHelperAction *action);
+ void setPostRunAction(DeviceApplicationHelperAction *action);
+
+signals:
+ void remoteStdout(const QByteArray &output);
+ void remoteStderr(const QByteArray &output);
+ void reportProgress(const QString &progressOutput);
+ void reportError(const QString &errorOutput);
+ void remoteProcessStarted();
+ void finished(bool success);
+
+private slots:
+ void handleConnected();
+ void handleConnectionFailure();
+ void handleHelperActionFinished(bool success);
+ void handleStopTimeout();
+ void handleApplicationFinished(int exitStatus);
+ void handleRemoteStdout();
+ void handleRemoteStderr();
+
+private:
+ void addAction(DeviceApplicationHelperAction *&target, DeviceApplicationHelperAction *source);
+ void connectToServer();
+ void executePreRunAction();
+ void executePostRunAction();
+ void runApplication();
+ void setFinished();
+
+ class DeviceApplicationRunnerPrivate;
+ DeviceApplicationRunnerPrivate * const d;
+};
+
+} // namespace ProjectExplorer
+
+#endif // ONDEVICEAPPLICATIONRUNNER_H
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index cd8a533557..d27b13f22c 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -125,7 +125,8 @@ HEADERS += projectexplorer.h \
devicesupport/deviceprocessesdialog.h \
devicesupport/devicesettingswidget.h \
devicesupport/devicesettingspage.h \
- devicesupport/deviceusedportsgatherer.h
+ devicesupport/deviceusedportsgatherer.h \
+ devicesupport/deviceapplicationrunner.h
SOURCES += projectexplorer.cpp \
abi.cpp \
@@ -227,7 +228,8 @@ SOURCES += projectexplorer.cpp \
devicesupport/deviceprocessesdialog.cpp \
devicesupport/devicesettingswidget.cpp \
devicesupport/devicesettingspage.cpp \
- devicesupport/deviceusedportsgatherer.cpp
+ devicesupport/deviceusedportsgatherer.cpp \
+ devicesupport/deviceapplicationrunner.cpp
FORMS += processstep.ui \
editorsettingspropertiespage.ui \
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index 0e5dbeeae5..10234f3ab5 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -308,7 +308,9 @@ QtcPlugin {
"devicesupport/deviceusedportsgatherer.h",
"devicesupport/idevicewidget.h",
"devicesupport/idevicefactory.cpp",
- "devicesupport/idevicefactory.h"
+ "devicesupport/idevicefactory.h",
+ "devicesupport/deviceapplicationrunner.cpp",
+ "devicesupport/deviceapplicationrunner.h"
]
Group {
diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.cpp b/src/plugins/qmlprofiler/qmlprofilerengine.cpp
index 7149c5a42b..32a667242d 100644
--- a/src/plugins/qmlprofiler/qmlprofilerengine.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerengine.cpp
@@ -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;
diff --git a/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp
index 9c5a3483ff..695e65eaab 100644
--- a/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp
+++ b/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp
@@ -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();
-}
-
diff --git a/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.h b/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.h
index 5f178edc42..6d0a766aff 100644
--- a/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.h
+++ b/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.h
@@ -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
diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro
index af0f672ff4..ed729e954f 100644
--- a/src/plugins/qnx/qnx.pro
+++ b/src/plugins/qnx/qnx.pro
@@ -41,7 +41,6 @@ SOURCES += qnxplugin.cpp \
qnxrunconfiguration.cpp \
qnxruncontrolfactory.cpp \
qnxdebugsupport.cpp \
- qnxapplicationrunner.cpp \
qnxdeploystepfactory.cpp \
qnxdeployconfigurationfactory.cpp \
qnxrunconfigurationfactory.cpp \
@@ -91,7 +90,6 @@ HEADERS += qnxplugin.h\
qnxrunconfiguration.h \
qnxruncontrolfactory.h \
qnxdebugsupport.h \
- qnxapplicationrunner.h \
qnxdeploystepfactory.h \
qnxdeployconfigurationfactory.h \
qnxrunconfigurationfactory.h \
diff --git a/src/plugins/qnx/qnxapplicationrunner.cpp b/src/plugins/qnx/qnxapplicationrunner.cpp
deleted file mode 100644
index 2156f059aa..0000000000
--- a/src/plugins/qnx/qnxapplicationrunner.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (C) 2011 - 2012 Research In Motion
-**
-** Contact: Research In Motion (blackberry-qt@qnx.com)
-** Contact: KDAB (info@kdab.com)
-**
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at info@qt.nokia.com.
-**
-**************************************************************************/
-
-#include "qnxapplicationrunner.h"
-#include "qnxrunconfiguration.h"
-#include "qnxconstants.h"
-
-using namespace Qnx;
-using namespace Qnx::Internal;
-
-QnxApplicationRunner::QnxApplicationRunner(QnxRunConfiguration *runConfig, QObject *parent)
- : RemoteLinux::AbstractRemoteLinuxApplicationRunner(runConfig, parent)
- , m_debugMode(false)
-{
- usedPortsGatherer()->setCommand(QLatin1String(Constants::QNX_PORT_GATHERER_COMMAND));
-}
-
-void QnxApplicationRunner::setDebugMode(bool debugMode)
-{
- m_debugMode = debugMode;
-}
-
-void QnxApplicationRunner::doDeviceSetup()
-{
- handleDeviceSetupDone(true);
-}
-
-void QnxApplicationRunner::doAdditionalInitialCleanup()
-{
- handleInitialCleanupDone(true);
-}
-
-void QnxApplicationRunner::doAdditionalInitializations()
-{
- handleInitializationsDone(true);
-}
-
-void QnxApplicationRunner::doPostRunCleanup()
-{
- handlePostRunCleanupDone();
-}
-
-void QnxApplicationRunner::doAdditionalConnectionErrorHandling()
-{
-}
-
-QString QnxApplicationRunner::killApplicationCommandLine() const
-{
- QString executable = m_debugMode ? QLatin1String(Constants::QNX_DEBUG_EXECUTABLE) : remoteExecutable();
- executable.replace(QLatin1String("/"), QLatin1String("\\/"));
- return QString::fromLatin1("for PID in $(ps -f -o pid,comm | grep %1 | awk '/%1/ {print $1}'); "
- "do "
- "kill $PID; sleep 1; kill -9 $PID; "
- "done").arg(executable);
-}
diff --git a/src/plugins/qnx/qnxapplicationrunner.h b/src/plugins/qnx/qnxapplicationrunner.h
deleted file mode 100644
index bcd861954f..0000000000
--- a/src/plugins/qnx/qnxapplicationrunner.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (C) 2011 - 2012 Research In Motion
-**
-** Contact: Research In Motion (blackberry-qt@qnx.com)
-** Contact: KDAB (info@kdab.com)
-**
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at info@qt.nokia.com.
-**
-**************************************************************************/
-
-#ifndef QNX_INTERNAL_QNXAPPLICATIONRUNNER_H
-#define QNX_INTERNAL_QNXAPPLICATIONRUNNER_H
-
-#include <remotelinux/remotelinuxapplicationrunner.h>
-
-namespace Qnx {
-namespace Internal {
-
-class QnxRunConfiguration;
-
-class QnxApplicationRunner : public RemoteLinux::AbstractRemoteLinuxApplicationRunner
-{
- Q_OBJECT
-public:
- explicit QnxApplicationRunner(QnxRunConfiguration *runConfig,
- QObject *parent = 0);
-
- void setDebugMode(bool debugMode);
-
-protected:
- void doDeviceSetup();
- void doAdditionalInitialCleanup();
- void doAdditionalInitializations();
- void doPostRunCleanup();
- void doAdditionalConnectionErrorHandling();
-
-private:
- QString killApplicationCommandLine() const;
-
- bool m_debugMode;
-};
-
-} // namespace Internal
-} // namespace Qnx
-
-#endif // QNX_INTERNAL_QNXAPPLICATIONRUNNER_H
diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp
index afda2edac5..766a06c9bf 100644
--- a/src/plugins/qnx/qnxdebugsupport.cpp
+++ b/src/plugins/qnx/qnxdebugsupport.cpp
@@ -32,22 +32,46 @@
**************************************************************************/
#include "qnxdebugsupport.h"
-#include "qnxapplicationrunner.h"
#include "qnxconstants.h"
+#include "qnxrunconfiguration.h"
+#include "qnxutils.h"
#include <debugger/debuggerengine.h>
+#include <projectexplorer/devicesupport/deviceapplicationrunner.h>
+#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
+#include <projectexplorer/profileinformation.h>
+#include <projectexplorer/target.h>
+#include <utils/portlist.h>
#include <utils/qtcassert.h>
+using namespace ProjectExplorer;
+using namespace RemoteLinux;
+
+using namespace Qnx;
using namespace Qnx::Internal;
QnxDebugSupport::QnxDebugSupport(QnxRunConfiguration *runConfig, Debugger::DebuggerEngine *engine)
: QObject(engine)
+ , m_executable(QLatin1String(Constants::QNX_DEBUG_EXECUTABLE))
+ , m_commandPrefix(runConfig->commandPrefix())
+ , m_arguments(runConfig->arguments())
+ , m_device(DeviceProfileInformation::device(runConfig->target()->profile()))
, m_engine(engine)
, m_port(-1)
, m_state(Inactive)
{
- m_runner = new QnxApplicationRunner(runConfig, this);
- m_runner->setDebugMode(true);
+ m_runner = new DeviceApplicationRunner(this);
+ m_portsGatherer = new DeviceUsedPortsGatherer(this);
+ m_portsGatherer->setCommand(QLatin1String(Constants::QNX_PORT_GATHERER_COMMAND));
+
+ connect(m_portsGatherer, SIGNAL(error(QString)), SLOT(handleError(QString)));
+ connect(m_portsGatherer, SIGNAL(portListReady()), SLOT(handlePortListReady()));
+
+ connect(m_runner, SIGNAL(reportError(QString)), SLOT(handleError(QString)));
+ connect(m_runner, SIGNAL(remoteProcessStarted()), this, SLOT(handleRemoteProcessStarted()));
+ connect(m_runner, SIGNAL(finished(bool)), SLOT(handleRemoteProcessFinished(qint64)));
+ connect(m_runner, SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
+ connect(m_runner, SIGNAL(remoteStdout(QByteArray)), this, SLOT(handleRemoteOutput(QByteArray)));
connect(m_engine, SIGNAL(requestRemoteSetup()), this, SLOT(handleAdapterSetupRequested()));
}
@@ -56,18 +80,16 @@ void QnxDebugSupport::handleAdapterSetupRequested()
{
QTC_ASSERT(m_state == Inactive, return);
- m_state = StartingRunner;
+ m_state = GatheringPorts;
if (m_engine)
m_engine->showMessage(tr("Preparing remote side...\n"), Debugger::AppStuff);
+ m_portsGatherer->start(m_device);
+}
- connect(m_runner, SIGNAL(error(QString)), this, SLOT(handleSshError(QString)));
- connect(m_runner, SIGNAL(readyForExecution()), this, SLOT(startExecution()));
- connect(m_runner, SIGNAL(remoteProcessStarted()), this, SLOT(handleRemoteProcessStarted()));
- connect(m_runner, SIGNAL(remoteProcessFinished(qint64)), this, SLOT(handleRemoteProcessFinished(qint64)));
- connect(m_runner, SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
- connect(m_runner, SIGNAL(remoteOutput(QByteArray)), this, SLOT(handleRemoteOutput(QByteArray)));
-
- m_runner->start();
+void QnxDebugSupport::handlePortListReady()
+{
+ QTC_ASSERT(m_state == GatheringPorts, return);
+ startExecution();
}
void QnxDebugSupport::startExecution()
@@ -75,13 +97,13 @@ void QnxDebugSupport::startExecution()
if (m_state == Inactive)
return;
- QTC_ASSERT(m_state == StartingRunner, return);
-
m_state = StartingRemoteProcess;
- m_port = m_runner->usedPortsGatherer()->getNextFreePort(m_runner->freePorts());
+ Utils::PortList portList = m_device->freePorts();
+ m_port = m_portsGatherer->getNextFreePort(&portList);
- const QString remoteCommandLine = QString::fromLatin1("%1 %2 %3").arg(m_runner->commandPrefix()).arg(QLatin1String(Constants::QNX_DEBUG_EXECUTABLE)).arg(m_port);
- m_runner->startExecution(remoteCommandLine.toUtf8());
+ const QString remoteCommandLine = QString::fromLatin1("%1 %2 %3")
+ .arg(m_commandPrefix, m_executable).arg(m_port);
+ m_runner->start(m_device, remoteCommandLine.toUtf8());
}
void QnxDebugSupport::handleRemoteProcessStarted()
@@ -90,17 +112,17 @@ void QnxDebugSupport::handleRemoteProcessStarted()
m_engine->notifyEngineRemoteSetupDone(m_port, -1);
}
-void QnxDebugSupport::handleRemoteProcessFinished(qint64 exitCode)
+void QnxDebugSupport::handleRemoteProcessFinished(bool success)
{
if (m_engine || m_state == Inactive)
return;
if (m_state == Debugging) {
- if (exitCode != 0)
+ if (!success)
m_engine->notifyInferiorIll();
} else {
- const QString errorMsg = tr("The %1 process closed unexpectedly.").arg(QLatin1String(Constants::QNX_DEBUG_EXECUTABLE));
+ const QString errorMsg = tr("The %1 process closed unexpectedly.").arg(m_executable);
m_engine->notifyEngineRemoteSetupFailed(errorMsg);
}
}
@@ -113,7 +135,7 @@ void QnxDebugSupport::handleDebuggingFinished()
void QnxDebugSupport::setFinished()
{
m_state = Inactive;
- m_runner->stop();
+ m_runner->stop(QnxUtils::applicationKillCommand(m_executable).toUtf8());
}
void QnxDebugSupport::handleProgressReport(const QString &progressOutput)
@@ -130,7 +152,7 @@ void QnxDebugSupport::handleRemoteOutput(const QByteArray &output)
m_engine->showMessage(QString::fromUtf8(output), Debugger::AppOutput);
}
-void QnxDebugSupport::handleSshError(const QString &error)
+void QnxDebugSupport::handleError(const QString &error)
{
if (m_state == Debugging) {
if (m_engine) {
diff --git a/src/plugins/qnx/qnxdebugsupport.h b/src/plugins/qnx/qnxdebugsupport.h
index f2a9dd2b06..a97796546c 100644
--- a/src/plugins/qnx/qnxdebugsupport.h
+++ b/src/plugins/qnx/qnxdebugsupport.h
@@ -34,16 +34,20 @@
#ifndef QNX_INTERNAL_QNXDEBUGSUPPORT_H
#define QNX_INTERNAL_QNXDEBUGSUPPORT_H
+#include <projectexplorer/devicesupport/idevice.h>
+
#include <QObject>
+#include <QString>
-namespace Debugger {
-class DebuggerEngine;
+namespace Debugger { class DebuggerEngine; }
+namespace ProjectExplorer {
+class DeviceApplicationRunner;
+class DeviceUsedPortsGatherer;
}
namespace Qnx {
namespace Internal {
-class QnxApplicationRunner;
class QnxRunConfiguration;
class QnxDebugSupport : public QObject
@@ -59,25 +63,30 @@ public slots:
private slots:
void handleAdapterSetupRequested();
- void startExecution();
void handleRemoteProcessStarted();
- void handleRemoteProcessFinished(qint64 exitCode);
+ void handleRemoteProcessFinished(bool success);
void handleProgressReport(const QString &progressOutput);
void handleRemoteOutput(const QByteArray &output);
- void handleSshError(const QString &error);
+ void handleError(const QString &error);
+ void handlePortListReady();
private:
+ void startExecution();
void setFinished();
enum State {
Inactive,
- StartingRunner,
+ GatheringPorts,
StartingRemoteProcess,
Debugging
};
- QnxApplicationRunner *m_runner;
-
+ const QString m_executable;
+ const QString m_commandPrefix;
+ const QString m_arguments;
+ ProjectExplorer::IDevice::ConstPtr m_device;
+ ProjectExplorer::DeviceApplicationRunner *m_runner;
+ ProjectExplorer::DeviceUsedPortsGatherer * m_portsGatherer;
Debugger::DebuggerEngine *m_engine;
int m_port;
diff --git a/src/plugins/qnx/qnxruncontrol.cpp b/src/plugins/qnx/qnxruncontrol.cpp
index 187317fe11..f3cb262c56 100644
--- a/src/plugins/qnx/qnxruncontrol.cpp
+++ b/src/plugins/qnx/qnxruncontrol.cpp
@@ -32,21 +32,22 @@
**************************************************************************/
#include "qnxruncontrol.h"
-#include "qnxapplicationrunner.h"
#include "qnxrunconfiguration.h"
+#include "qnxutils.h"
#include <projectexplorer/runconfiguration.h>
+#include <remotelinux/remotelinuxrunconfiguration.h>
using namespace Qnx;
using namespace Qnx::Internal;
+using namespace RemoteLinux;
QnxRunControl::QnxRunControl(ProjectExplorer::RunConfiguration *runConfig)
- : RemoteLinux::AbstractRemoteLinuxRunControl(runConfig)
- , m_runner(new QnxApplicationRunner(qobject_cast<QnxRunConfiguration *>(runConfig), this))
+ : RemoteLinuxRunControl(runConfig)
{
-}
-
-RemoteLinux::AbstractRemoteLinuxApplicationRunner *QnxRunControl::runner() const
-{
- return m_runner;
+ const RemoteLinuxRunConfiguration * const rc
+ = qobject_cast<RemoteLinuxRunConfiguration *>(runConfig);
+ QString executable = rc->remoteExecutableFilePath();
+ executable.replace(QLatin1String("/"), QLatin1String("\\/"));
+ overrideStopCommandLine(QnxUtils::applicationKillCommand(executable).toUtf8());
}
diff --git a/src/plugins/qnx/qnxruncontrol.h b/src/plugins/qnx/qnxruncontrol.h
index f96ac525d0..d90b27debf 100644
--- a/src/plugins/qnx/qnxruncontrol.h
+++ b/src/plugins/qnx/qnxruncontrol.h
@@ -39,18 +39,11 @@
namespace Qnx {
namespace Internal {
-class QnxApplicationRunner;
-
-class QnxRunControl : public RemoteLinux::AbstractRemoteLinuxRunControl
+class QnxRunControl : public RemoteLinux::RemoteLinuxRunControl
{
Q_OBJECT
public:
explicit QnxRunControl(ProjectExplorer::RunConfiguration *runConfig);
-
- RemoteLinux::AbstractRemoteLinuxApplicationRunner *runner() const;
-
-private:
- QnxApplicationRunner * const m_runner;
};
} // namespace Internal
diff --git a/src/plugins/qnx/qnxutils.cpp b/src/plugins/qnx/qnxutils.cpp
index 4ef95137c9..d96b50649a 100644
--- a/src/plugins/qnx/qnxutils.cpp
+++ b/src/plugins/qnx/qnxutils.cpp
@@ -75,3 +75,11 @@ QStringList QnxUtils::searchPaths(QnxAbstractQtVersion *qtVersion)
return searchPaths;
}
+
+QString QnxUtils::applicationKillCommand(const QString &applicationFilePath)
+{
+ return QString::fromLatin1("for PID in $(ps -f -o pid,comm | grep %1 | awk '/%1/ {print $1}'); "
+ "do "
+ "kill $PID; sleep 1; kill -9 $PID; "
+ "done").arg(applicationFilePath);
+}
diff --git a/src/plugins/qnx/qnxutils.h b/src/plugins/qnx/qnxutils.h
index 1195f87c57..82d63de841 100644
--- a/src/plugins/qnx/qnxutils.h
+++ b/src/plugins/qnx/qnxutils.h
@@ -49,6 +49,7 @@ public:
static QString addQuotes(const QString &string);
static Qnx::QnxArchitecture cpudirToArch(const QString &cpuDir);
static QStringList searchPaths(QnxAbstractQtVersion *qtVersion);
+ static QString applicationKillCommand(const QString &applicationFilePath);
};
} // namespace Internal
diff --git a/src/plugins/remotelinux/remotelinux.pro b/src/plugins/remotelinux/remotelinux.pro
index 898f7cdf45..ed18ddd839 100644
--- a/src/plugins/remotelinux/remotelinux.pro
+++ b/src/plugins/remotelinux/remotelinux.pro
@@ -17,7 +17,6 @@ HEADERS += \
genericlinuxdeviceconfigurationfactory.h \
remotelinuxrunconfigurationwidget.h \
remotelinuxrunconfigurationfactory.h \
- remotelinuxapplicationrunner.h \
remotelinuxruncontrol.h \
remotelinuxruncontrolfactory.h \
remotelinuxdebugsupport.h \
@@ -65,7 +64,6 @@ SOURCES += \
genericlinuxdeviceconfigurationfactory.cpp \
remotelinuxrunconfigurationwidget.cpp \
remotelinuxrunconfigurationfactory.cpp \
- remotelinuxapplicationrunner.cpp \
remotelinuxruncontrol.cpp \
remotelinuxruncontrolfactory.cpp \
remotelinuxdebugsupport.cpp \
diff --git a/src/plugins/remotelinux/remotelinux.qbs b/src/plugins/remotelinux/remotelinux.qbs
index 2236fe1511..7c353ea2fc 100644
--- a/src/plugins/remotelinux/remotelinux.qbs
+++ b/src/plugins/remotelinux/remotelinux.qbs
@@ -64,8 +64,6 @@ QtcPlugin {
"remotelinux.qrc",
"remotelinux_constants.h",
"remotelinux_export.h",
- "remotelinuxapplicationrunner.cpp",
- "remotelinuxapplicationrunner.h",
"remotelinuxcustomcommanddeploymentstep.h",
"remotelinuxcustomcommanddeployservice.cpp",
"remotelinuxcustomcommanddeployservice.h",
diff --git a/src/plugins/remotelinux/remotelinuxapplicationrunner.cpp b/src/plugins/remotelinux/remotelinuxapplicationrunner.cpp
deleted file mode 100644
index 1d73d77cf5..0000000000
--- a/src/plugins/remotelinux/remotelinuxapplicationrunner.cpp
+++ /dev/null
@@ -1,508 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: http://www.qt-project.org/
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**************************************************************************/
-
-#include "remotelinuxapplicationrunner.h"
-
-#include "linuxdeviceconfiguration.h"
-#include "remotelinuxrunconfiguration.h"
-
-#include <projectexplorer/target.h>
-#include <projectexplorer/profileinformation.h>
-#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
-
-#include <utils/portlist.h>
-#include <utils/qtcassert.h>
-#include <ssh/sshconnection.h>
-#include <ssh/sshconnectionmanager.h>
-#include <ssh/sshremoteprocess.h>
-
-#include <limits>
-
-using namespace ProjectExplorer;
-using namespace QSsh;
-using namespace Utils;
-
-namespace RemoteLinux {
-namespace Internal {
-namespace {
-
-enum State {
- Inactive, SettingUpDevice, Connecting, PreRunCleaning, AdditionalPreRunCleaning,
- GatheringPorts, AdditionalInitializing, ReadyForExecution, ProcessStarting, ProcessStarted,
- PostRunCleaning
-};
-
-} // anonymous namespace
-
-class AbstractRemoteLinuxApplicationRunnerPrivate
-{
-public:
- AbstractRemoteLinuxApplicationRunnerPrivate(const RemoteLinuxRunConfiguration *runConfig)
- : devConfig(DeviceProfileInformation::device(runConfig->target()->profile())),
- remoteExecutable(runConfig->remoteExecutableFilePath()),
- appArguments(runConfig->arguments()),
- commandPrefix(runConfig->commandPrefix()),
- initialFreePorts(devConfig->freePorts()),
- connection(0),
- stopRequested(false),
- state(Inactive)
- { }
-
- DeviceUsedPortsGatherer portsGatherer;
- IDevice::ConstPtr devConfig;
- const QString remoteExecutable;
- const QString appArguments;
- const QString commandPrefix;
- const PortList initialFreePorts;
-
- QSsh::SshConnection *connection;
- QSsh::SshRemoteProcess::Ptr runner;
- QSsh::SshRemoteProcess::Ptr cleaner;
-
- PortList freePorts;
- int exitStatus;
- bool stopRequested;
- State state;
-
-};
-} // namespace Internal
-
-
-using namespace Internal;
-
-AbstractRemoteLinuxApplicationRunner::AbstractRemoteLinuxApplicationRunner(RemoteLinuxRunConfiguration *runConfig,
- QObject *parent)
- : QObject(parent), d(new AbstractRemoteLinuxApplicationRunnerPrivate(runConfig))
-{
- connect(&d->portsGatherer, SIGNAL(error(QString)), SLOT(handlePortsGathererError(QString)));
- connect(&d->portsGatherer, SIGNAL(portListReady()), SLOT(handleUsedPortsAvailable()));
-}
-
-AbstractRemoteLinuxApplicationRunner::~AbstractRemoteLinuxApplicationRunner()
-{
- delete d;
-}
-
-SshConnection *AbstractRemoteLinuxApplicationRunner::connection() const
-{
- return d->connection;
-}
-
-IDevice::ConstPtr AbstractRemoteLinuxApplicationRunner::devConfig() const
-{
- return d->devConfig;
-}
-
-DeviceUsedPortsGatherer *AbstractRemoteLinuxApplicationRunner::usedPortsGatherer() const
-{
- return &d->portsGatherer;
-}
-
-PortList *AbstractRemoteLinuxApplicationRunner::freePorts()
-{
- return &d->freePorts;
-}
-
-QString AbstractRemoteLinuxApplicationRunner::remoteExecutable() const
-{
- return d->remoteExecutable;
-}
-
-QString AbstractRemoteLinuxApplicationRunner::arguments() const
-{
- return d->appArguments;
-}
-
-QString AbstractRemoteLinuxApplicationRunner::commandPrefix() const
-{
- return d->commandPrefix;
-}
-
-void AbstractRemoteLinuxApplicationRunner::start()
-{
- QTC_ASSERT(!d->stopRequested && d->state == Inactive, return);
-
- QString errorMsg;
- if (!canRun(errorMsg)) {
- emitError(tr("Cannot run: %1").arg(errorMsg), true);
- return;
- }
-
- d->state = SettingUpDevice;
- doDeviceSetup();
-}
-
-void AbstractRemoteLinuxApplicationRunner::stop()
-{
- if (d->stopRequested)
- return;
-
- switch (d->state) {
- case Connecting:
- setInactive();
- emit remoteProcessFinished(InvalidExitCode);
- break;
- case GatheringPorts:
- d->portsGatherer.stop();
- setInactive();
- emit remoteProcessFinished(InvalidExitCode);
- break;
- case SettingUpDevice:
- case PreRunCleaning:
- case AdditionalPreRunCleaning:
- case AdditionalInitializing:
- case ProcessStarting:
- case PostRunCleaning:
- d->stopRequested = true; // TODO: We might need stopPreRunCleaning() etc. for the subclasses
- break;
- case ReadyForExecution:
- d->stopRequested = true;
- d->state = PostRunCleaning;
- doPostRunCleanup();
- break;
- case ProcessStarted:
- d->stopRequested = true;
- cleanup();
- break;
- case Inactive:
- break;
- }
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleConnected()
-{
- QTC_ASSERT(d->state == Connecting, return);
-
- if (d->stopRequested) {
- emit remoteProcessFinished(InvalidExitCode);
- setInactive();
- } else {
- d->state = PreRunCleaning;
- cleanup();
- }
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleConnectionFailure()
-{
- QTC_ASSERT(d->state != Inactive, return);
-
- if (d->state != Connecting || d->state != PreRunCleaning)
- doAdditionalConnectionErrorHandling();
-
- const QString errorMsg = d->state == Connecting
- ? tr("Could not connect to host: %1") : tr("Connection error: %1");
- emitError(errorMsg.arg(d->connection->errorString()));
-}
-
-void AbstractRemoteLinuxApplicationRunner::cleanup()
-{
- QTC_ASSERT(d->state == PreRunCleaning
- || (d->state == ProcessStarted && d->stopRequested), return);
-
- emit reportProgress(tr("Killing remote process(es)..."));
- d->cleaner = d->connection->createRemoteProcess(killApplicationCommandLine().toUtf8());
- connect(d->cleaner.data(), SIGNAL(closed(int)), SLOT(handleCleanupFinished(int)));
- d->cleaner->start();
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleCleanupFinished(int exitStatus)
-{
- Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart
- || exitStatus == SshRemoteProcess::CrashExit
- || exitStatus == SshRemoteProcess::NormalExit);
-
- QTC_ASSERT(d->state == PreRunCleaning
- || (d->state == ProcessStarted && d->stopRequested) || d->state == Inactive, return);
-
- if (d->state == Inactive)
- return;
- if (d->stopRequested && d->state == PreRunCleaning) {
- setInactive();
- emit remoteProcessFinished(InvalidExitCode);
- return;
- }
- if (d->stopRequested) {
- d->state = PostRunCleaning;
- doPostRunCleanup();
- return;
- }
-
- if (exitStatus != SshRemoteProcess::NormalExit) {
- emitError(tr("Initial cleanup failed: %1").arg(d->cleaner->errorString()));
- emit remoteProcessFinished(InvalidExitCode);
- return;
- }
-
- d->state = AdditionalPreRunCleaning;
- doAdditionalInitialCleanup();
-}
-
-void AbstractRemoteLinuxApplicationRunner::startExecution(const QByteArray &remoteCall)
-{
- QTC_ASSERT(d->state == ReadyForExecution, return);
-
- if (d->stopRequested)
- return;
-
- d->runner = d->connection->createRemoteProcess(remoteCall);
- connect(d->runner.data(), SIGNAL(started()), SLOT(handleRemoteProcessStarted()));
- connect(d->runner.data(), SIGNAL(closed(int)), SLOT(handleRemoteProcessFinished(int)));
- connect(d->runner.data(), SIGNAL(readyReadStandardOutput()), SLOT(handleRemoteStdout()));
- connect(d->runner.data(), SIGNAL(readyReadStandardError()), SLOT(handleRemoteStderr()));
- d->state = ProcessStarting;
- d->runner->start();
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleRemoteProcessStarted()
-{
- QTC_ASSERT(d->state == ProcessStarting, return);
-
- d->state = ProcessStarted;
- if (d->stopRequested) {
- cleanup();
- return;
- }
-
- emit reportProgress(tr("Remote process started."));
- emit remoteProcessStarted();
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleRemoteProcessFinished(int exitStatus)
-{
- Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart
- || exitStatus == SshRemoteProcess::CrashExit
- || exitStatus == SshRemoteProcess::NormalExit);
- QTC_ASSERT(d->state == ProcessStarted || d->state == Inactive, return);
-
- d->exitStatus = exitStatus;
- if (!d->stopRequested && d->state != Inactive) {
- d->state = PostRunCleaning;
- doPostRunCleanup();
- }
-}
-
-void AbstractRemoteLinuxApplicationRunner::setInactive()
-{
- d->portsGatherer.stop();
- if (d->connection) {
- disconnect(d->connection, 0, this, 0);
- SshConnectionManager::instance().releaseConnection(d->connection);
- d->connection = 0;
- }
- if (d->cleaner)
- disconnect(d->cleaner.data(), 0, this, 0);
- d->stopRequested = false;
- d->state = Inactive;
-}
-
-void AbstractRemoteLinuxApplicationRunner::emitError(const QString &errorMsg, bool force)
-{
- if (d->state != Inactive) {
- setInactive();
- emit error(errorMsg);
- } else if (force) {
- emit error(errorMsg);
- }
-}
-
-void AbstractRemoteLinuxApplicationRunner::handlePortsGathererError(const QString &errorMsg)
-{
- if (d->state != Inactive) {
- if (connection()->errorState() != SshNoError) {
- emitError(errorMsg);
- } else {
- emit reportProgress(tr("Gathering ports failed: %1\nContinuing anyway.").arg(errorMsg));
- handleUsedPortsAvailable();
- }
- }
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleUsedPortsAvailable()
-{
- QTC_ASSERT(d->state == GatheringPorts, return);
-
- if (d->stopRequested) {
- setInactive();
- emit remoteProcessFinished(InvalidExitCode);
- return;
- }
-
- d->state = AdditionalInitializing;
- doAdditionalInitializations();
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleRemoteStdout()
-{
- emit remoteOutput(d->runner->readAllStandardOutput());
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleRemoteStderr()
-{
- emit remoteErrorOutput(d->runner->readAllStandardError());
-}
-
-bool AbstractRemoteLinuxApplicationRunner::canRun(QString &whyNot) const
-{
- if (d->remoteExecutable.isEmpty()) {
- whyNot = tr("No remote executable set.");
- return false;
- }
-
- if (!d->devConfig) {
- whyNot = tr("No device configuration set.");
- return false;
- }
-
- return true;
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleDeviceSetupDone(bool success)
-{
- QTC_ASSERT(d->state == SettingUpDevice, return);
-
- if (!success || d->stopRequested) {
- setInactive();
- emit remoteProcessFinished(InvalidExitCode);
- return;
- }
-
- d->connection = SshConnectionManager::instance().acquireConnection(d->devConfig->sshParameters());
- d->state = Connecting;
- d->exitStatus = -1;
- d->freePorts = d->initialFreePorts;
- connect(d->connection, SIGNAL(connected()), SLOT(handleConnected()));
- connect(d->connection, SIGNAL(error(QSsh::SshError)),
- SLOT(handleConnectionFailure()));
- if (d->connection->state() == SshConnection::Connected) {
- handleConnected();
- } else {
- emit reportProgress(tr("Connecting to device..."));
- if (d->connection->state() == QSsh::SshConnection::Unconnected)
- d->connection->connectToHost();
- }
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleInitialCleanupDone(bool success)
-{
- QTC_ASSERT(d->state == AdditionalPreRunCleaning, return);
-
- if (!success || d->stopRequested) {
- setInactive();
- emit remoteProcessFinished(InvalidExitCode);
- return;
- }
-
- d->state = GatheringPorts;
- d->portsGatherer.start(d->devConfig);
-}
-
-void AbstractRemoteLinuxApplicationRunner::handleInitializationsDone(bool success)
-{
- QTC_ASSERT(d->state == AdditionalInitializing, return);
-
- if (!success) {
- setInactive();
- emit remoteProcessFinished(InvalidExitCode);
- return;
- }
- if (d->stopRequested) {
- d->state = PostRunCleaning;
- doPostRunCleanup();
- return;
- }
-
- d->state = ReadyForExecution;
- emit readyForExecution();
-}
-
-void AbstractRemoteLinuxApplicationRunner::handlePostRunCleanupDone()
-{
- QTC_ASSERT(d->state == PostRunCleaning, return);
-
- const bool wasStopRequested = d->stopRequested;
- setInactive();
- if (wasStopRequested)
- emit remoteProcessFinished(InvalidExitCode);
- else if (d->exitStatus == SshRemoteProcess::NormalExit)
- emit remoteProcessFinished(d->runner->exitCode());
- else
- emit error(tr("Error running remote process: %1").arg(d->runner->errorString()));
-}
-
-QString AbstractRemoteLinuxApplicationRunner::killApplicationCommandLine() const
-{
- return QString::fromLatin1("cd /proc; for pid in `ls -d [0123456789]*`; "
- "do "
- "if [ \"`readlink /proc/$pid/exe`\" = \"%1\" ]; then "
- " kill $pid; sleep 1; kill -9 $pid; "
- "fi; "
- "done").arg(remoteExecutable());
-}
-
-
-const qint64 AbstractRemoteLinuxApplicationRunner::InvalidExitCode = std::numeric_limits<qint64>::min();
-
-
-GenericRemoteLinuxApplicationRunner::GenericRemoteLinuxApplicationRunner(RemoteLinuxRunConfiguration *runConfig,
- QObject *parent)
- : AbstractRemoteLinuxApplicationRunner(runConfig, parent)
-{
-}
-
-GenericRemoteLinuxApplicationRunner::~GenericRemoteLinuxApplicationRunner()
-{
-}
-
-
-void GenericRemoteLinuxApplicationRunner::doDeviceSetup()
-{
- handleDeviceSetupDone(true);
-}
-
-void GenericRemoteLinuxApplicationRunner::doAdditionalInitialCleanup()
-{
- handleInitialCleanupDone(true);
-}
-
-void GenericRemoteLinuxApplicationRunner::doAdditionalInitializations()
-{
- handleInitializationsDone(true);
-}
-
-void GenericRemoteLinuxApplicationRunner::doPostRunCleanup()
-{
- handlePostRunCleanupDone();
-}
-
-void GenericRemoteLinuxApplicationRunner::doAdditionalConnectionErrorHandling()
-{
-}
-
-} // namespace RemoteLinux
-
diff --git a/src/plugins/remotelinux/remotelinuxapplicationrunner.h b/src/plugins/remotelinux/remotelinuxapplicationrunner.h
deleted file mode 100644
index 1b0d850bca..0000000000
--- a/src/plugins/remotelinux/remotelinuxapplicationrunner.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: http://www.qt-project.org/
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**************************************************************************/
-
-#ifndef REMOTELINUXAPPLICATIONRUNNER_H
-#define REMOTELINUXAPPLICATIONRUNNER_H
-
-#include "remotelinux_export.h"
-
-#include <projectexplorer/devicesupport/idevice.h>
-#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
-
-namespace QSsh { class SshConnection; }
-namespace Utils { class PortList; }
-
-namespace RemoteLinux {
-class RemoteLinuxRunConfiguration;
-
-namespace Internal { class AbstractRemoteLinuxApplicationRunnerPrivate; }
-
-class REMOTELINUX_EXPORT AbstractRemoteLinuxApplicationRunner : public QObject
-{
- Q_OBJECT
- Q_DISABLE_COPY(AbstractRemoteLinuxApplicationRunner)
-public:
- AbstractRemoteLinuxApplicationRunner(RemoteLinuxRunConfiguration *runConfig,
- QObject *parent = 0);
- ~AbstractRemoteLinuxApplicationRunner();
-
- void start();
- void stop();
-
- void startExecution(const QByteArray &remoteCall);
-
- ProjectExplorer::IDevice::ConstPtr devConfig() const;
- QSsh::SshConnection *connection() const;
- ProjectExplorer::DeviceUsedPortsGatherer *usedPortsGatherer() const;
- Utils::PortList *freePorts();
- QString remoteExecutable() const;
- QString arguments() const;
- QString commandPrefix() const;
-
- static const qint64 InvalidExitCode;
-
-signals:
- void error(const QString &error);
- void readyForExecution();
- void remoteOutput(const QByteArray &output);
- void remoteErrorOutput(const QByteArray &output);
- void reportProgress(const QString &progressOutput);
- void remoteProcessStarted();
- void remoteProcessFinished(qint64 exitCode);
-
-protected:
- // Override to to additional checks.
- virtual bool canRun(QString &whyNot) const;
-
- void handleDeviceSetupDone(bool success);
- void handleInitialCleanupDone(bool success);
- void handleInitializationsDone(bool success);
- void handlePostRunCleanupDone();
-
-private slots:
- void handleConnected();
- void handleConnectionFailure();
- void handleCleanupFinished(int exitStatus);
- void handleRemoteProcessStarted();
- void handleRemoteProcessFinished(int exitStatus);
- void handlePortsGathererError(const QString &errorMsg);
- void handleUsedPortsAvailable();
- void handleRemoteStdout();
- void handleRemoteStderr();
-
-private:
-
- virtual QString killApplicationCommandLine() const;
-
- // Implement to do custom setup of the device *before* connecting.
- // Call handleDeviceSetupDone() afterwards.
- virtual void doDeviceSetup() = 0;
-
- // Implement to do additional pre-run cleanup and call handleInitialCleanupDone().
- virtual void doAdditionalInitialCleanup() = 0;
-
- // Implement to do additional initializations right before the application is ready.
- // Call handleInitializationsDone() afterwards.
- virtual void doAdditionalInitializations() = 0;
-
- // Implement to do cleanups after application exit and call handlePostRunCleanupDone();
- virtual void doPostRunCleanup() = 0;
-
- virtual void doAdditionalConnectionErrorHandling() = 0;
-
- void setInactive();
- void emitError(const QString &errorMsg, bool force = false);
- void cleanup();
-
- Internal::AbstractRemoteLinuxApplicationRunnerPrivate * const d;
-};
-
-
-class REMOTELINUX_EXPORT GenericRemoteLinuxApplicationRunner : public AbstractRemoteLinuxApplicationRunner
-{
- Q_OBJECT
-public:
- GenericRemoteLinuxApplicationRunner(RemoteLinuxRunConfiguration *runConfig,
- QObject *parent = 0);
- ~GenericRemoteLinuxApplicationRunner();
-
-protected:
- void doDeviceSetup();
- void doAdditionalInitialCleanup();
- void doAdditionalInitializations();
- void doPostRunCleanup();
- void doAdditionalConnectionErrorHandling();
-};
-
-} // namespace RemoteLinux
-
-#endif // REMOTELINUXAPPLICATIONRUNNER_H
diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
index 30dd23fe66..e9d299db94 100644
--- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
+++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
@@ -29,8 +29,8 @@
#include "remotelinuxdebugsupport.h"
-#include "remotelinuxapplicationrunner.h"
#include "remotelinuxrunconfiguration.h"
+#include "remotelinuxutils.h"
#include <debugger/debuggerengine.h>
#include <debugger/debuggerstartparameters.h>
@@ -42,6 +42,8 @@
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
+#include <projectexplorer/devicesupport/deviceapplicationrunner.h>
+#include <utils/portlist.h>
#include <utils/qtcassert.h>
#include <QPointer>
@@ -54,19 +56,23 @@ using namespace ProjectExplorer;
namespace RemoteLinux {
namespace Internal {
namespace {
-enum State { Inactive, StartingRunner, StartingRemoteProcess, Debugging };
+enum State { Inactive, GatheringPorts, StartingRunner, Debugging };
} // anonymous namespace
-class AbstractRemoteLinuxDebugSupportPrivate
+class LinuxDeviceDebugSupportPrivate
{
public:
- AbstractRemoteLinuxDebugSupportPrivate(RunConfiguration *runConfig,
+ LinuxDeviceDebugSupportPrivate(const RemoteLinuxRunConfiguration *runConfig,
DebuggerEngine *engine)
: engine(engine),
qmlDebugging(runConfig->debuggerAspect()->useQmlDebugger()),
cppDebugging(runConfig->debuggerAspect()->useCppDebugger()),
state(Inactive),
- gdbServerPort(-1), qmlPort(-1)
+ gdbServerPort(-1), qmlPort(-1),
+ device(DeviceProfileInformation::device(runConfig->target()->profile())),
+ remoteFilePath(runConfig->remoteExecutableFilePath()),
+ arguments(runConfig->arguments()),
+ commandPrefix(runConfig->commandPrefix())
{
}
@@ -77,21 +83,20 @@ public:
State state;
int gdbServerPort;
int qmlPort;
-};
-
-class RemoteLinuxDebugSupportPrivate
-{
-public:
- RemoteLinuxDebugSupportPrivate(RemoteLinuxRunConfiguration *runConfig) : runner(runConfig) {}
-
- GenericRemoteLinuxApplicationRunner runner;
+ DeviceApplicationRunner appRunner;
+ DeviceUsedPortsGatherer portsGatherer;
+ const ProjectExplorer::IDevice::ConstPtr device;
+ Utils::PortList portList;
+ const QString remoteFilePath;
+ const QString arguments;
+ const QString commandPrefix;
};
} // namespace Internal
using namespace Internal;
-DebuggerStartParameters AbstractRemoteLinuxDebugSupport::startParameters(const RemoteLinuxRunConfiguration *runConfig)
+DebuggerStartParameters LinuxDeviceDebugSupport::startParameters(const RemoteLinuxRunConfiguration *runConfig)
{
DebuggerStartParameters params;
Target *target = runConfig->target();
@@ -130,92 +135,101 @@ DebuggerStartParameters AbstractRemoteLinuxDebugSupport::startParameters(const R
return params;
}
-AbstractRemoteLinuxDebugSupport::AbstractRemoteLinuxDebugSupport(RunConfiguration *runConfig,
+LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunConfiguration *runConfig,
DebuggerEngine *engine)
- : QObject(engine), d(new AbstractRemoteLinuxDebugSupportPrivate(runConfig, engine))
+ : QObject(engine),
+ d(new LinuxDeviceDebugSupportPrivate(static_cast<RemoteLinuxRunConfiguration *>(runConfig), engine))
{
connect(d->engine, SIGNAL(requestRemoteSetup()), this, SLOT(handleRemoteSetupRequested()));
}
-AbstractRemoteLinuxDebugSupport::~AbstractRemoteLinuxDebugSupport()
+LinuxDeviceDebugSupport::~LinuxDeviceDebugSupport()
{
setFinished();
delete d;
}
-void AbstractRemoteLinuxDebugSupport::showMessage(const QString &msg, int channel)
+void LinuxDeviceDebugSupport::setApplicationRunnerPreRunAction(DeviceApplicationHelperAction *action)
{
- if (d->engine)
+ d->appRunner.setPreRunAction(action);
+}
+
+void LinuxDeviceDebugSupport::setApplicationRunnerPostRunAction(DeviceApplicationHelperAction *action)
+{
+ d->appRunner.setPostRunAction(action);
+}
+
+void LinuxDeviceDebugSupport::showMessage(const QString &msg, int channel)
+{
+ if (d->state != Inactive && d->engine)
d->engine->showMessage(msg, channel);
}
-void AbstractRemoteLinuxDebugSupport::handleRemoteSetupRequested()
+void LinuxDeviceDebugSupport::handleRemoteSetupRequested()
{
QTC_ASSERT(d->state == Inactive, return);
- d->state = StartingRunner;
- showMessage(tr("Preparing remote side...\n"), AppStuff);
- disconnect(runner(), 0, this, 0);
- connect(runner(), SIGNAL(error(QString)), this, SLOT(handleSshError(QString)));
- connect(runner(), SIGNAL(readyForExecution()), this, SLOT(startExecution()));
- connect(runner(), SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
- runner()->start();
+ d->state = GatheringPorts;
+ showMessage(tr("Checking available ports...\n"), LogStatus);
+ connect(&d->portsGatherer, SIGNAL(error(QString)), SLOT(handlePortsGathererError(QString)));
+ connect(&d->portsGatherer, SIGNAL(portListReady()), SLOT(handlePortListReady()));
+ d->portsGatherer.start(d->device);
}
-void AbstractRemoteLinuxDebugSupport::handleSshError(const QString &error)
+void LinuxDeviceDebugSupport::handlePortsGathererError(const QString &message)
{
- if (d->state == Debugging) {
- showMessage(error, AppError);
- if (d->engine)
- d->engine->notifyInferiorIll();
- } else if (d->state != Inactive) {
- handleAdapterSetupFailed(error);
- }
+ QTC_ASSERT(d->state == GatheringPorts, return);
+ handleAdapterSetupFailed(message);
}
-void AbstractRemoteLinuxDebugSupport::startExecution()
+void LinuxDeviceDebugSupport::handlePortListReady()
{
- if (d->state == Inactive)
- return;
+ QTC_ASSERT(d->state == GatheringPorts, return);
- QTC_ASSERT(d->state == StartingRunner, return);
+ d->portList = d->device->freePorts();
+ startExecution();
+}
+
+void LinuxDeviceDebugSupport::startExecution()
+{
+ QTC_ASSERT(d->state == GatheringPorts, return);
if (d->cppDebugging && !setPort(d->gdbServerPort))
return;
if (d->qmlDebugging && !setPort(d->qmlPort))
return;
- d->state = StartingRemoteProcess;
+ d->state = StartingRunner;
d->gdbserverOutput.clear();
- connect(runner(), SIGNAL(remoteErrorOutput(QByteArray)), this,
- SLOT(handleRemoteErrorOutput(QByteArray)));
- connect(runner(), SIGNAL(remoteOutput(QByteArray)), this,
- SLOT(handleRemoteOutput(QByteArray)));
- if (d->qmlDebugging && !d->cppDebugging) {
- connect(runner(), SIGNAL(remoteProcessStarted()),
- SLOT(handleRemoteProcessStarted()));
- }
- const QString &remoteExe = runner()->remoteExecutable();
- QString args = runner()->arguments();
- if (d->qmlDebugging) {
- args += QString::fromLatin1(" -qmljsdebugger=port:%1,block")
- .arg(d->qmlPort);
- }
- const QHostAddress peerAddress = runner()->connection()->connectionInfo().peerAddress;
- QString peerAddressString = peerAddress.toString();
- if (peerAddress.protocol() == QAbstractSocket::IPv6Protocol)
- peerAddressString.prepend(QLatin1Char('[')).append(QLatin1Char(']'));
+ connect(&d->appRunner, SIGNAL(remoteStderr(QByteArray)),
+ SLOT(handleRemoteErrorOutput(QByteArray)));
+ connect(&d->appRunner, SIGNAL(remoteStdout(QByteArray)), SLOT(handleRemoteOutput(QByteArray)));
+ if (d->qmlDebugging && !d->cppDebugging)
+ connect(&d->appRunner, SIGNAL(remoteProcessStarted()), SLOT(handleRemoteProcessStarted()));
+ QString args = d->arguments;
+ if (d->qmlDebugging)
+ args += QString::fromLocal8Bit(" -qmljsdebugger=port:%1,block").arg(d->qmlPort);
const QString remoteCommandLine = (d->qmlDebugging && !d->cppDebugging)
- ? QString::fromLatin1("%1 %2 %3").arg(runner()->commandPrefix()).arg(remoteExe).arg(args)
- : QString::fromLatin1("%1 gdbserver %5:%2 %3 %4").arg(runner()->commandPrefix())
- .arg(d->gdbServerPort).arg(remoteExe).arg(args).arg(peerAddressString);
- connect(runner(), SIGNAL(remoteProcessFinished(qint64)),
- SLOT(handleRemoteProcessFinished(qint64)));
- runner()->startExecution(remoteCommandLine.toUtf8());
+ ? QString::fromLatin1("%1 %2 %3").arg(d->commandPrefix).arg(d->remoteFilePath).arg(args)
+ : QString::fromLatin1("%1 gdbserver :%2 %3 %4").arg(d->commandPrefix)
+ .arg(d->gdbServerPort).arg(d->remoteFilePath).arg(args);
+ connect(&d->appRunner, SIGNAL(finished(bool)), SLOT(handleAppRunnerFinished(bool)));
+ d->appRunner.start(d->device, remoteCommandLine.toUtf8());
}
-void AbstractRemoteLinuxDebugSupport::handleRemoteProcessFinished(qint64 exitCode)
+void LinuxDeviceDebugSupport::handleAppRunnerError(const QString &error)
+{
+ if (d->state == Debugging) {
+ showMessage(error, AppError);
+ if (d->engine)
+ d->engine->notifyInferiorIll();
+ } else if (d->state != Inactive) {
+ handleAdapterSetupFailed(error);
+ }
+}
+
+void LinuxDeviceDebugSupport::handleAppRunnerFinished(bool success)
{
if (!d->engine || d->state == Inactive)
return;
@@ -224,39 +238,35 @@ void AbstractRemoteLinuxDebugSupport::handleRemoteProcessFinished(qint64 exitCod
// The QML engine does not realize on its own that the application has finished.
if (d->qmlDebugging && !d->cppDebugging)
d->engine->quitDebugger();
- else if (exitCode != 0)
+ else if (!success)
d->engine->notifyInferiorIll();
} else {
- const QString errorMsg = (d->qmlDebugging && !d->cppDebugging)
- ? tr("Remote application failed with exit code %1.").arg(exitCode)
- : tr("The gdbserver process closed unexpectedly.");
- d->engine->notifyEngineRemoteSetupFailed(errorMsg);
+ d->engine->notifyEngineRemoteSetupFailed(tr("Debugging failed."));
}
}
-void AbstractRemoteLinuxDebugSupport::handleDebuggingFinished()
+void LinuxDeviceDebugSupport::handleDebuggingFinished()
{
setFinished();
}
-void AbstractRemoteLinuxDebugSupport::handleRemoteOutput(const QByteArray &output)
+void LinuxDeviceDebugSupport::handleRemoteOutput(const QByteArray &output)
{
QTC_ASSERT(d->state == Inactive || d->state == Debugging, return);
showMessage(QString::fromUtf8(output), AppOutput);
}
-void AbstractRemoteLinuxDebugSupport::handleRemoteErrorOutput(const QByteArray &output)
+void LinuxDeviceDebugSupport::handleRemoteErrorOutput(const QByteArray &output)
{
- QTC_ASSERT(d->state == Inactive || d->state == StartingRemoteProcess || d->state == Debugging,
- return);
+ QTC_ASSERT(d->state != GatheringPorts, return);
if (!d->engine)
return;
- showMessage(QString::fromUtf8(output), AppOutput);
- if (d->state == StartingRemoteProcess && d->cppDebugging) {
+ showMessage(QString::fromUtf8(output), AppError);
+ if (d->state == StartingRunner && d->cppDebugging) {
d->gdbserverOutput += output;
if (d->gdbserverOutput.contains("Listening on port")) {
handleAdapterSetupDone();
@@ -265,42 +275,45 @@ void AbstractRemoteLinuxDebugSupport::handleRemoteErrorOutput(const QByteArray &
}
}
-void AbstractRemoteLinuxDebugSupport::handleProgressReport(const QString &progressOutput)
+void LinuxDeviceDebugSupport::handleProgressReport(const QString &progressOutput)
{
- showMessage(progressOutput + QLatin1Char('\n'), AppStuff);
+ showMessage(progressOutput + QLatin1Char('\n'), LogStatus);
}
-void AbstractRemoteLinuxDebugSupport::handleAdapterSetupFailed(const QString &error)
+void LinuxDeviceDebugSupport::handleAdapterSetupFailed(const QString &error)
{
setFinished();
d->engine->notifyEngineRemoteSetupFailed(tr("Initial setup failed: %1").arg(error));
}
-void AbstractRemoteLinuxDebugSupport::handleAdapterSetupDone()
+void LinuxDeviceDebugSupport::handleAdapterSetupDone()
{
d->state = Debugging;
d->engine->notifyEngineRemoteSetupDone(d->gdbServerPort, d->qmlPort);
}
-void AbstractRemoteLinuxDebugSupport::handleRemoteProcessStarted()
+void LinuxDeviceDebugSupport::handleRemoteProcessStarted()
{
- Q_ASSERT(d->qmlDebugging && !d->cppDebugging);
- QTC_ASSERT(d->state == StartingRemoteProcess, return);
+ QTC_ASSERT(d->qmlDebugging && !d->cppDebugging, return);
+ QTC_ASSERT(d->state == StartingRunner, return);
handleAdapterSetupDone();
}
-void AbstractRemoteLinuxDebugSupport::setFinished()
+void LinuxDeviceDebugSupport::setFinished()
{
if (d->state == Inactive)
return;
+ d->portsGatherer.disconnect(this);
+ d->appRunner.disconnect(this);
+ if (d->state == StartingRunner)
+ d->appRunner.stop(RemoteLinuxUtils::killApplicationCommandLine(d->remoteFilePath).toUtf8());
d->state = Inactive;
- runner()->stop();
}
-bool AbstractRemoteLinuxDebugSupport::setPort(int &port)
+bool LinuxDeviceDebugSupport::setPort(int &port)
{
- port = runner()->usedPortsGatherer()->getNextFreePort(runner()->freePorts());
+ port = d->portsGatherer.getNextFreePort(&d->portList);
if (port == -1) {
handleAdapterSetupFailed(tr("Not enough free ports on device for debugging."));
return false;
@@ -308,22 +321,4 @@ bool AbstractRemoteLinuxDebugSupport::setPort(int &port)
return true;
}
-
-RemoteLinuxDebugSupport::RemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig,
- DebuggerEngine *engine)
- : AbstractRemoteLinuxDebugSupport(runConfig, engine),
- d(new RemoteLinuxDebugSupportPrivate(runConfig))
-{
-}
-
-RemoteLinuxDebugSupport::~RemoteLinuxDebugSupport()
-{
- delete d;
-}
-
-AbstractRemoteLinuxApplicationRunner *RemoteLinuxDebugSupport::runner() const
-{
- return &d->runner;
-}
-
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.h b/src/plugins/remotelinux/remotelinuxdebugsupport.h
index cee77a1420..6643835c50 100644
--- a/src/plugins/remotelinux/remotelinuxdebugsupport.h
+++ b/src/plugins/remotelinux/remotelinuxdebugsupport.h
@@ -40,65 +40,49 @@ class DebuggerStartParameters;
}
namespace ProjectExplorer {
-class RunControl;
+class DeviceApplicationHelperAction;
class RunConfiguration;
}
namespace RemoteLinux {
class RemoteLinuxRunConfiguration;
-class AbstractRemoteLinuxApplicationRunner;
-namespace Internal {
-class AbstractRemoteLinuxDebugSupportPrivate;
-class RemoteLinuxDebugSupportPrivate;
-} // namespace Internal
+namespace Internal { class LinuxDeviceDebugSupportPrivate; }
-class REMOTELINUX_EXPORT AbstractRemoteLinuxDebugSupport : public QObject
+class REMOTELINUX_EXPORT LinuxDeviceDebugSupport : public QObject
{
Q_OBJECT
- Q_DISABLE_COPY(AbstractRemoteLinuxDebugSupport)
public:
static Debugger::DebuggerStartParameters startParameters(const RemoteLinuxRunConfiguration *runConfig);
- AbstractRemoteLinuxDebugSupport(ProjectExplorer::RunConfiguration *runConfig,
- Debugger::DebuggerEngine *engine);
- ~AbstractRemoteLinuxDebugSupport();
+ LinuxDeviceDebugSupport(ProjectExplorer::RunConfiguration *runConfig,
+ Debugger::DebuggerEngine *engine);
+ ~LinuxDeviceDebugSupport();
+
+ void setApplicationRunnerPreRunAction(ProjectExplorer::DeviceApplicationHelperAction *action);
+ void setApplicationRunnerPostRunAction(ProjectExplorer::DeviceApplicationHelperAction *action);
private slots:
void handleRemoteSetupRequested();
- void handleSshError(const QString &error);
+ void handleAppRunnerError(const QString &error);
void startExecution();
void handleDebuggingFinished();
void handleRemoteOutput(const QByteArray &output);
void handleRemoteErrorOutput(const QByteArray &output);
void handleProgressReport(const QString &progressOutput);
void handleRemoteProcessStarted();
- void handleRemoteProcessFinished(qint64 exitCode);
+ void handleAppRunnerFinished(bool success);
+ void handlePortsGathererError(const QString &message);
+ void handlePortListReady();
private:
- virtual AbstractRemoteLinuxApplicationRunner *runner() const = 0;
-
void handleAdapterSetupFailed(const QString &error);
void handleAdapterSetupDone();
void setFinished();
bool setPort(int &port);
void showMessage(const QString &msg, int channel);
- Internal::AbstractRemoteLinuxDebugSupportPrivate * const d;
-};
-
-
-class REMOTELINUX_EXPORT RemoteLinuxDebugSupport : public AbstractRemoteLinuxDebugSupport
-{
- Q_OBJECT
-public:
- RemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig, Debugger::DebuggerEngine *engine);
- ~RemoteLinuxDebugSupport();
-
-private:
- AbstractRemoteLinuxApplicationRunner *runner() const;
-
- Internal::RemoteLinuxDebugSupportPrivate * const d;
+ Internal::LinuxDeviceDebugSupportPrivate * const d;
};
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxruncontrol.cpp b/src/plugins/remotelinux/remotelinuxruncontrol.cpp
index b550c21331..3492cf3a73 100644
--- a/src/plugins/remotelinux/remotelinuxruncontrol.cpp
+++ b/src/plugins/remotelinux/remotelinuxruncontrol.cpp
@@ -29,10 +29,13 @@
#include "remotelinuxruncontrol.h"
-#include "remotelinuxapplicationrunner.h"
#include "remotelinuxrunconfiguration.h"
+#include "remotelinuxutils.h"
+#include <projectexplorer/devicesupport/deviceapplicationrunner.h>
+#include <projectexplorer/profileinformation.h>
#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/target.h>
#include <utils/qtcassert.h>
#include <QString>
@@ -42,120 +45,112 @@ using namespace ProjectExplorer;
namespace RemoteLinux {
-using ProjectExplorer::RunConfiguration;
+class RemoteLinuxRunControl::RemoteLinuxRunControlPrivate
+{
+public:
+ bool running;
+ ProjectExplorer::DeviceApplicationRunner runner;
+ IDevice::ConstPtr device;
+ QString remoteExecutable;
+ QString arguments;
+ QString prefix;
+ QByteArray stopCommand;
+};
-AbstractRemoteLinuxRunControl::AbstractRemoteLinuxRunControl(RunConfiguration *rc)
- : RunControl(rc, ProjectExplorer::NormalRunMode)
- , m_running(false)
+RemoteLinuxRunControl::RemoteLinuxRunControl(RunConfiguration *rc)
+ : RunControl(rc, ProjectExplorer::NormalRunMode), d(new RemoteLinuxRunControlPrivate)
{
+ d->running = false;
+ d->device = DeviceProfileInformation::device(rc->target()->profile());
+ const RemoteLinuxRunConfiguration * const lrc = qobject_cast<RemoteLinuxRunConfiguration *>(rc);
+ d->remoteExecutable = lrc->remoteExecutableFilePath();
+ d->arguments = lrc->arguments();
+ d->prefix = lrc->commandPrefix();
+ d->stopCommand = RemoteLinuxUtils::killApplicationCommandLine(d->remoteExecutable).toUtf8();
}
-AbstractRemoteLinuxRunControl::~AbstractRemoteLinuxRunControl()
+RemoteLinuxRunControl::~RemoteLinuxRunControl()
{
+ delete d;
}
-void AbstractRemoteLinuxRunControl::start()
+void RemoteLinuxRunControl::start()
{
- m_running = true;
+ d->running = true;
emit started();
- disconnect(runner(), 0, this, 0);
- connect(runner(), SIGNAL(error(QString)), SLOT(handleSshError(QString)));
- connect(runner(), SIGNAL(readyForExecution()), SLOT(startExecution()));
- connect(runner(), SIGNAL(remoteErrorOutput(QByteArray)),
+ d->runner.disconnect(this);
+ connect(&d->runner, SIGNAL(reportError(QString)), SLOT(handleErrorMessage(QString)));
+ connect(&d->runner, SIGNAL(remoteStderr(QByteArray)),
SLOT(handleRemoteErrorOutput(QByteArray)));
- connect(runner(), SIGNAL(remoteOutput(QByteArray)),
- SLOT(handleRemoteOutput(QByteArray)));
- connect(runner(), SIGNAL(remoteProcessStarted()),
- SLOT(handleRemoteProcessStarted()));
- connect(runner(), SIGNAL(remoteProcessFinished(qint64)),
- SLOT(handleRemoteProcessFinished(qint64)));
- connect(runner(), SIGNAL(reportProgress(QString)),
- SLOT(handleProgressReport(QString)));
- runner()->start();
+ connect(&d->runner, SIGNAL(remoteStdout(QByteArray)), SLOT(handleRemoteOutput(QByteArray)));
+ connect(&d->runner, SIGNAL(finished(bool)), SLOT(handleRunnerFinished()));
+ connect(&d->runner, SIGNAL(reportProgress(QString)), SLOT(handleProgressReport(QString)));
+ const QString commandLine = QString::fromLatin1("%1 %2 %3")
+ .arg(d->prefix, d->remoteExecutable, d->arguments);
+ d->runner.start(d->device, commandLine.toUtf8());
}
-RunControl::StopResult AbstractRemoteLinuxRunControl::stop()
+RunControl::StopResult RemoteLinuxRunControl::stop()
{
- runner()->stop();
+ d->runner.stop(d->stopCommand);
return AsynchronousStop;
}
-void AbstractRemoteLinuxRunControl::handleSshError(const QString &error)
+void RemoteLinuxRunControl::handleErrorMessage(const QString &error)
{
- handleError(error);
- setFinished();
+ appendMessage(error, Utils::ErrorMessageFormat);
}
-void AbstractRemoteLinuxRunControl::startExecution()
+void RemoteLinuxRunControl::handleRunnerFinished()
{
- appendMessage(tr("Starting remote process...\n"), Utils::NormalMessageFormat);
- runner()->startExecution(QString::fromLatin1("%1 %2 %3")
- .arg(runner()->commandPrefix())
- .arg(runner()->remoteExecutable())
- .arg(runner()->arguments()).toUtf8());
-}
-
-void AbstractRemoteLinuxRunControl::handleRemoteProcessFinished(qint64 exitCode)
-{
- if (exitCode != AbstractRemoteLinuxApplicationRunner::InvalidExitCode) {
- appendMessage(tr("Finished running remote process. Exit code was %1.\n")
- .arg(exitCode), Utils::NormalMessageFormat);
- }
setFinished();
}
-void AbstractRemoteLinuxRunControl::handleRemoteOutput(const QByteArray &output)
+void RemoteLinuxRunControl::handleRemoteOutput(const QByteArray &output)
{
appendMessage(QString::fromUtf8(output), Utils::StdOutFormatSameLine);
}
-void AbstractRemoteLinuxRunControl::handleRemoteErrorOutput(const QByteArray &output)
+void RemoteLinuxRunControl::handleRemoteErrorOutput(const QByteArray &output)
{
appendMessage(QString::fromUtf8(output), Utils::StdErrFormatSameLine);
}
-void AbstractRemoteLinuxRunControl::handleProgressReport(const QString &progressString)
+void RemoteLinuxRunControl::handleProgressReport(const QString &progressString)
{
appendMessage(progressString + QLatin1Char('\n'), Utils::NormalMessageFormat);
}
-bool AbstractRemoteLinuxRunControl::isRunning() const
+bool RemoteLinuxRunControl::isRunning() const
{
- return m_running;
+ return d->running;
}
-QIcon AbstractRemoteLinuxRunControl::icon() const
+QIcon RemoteLinuxRunControl::icon() const
{
return QIcon(ProjectExplorer::Constants::ICON_RUN_SMALL);
}
-void AbstractRemoteLinuxRunControl::handleError(const QString &errString)
+void RemoteLinuxRunControl::setApplicationRunnerPreRunAction(DeviceApplicationHelperAction *action)
{
- stop();
- appendMessage(errString, Utils::ErrorMessageFormat);
+ d->runner.setPreRunAction(action);
}
-void AbstractRemoteLinuxRunControl::setFinished()
+void RemoteLinuxRunControl::setApplicationRunnerPostRunAction(DeviceApplicationHelperAction *action)
{
- disconnect(runner(), 0, this, 0);
- m_running = false;
- emit finished();
+ d->runner.setPostRunAction(action);
}
-
-RemoteLinuxRunControl::RemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig)
- : AbstractRemoteLinuxRunControl(runConfig),
- m_runner(new GenericRemoteLinuxApplicationRunner(qobject_cast<RemoteLinuxRunConfiguration *>(runConfig), this))
-{
-}
-
-RemoteLinuxRunControl::~RemoteLinuxRunControl()
+void RemoteLinuxRunControl::overrideStopCommandLine(const QByteArray &commandLine)
{
+ d->stopCommand = commandLine;
}
-AbstractRemoteLinuxApplicationRunner *RemoteLinuxRunControl::runner() const
+void RemoteLinuxRunControl::setFinished()
{
- return m_runner;
+ d->runner.disconnect(this);
+ d->running = false;
+ emit finished();
}
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxruncontrol.h b/src/plugins/remotelinux/remotelinuxruncontrol.h
index adde0a01e4..86f690d66a 100644
--- a/src/plugins/remotelinux/remotelinuxruncontrol.h
+++ b/src/plugins/remotelinux/remotelinuxruncontrol.h
@@ -34,54 +34,38 @@
#include <projectexplorer/runconfiguration.h>
-QT_FORWARD_DECLARE_CLASS(QString)
+namespace ProjectExplorer { class DeviceApplicationHelperAction; }
namespace RemoteLinux {
-class AbstractRemoteLinuxApplicationRunner;
-class REMOTELINUX_EXPORT AbstractRemoteLinuxRunControl : public ProjectExplorer::RunControl
+class REMOTELINUX_EXPORT RemoteLinuxRunControl : public ProjectExplorer::RunControl
{
Q_OBJECT
- Q_DISABLE_COPY(AbstractRemoteLinuxRunControl)
public:
- explicit AbstractRemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig);
- virtual ~AbstractRemoteLinuxRunControl();
+ explicit RemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig);
+ virtual ~RemoteLinuxRunControl();
virtual void start();
virtual StopResult stop();
virtual bool isRunning() const;
virtual QIcon icon() const;
- virtual AbstractRemoteLinuxApplicationRunner *runner() const = 0;
+ void setApplicationRunnerPreRunAction(ProjectExplorer::DeviceApplicationHelperAction *action);
+ void setApplicationRunnerPostRunAction(ProjectExplorer::DeviceApplicationHelperAction *action);
+ void overrideStopCommandLine(const QByteArray &commandLine);
private slots:
- void startExecution();
- void handleSshError(const QString &error);
- void handleRemoteProcessStarted() {}
- void handleRemoteProcessFinished(qint64 exitCode);
+ void handleErrorMessage(const QString &error);
+ void handleRunnerFinished();
void handleRemoteOutput(const QByteArray &output);
void handleRemoteErrorOutput(const QByteArray &output);
void handleProgressReport(const QString &progressString);
private:
void setFinished();
- void handleError(const QString &errString);
-
- bool m_running;
-};
-
-
-class REMOTELINUX_EXPORT RemoteLinuxRunControl : public AbstractRemoteLinuxRunControl
-{
- Q_OBJECT
-
-public:
- explicit RemoteLinuxRunControl(ProjectExplorer::RunConfiguration *runConfig);
- virtual ~RemoteLinuxRunControl();
-private:
- virtual AbstractRemoteLinuxApplicationRunner *runner() const;
- AbstractRemoteLinuxApplicationRunner * const m_runner;
+ class RemoteLinuxRunControlPrivate;
+ RemoteLinuxRunControlPrivate * const d;
};
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp
index 36e2820b36..449ef7832f 100644
--- a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp
+++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp
@@ -89,14 +89,14 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Ru
if (mode == ProjectExplorer::NormalRunMode)
return new RemoteLinuxRunControl(rc);
- DebuggerStartParameters params = AbstractRemoteLinuxDebugSupport::startParameters(rc);
+ DebuggerStartParameters params = LinuxDeviceDebugSupport::startParameters(rc);
if (mode == ProjectExplorer::DebugRunModeWithBreakOnMain)
params.breakOnMain = true;
DebuggerRunControl * const runControl = DebuggerPlugin::createDebugger(params, rc);
if (!runControl)
return 0;
- RemoteLinuxDebugSupport *debugSupport =
- new RemoteLinuxDebugSupport(rc, runControl->engine());
+ LinuxDeviceDebugSupport * const debugSupport =
+ new LinuxDeviceDebugSupport(rc, runControl->engine());
connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished()));
return runControl;
}
diff --git a/src/plugins/remotelinux/remotelinuxutils.cpp b/src/plugins/remotelinux/remotelinuxutils.cpp
index 481fcb2afe..80d2e42863 100644
--- a/src/plugins/remotelinux/remotelinuxutils.cpp
+++ b/src/plugins/remotelinux/remotelinuxutils.cpp
@@ -41,9 +41,14 @@ using namespace ExtensionSystem;
namespace RemoteLinux {
-QString RemoteLinuxUtils::deviceConfigurationName(const LinuxDeviceConfiguration::ConstPtr &devConf)
+QString RemoteLinuxUtils::killApplicationCommandLine(const QString &applicationFilePath)
{
- return devConf ? devConf->displayName() : QCoreApplication::translate("RemoteLinux", "(No device)");
+ return QString::fromLatin1("cd /proc; for pid in `ls -d [0123456789]*`; "
+ "do "
+ "if [ \"`readlink /proc/$pid/exe`\" = \"%1\" ]; then "
+ " kill $pid; sleep 1; kill -9 $pid; "
+ "fi; "
+ "done").arg(applicationFilePath);
}
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxutils.h b/src/plugins/remotelinux/remotelinuxutils.h
index 69ae6deeab..403a60d8d5 100644
--- a/src/plugins/remotelinux/remotelinuxutils.h
+++ b/src/plugins/remotelinux/remotelinuxutils.h
@@ -40,7 +40,7 @@ class LinuxDeviceConfiguration;
class REMOTELINUX_EXPORT RemoteLinuxUtils
{
public:
- static QString deviceConfigurationName(const QSharedPointer<const LinuxDeviceConfiguration> &devConf);
+ static QString killApplicationCommandLine(const QString &applicationFilePath);
};
} // namespace RemoteLinux