From b90e3bbd8bea27ad915a4d9033e0d5bda26f5667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20N=C3=A4tterlund?= Date: Thu, 30 May 2013 13:53:28 +0200 Subject: [PATCH] QNX/RemoteLinux/Madde: Made device test more generic Any device inheriting from LinuxDevice can now implement a createDeviceTester() method to return their own AbstractLinuxDeviceTester that runs when the device wizard is completed, or when the Test Device button is pressed. The MaddeDevice implementation of the device actions now completely matches that of LinuxDevice, so those are removed. The QNX device check was improved with additional tool checking. Change-Id: Ie761b7cfc5591238aa2a18a74fe1843fb2cdbeaa Reviewed-by: Christian Kandeler Reviewed-by: Nicolas Arnaud-Cormos Reviewed-by: Tobias Hunger --- src/plugins/madde/maddedevice.cpp | 38 +--- src/plugins/madde/maddedevice.h | 5 +- src/plugins/qnx/qnx.pro | 6 +- src/plugins/qnx/qnx.qbs | 2 + src/plugins/qnx/qnxdeviceconfiguration.cpp | 6 + src/plugins/qnx/qnxdeviceconfiguration.h | 2 + .../qnx/qnxdeviceconfigurationwizard.cpp | 4 +- src/plugins/qnx/qnxdevicetester.cpp | 163 ++++++++++++++++++ src/plugins/qnx/qnxdevicetester.h | 84 +++++++++ src/plugins/remotelinux/linuxdevice.cpp | 7 +- src/plugins/remotelinux/linuxdevice.h | 2 + 11 files changed, 277 insertions(+), 42 deletions(-) create mode 100644 src/plugins/qnx/qnxdevicetester.cpp create mode 100644 src/plugins/qnx/qnxdevicetester.h diff --git a/src/plugins/madde/maddedevice.cpp b/src/plugins/madde/maddedevice.cpp index f8b963246e2..e8f3c5546f4 100644 --- a/src/plugins/madde/maddedevice.cpp +++ b/src/plugins/madde/maddedevice.cpp @@ -41,7 +41,6 @@ using namespace RemoteLinux; namespace Madde { namespace Internal { -const char MaddeDeviceTestActionId[] = "Madde.DeviceTestAction"; MaddeDevice::Ptr MaddeDevice::create() { @@ -78,38 +77,6 @@ QString MaddeDevice::displayType() const return maddeDisplayType(type()); } -QList MaddeDevice::actionIds() const -{ - return QList() << Core::Id(MaddeDeviceTestActionId) - << Core::Id(Constants::GenericDeployKeyToDeviceActionId); -} - -QString MaddeDevice::displayNameForActionId(Core::Id actionId) const -{ - QTC_ASSERT(actionIds().contains(actionId), return QString()); - - if (actionId == MaddeDeviceTestActionId) - return tr("Test"); - if (actionId == Constants::GenericDeployKeyToDeviceActionId) - return tr("Deploy Public Key..."); - return QString(); // Can't happen. -} - -void MaddeDevice::executeAction(Core::Id actionId, QWidget *parent) const -{ - QTC_ASSERT(actionIds().contains(actionId), return); - - QDialog *d = 0; - const IDevice::ConstPtr device = sharedFromThis(); - if (actionId == MaddeDeviceTestActionId) - d = new LinuxDeviceTestDialog(device, new MaddeDeviceTester, parent); - else if (actionId == Constants::GenericDeployKeyToDeviceActionId) - d = PublicKeyDeploymentDialog::createDialog(device, parent); - if (d) - d->exec(); - delete d; -} - QString MaddeDevice::maddeDisplayType(Core::Id type) { if (type == Maemo5OsType) @@ -144,5 +111,10 @@ QSize MaddeDevice::packageManagerIconSize(Core::Id type) return QSize(); } +AbstractLinuxDeviceTester *MaddeDevice::createDeviceTester() const +{ + return new MaddeDeviceTester; +} + } // namespace Internal } // namespace Madde diff --git a/src/plugins/madde/maddedevice.h b/src/plugins/madde/maddedevice.h index 0d956147753..463c2252319 100644 --- a/src/plugins/madde/maddedevice.h +++ b/src/plugins/madde/maddedevice.h @@ -49,9 +49,6 @@ public: Origin origin = ManuallyAdded, Core::Id id = Core::Id()); QString displayType() const; - QList actionIds() const; - QString displayNameForActionId(Core::Id actionId) const; - void executeAction(Core::Id actionId, QWidget *parent) const; ProjectExplorer::IDevice::Ptr clone() const; static QString maddeDisplayType(Core::Id type); @@ -61,6 +58,8 @@ public: static QSize packageManagerIconSize(Core::Id type); + RemoteLinux::AbstractLinuxDeviceTester *createDeviceTester() const; + private: MaddeDevice(); MaddeDevice(const QString &name, Core::Id type, MachineType machineType, diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro index a50ed1d8b53..16f02fa6f29 100644 --- a/src/plugins/qnx/qnx.pro +++ b/src/plugins/qnx/qnx.pro @@ -92,7 +92,8 @@ SOURCES += qnxplugin.cpp \ bardescriptoreditorabstractpanelwidget.cpp \ blackberrysetupwizard.cpp \ blackberrysetupwizardpages.cpp \ - blackberryutils.cpp + blackberryutils.cpp \ + qnxdevicetester.cpp HEADERS += qnxplugin.h\ qnxconstants.h \ @@ -184,7 +185,8 @@ HEADERS += qnxplugin.h\ bardescriptoreditorabstractpanelwidget.h \ blackberrysetupwizard.h \ blackberrysetupwizardpages.h \ - blackberryutils.h + blackberryutils.h \ + qnxdevicetester.h FORMS += \ blackberrydeviceconfigurationwizardsetuppage.ui \ diff --git a/src/plugins/qnx/qnx.qbs b/src/plugins/qnx/qnx.qbs index 83d168aab32..214e43e3028 100644 --- a/src/plugins/qnx/qnx.qbs +++ b/src/plugins/qnx/qnx.qbs @@ -208,6 +208,8 @@ QtcPlugin { "qnxdeviceconfigurationwizard.h", "qnxdeviceconfigurationwizardpages.cpp", "qnxdeviceconfigurationwizardpages.h", + "qnxdevicetester.cpp", + "qnxdevicetester.h", "qnxplugin.cpp", "qnxplugin.h", "qnxqtversion.cpp", diff --git a/src/plugins/qnx/qnxdeviceconfiguration.cpp b/src/plugins/qnx/qnxdeviceconfiguration.cpp index 50cc3a89cd7..7fb16988a66 100644 --- a/src/plugins/qnx/qnxdeviceconfiguration.cpp +++ b/src/plugins/qnx/qnxdeviceconfiguration.cpp @@ -30,6 +30,7 @@ ****************************************************************************/ #include "qnxdeviceconfiguration.h" +#include "qnxdevicetester.h" #include @@ -185,3 +186,8 @@ ProjectExplorer::DeviceProcessList *QnxDeviceConfiguration::createProcessListMod { return new QnxDeviceProcessList(sharedFromThis(), parent); } + +RemoteLinux::AbstractLinuxDeviceTester *QnxDeviceConfiguration::createDeviceTester() const +{ + return new QnxDeviceTester; +} diff --git a/src/plugins/qnx/qnxdeviceconfiguration.h b/src/plugins/qnx/qnxdeviceconfiguration.h index f1645d6793d..1e2a9d0aefe 100644 --- a/src/plugins/qnx/qnxdeviceconfiguration.h +++ b/src/plugins/qnx/qnxdeviceconfiguration.h @@ -54,6 +54,8 @@ public: ProjectExplorer::PortsGatheringMethod::Ptr portsGatheringMethod() const; ProjectExplorer::DeviceProcessList *createProcessListModel(QObject *parent) const; + RemoteLinux::AbstractLinuxDeviceTester *createDeviceTester() const; + QString displayType() const; protected: diff --git a/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp b/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp index cc8b9929b03..c14d69530ca 100644 --- a/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp +++ b/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include using namespace ProjectExplorer; @@ -77,8 +76,7 @@ IDevice::Ptr QnxDeviceConfigurationWizard::device() device->setSshParameters(sshParams); device->setFreePorts(Utils::PortList::fromString(QLatin1String("10000-10100"))); - RemoteLinux::GenericLinuxDeviceTester *devTester = new RemoteLinux::GenericLinuxDeviceTester(this); - RemoteLinux::LinuxDeviceTestDialog dlg(device, devTester, this); + RemoteLinux::LinuxDeviceTestDialog dlg(device, device->createDeviceTester(), this); dlg.exec(); return device; diff --git a/src/plugins/qnx/qnxdevicetester.cpp b/src/plugins/qnx/qnxdevicetester.cpp new file mode 100644 index 00000000000..c7ce3564833 --- /dev/null +++ b/src/plugins/qnx/qnxdevicetester.cpp @@ -0,0 +1,163 @@ +/************************************************************************** +** +** Copyright (C) 2011 - 2013 Research In Motion +** +** Contact: Research In Motion (blackberry-qt@qnx.com) +** Contact: KDAB (info@kdab.com) +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qnxdevicetester.h" + +#include +#include + +using namespace Qnx; +using namespace Qnx::Internal; + +QnxDeviceTester::QnxDeviceTester(QObject *parent) + : RemoteLinux::AbstractLinuxDeviceTester(parent) + , m_result(TestSuccess) + , m_state(Inactive) + , m_currentCommandIndex(-1) +{ + m_genericTester = new RemoteLinux::GenericLinuxDeviceTester(this); + + m_processRunner = new QSsh::SshRemoteProcessRunner(this); + connect(m_processRunner, SIGNAL(connectionError()), SLOT(handleConnectionError())); + connect(m_processRunner, SIGNAL(processClosed(int)), SLOT(handleProcessFinished(int))); + + m_commandsToTest << QLatin1String("awk") + << QLatin1String("grep") + << QLatin1String("kill") + << QLatin1String("netstat") + << QLatin1String("print") + << QLatin1String("printf") + << QLatin1String("ps") + << QLatin1String("read") + << QLatin1String("sed") + << QLatin1String("sleep") + << QLatin1String("uname"); +} + +void QnxDeviceTester::testDevice(const ProjectExplorer::IDevice::ConstPtr &deviceConfiguration) +{ + QTC_ASSERT(m_state == Inactive, return); + + m_deviceConfiguration = deviceConfiguration; + + connect(m_genericTester, SIGNAL(progressMessage(QString)), SIGNAL(progressMessage(QString))); + connect(m_genericTester, SIGNAL(errorMessage(QString)), SIGNAL(errorMessage(QString))); + connect(m_genericTester, SIGNAL(finished(RemoteLinux::AbstractLinuxDeviceTester::TestResult)), + SLOT(handleGenericTestFinished(RemoteLinux::AbstractLinuxDeviceTester::TestResult))); + + m_state = GenericTest; + m_genericTester->testDevice(deviceConfiguration); +} + +void QnxDeviceTester::stopTest() +{ + QTC_ASSERT(m_state != Inactive, return); + + switch (m_state) { + case Inactive: + break; + case GenericTest: + m_genericTester->stopTest(); + break; + case CommandsTest: + m_processRunner->cancel(); + break; + } + + m_result = TestFailure; + setFinished(); +} + +void QnxDeviceTester::handleGenericTestFinished(RemoteLinux::AbstractLinuxDeviceTester::TestResult result) +{ + QTC_ASSERT(m_state == GenericTest, return); + + if (result == TestFailure) { + m_result = TestFailure; + setFinished(); + return; + } + + m_state = CommandsTest; + testNextCommand(); +} + +void QnxDeviceTester::handleProcessFinished(int exitStatus) +{ + QTC_ASSERT(m_state == CommandsTest, return); + + const QString command = m_commandsToTest[m_currentCommandIndex]; + if (exitStatus == QSsh::SshRemoteProcess::NormalExit) { + if (m_processRunner->processExitCode() == 0) { + emit progressMessage(tr("%1 found.\n").arg(command)); + } else { + emit errorMessage(tr("%1 not found.\n").arg(command)); + m_result = TestFailure; + } + } else { + emit errorMessage(tr("An error occurred checking for %1.\n").arg(command)); + m_result = TestFailure; + } + testNextCommand(); +} + +void QnxDeviceTester::handleConnectionError() +{ + QTC_ASSERT(m_state == CommandsTest, return); + + m_result = TestFailure; + emit errorMessage(tr("SSH connection error: %1\n").arg(m_processRunner->lastConnectionErrorString())); + setFinished(); +} + +void QnxDeviceTester::testNextCommand() +{ + ++m_currentCommandIndex; + + if (m_currentCommandIndex >= m_commandsToTest.size()) { + setFinished(); + return; + } + + QString command = m_commandsToTest[m_currentCommandIndex]; + emit progressMessage(tr("Checking for %1...").arg(command)); + + m_processRunner->run("command -v " + command.toLatin1(), m_deviceConfiguration->sshParameters()); +} + +void QnxDeviceTester::setFinished() +{ + m_state = Inactive; + disconnect(m_genericTester, 0, this, 0); + if (m_processRunner) + disconnect(m_processRunner, 0, this, 0); + emit finished(m_result); +} diff --git a/src/plugins/qnx/qnxdevicetester.h b/src/plugins/qnx/qnxdevicetester.h new file mode 100644 index 00000000000..ccec636f08f --- /dev/null +++ b/src/plugins/qnx/qnxdevicetester.h @@ -0,0 +1,84 @@ +/************************************************************************** +** +** Copyright (C) 2011 - 2013 Research In Motion +** +** Contact: Research In Motion (blackberry-qt@qnx.com) +** Contact: KDAB (info@kdab.com) +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QNX_INTERNAL_QNXDEVICETESTER_H +#define QNX_INTERNAL_QNXDEVICETESTER_H + +#include + +#include + +namespace QSsh { +class SshRemoteProcessRunner; +} + +namespace Qnx { +namespace Internal { + +class QnxDeviceTester : public RemoteLinux::AbstractLinuxDeviceTester +{ + Q_OBJECT +public: + explicit QnxDeviceTester(QObject *parent = 0); + + void testDevice(const ProjectExplorer::IDevice::ConstPtr &deviceConfiguration); + void stopTest(); + +private slots: + void handleGenericTestFinished(RemoteLinux::AbstractLinuxDeviceTester::TestResult result); + + void handleProcessFinished(int exitStatus); + void handleConnectionError(); + +private: + enum State { + Inactive, + GenericTest, + CommandsTest + }; + + void testNextCommand(); + void setFinished(); + + RemoteLinux::GenericLinuxDeviceTester *m_genericTester; + ProjectExplorer::IDevice::ConstPtr m_deviceConfiguration; + TestResult m_result; + State m_state; + + int m_currentCommandIndex; + QStringList m_commandsToTest; + QSsh::SshRemoteProcessRunner *m_processRunner; +}; + +} // namespace Internal +} // namespace Qnx + +#endif // QNX_INTERNAL_QNXDEVICETESTER_H diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 70796e54cd4..8c530ac3ac3 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -214,7 +214,7 @@ void LinuxDevice::executeAction(Core::Id actionId, QWidget *parent) const QDialog *d = 0; const LinuxDevice::ConstPtr device = sharedFromThis().staticCast(); if (actionId == Constants::GenericTestDeviceActionId) - d = new LinuxDeviceTestDialog(device, new GenericLinuxDeviceTester, parent); + d = new LinuxDeviceTestDialog(device, createDeviceTester(), parent); else if (actionId == Constants::GenericDeployKeyToDeviceActionId) d = PublicKeyDeploymentDialog::createDialog(device, parent); if (d) @@ -264,4 +264,9 @@ DeviceProcessList *LinuxDevice::createProcessListModel(QObject *parent) const return new LinuxDeviceProcessList(sharedFromThis(), parent); } +AbstractLinuxDeviceTester *LinuxDevice::createDeviceTester() const +{ + return new GenericLinuxDeviceTester; +} + } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h index 0daa95e58e8..0ec84cd44e0 100644 --- a/src/plugins/remotelinux/linuxdevice.h +++ b/src/plugins/remotelinux/linuxdevice.h @@ -41,6 +41,7 @@ namespace Utils { class PortList; } namespace RemoteLinux { namespace Internal { class LinuxDevicePrivate; } +class AbstractLinuxDeviceTester; class REMOTELINUX_EXPORT LinuxDeviceProcessSupport : public ProjectExplorer::DeviceProcessSupport { @@ -73,6 +74,7 @@ public: ProjectExplorer::PortsGatheringMethod::Ptr portsGatheringMethod() const; bool canCreateProcessModel() const { return true; } ProjectExplorer::DeviceProcessList *createProcessListModel(QObject *parent) const; + virtual AbstractLinuxDeviceTester *createDeviceTester() const; protected: LinuxDevice() {}