diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.cpp index be6d134ad61..047e9b2606d 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.cpp @@ -37,6 +37,7 @@ #include "maemodeviceconfigurations.h" #include "maemoglobal.h" +#include "maemousedportsgatherer.h" #include @@ -52,6 +53,7 @@ MaemoConfigTestDialog::MaemoConfigTestDialog(const MaemoDeviceConfig &config, QW : QDialog(parent) , m_ui(new Ui_MaemoConfigTestDialog) , m_config(config) + , m_portsGatherer(new MaemoUsedPortsGatherer(this)) { setAttribute(Qt::WA_DeleteOnClose); @@ -59,6 +61,10 @@ MaemoConfigTestDialog::MaemoConfigTestDialog(const MaemoDeviceConfig &config, QW m_closeButton = m_ui->buttonBox->button(QDialogButtonBox::Close); connect(m_closeButton, SIGNAL(clicked()), SLOT(stopConfigTest())); + connect(m_portsGatherer, SIGNAL(error(QString)), + SLOT(handlePortListFailure(QString))); + connect(m_portsGatherer, SIGNAL(portListReady()), + SLOT(handlePortListReady())); startConfigTest(); } @@ -151,6 +157,37 @@ void MaemoConfigTestDialog::handleMadDeveloperTestResult(int exitStatus) + QLatin1String("
") + tr("Mad Developer is not installed.
" "You will not be able to deploy to this device.")); } + if (m_config.freePorts().hasMore()) + m_portsGatherer->start(m_testProcessRunner->connection(), + m_config.freePorts()); + else + finish(); +} + +void MaemoConfigTestDialog::handlePortListFailure(const QString &errMsg) +{ + m_ui->testResultEdit->appendPlainText(tr("Error retrieving list of used ports: %1") + .arg(errMsg)); + finish(); +} + +void MaemoConfigTestDialog::handlePortListReady() +{ + const QList &usedPorts = m_portsGatherer->usedPorts(); + QString output; + if (usedPorts.isEmpty()) { + output = tr("All specified ports are available."); + } else { + output = tr("The following supposedly free ports are being used on the device:"); + foreach (const int port, usedPorts) + output += QLatin1Char(' ') + QString::number(port); + } + m_ui->testResultEdit->appendPlainText(output); + finish(); +} + +void MaemoConfigTestDialog::finish() +{ if (m_ui->errorLabel->text().isEmpty()) { QPalette palette = m_ui->errorLabel->palette(); palette.setColor(m_ui->errorLabel->foregroundRole(), diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.h b/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.h index 19a3caf75fe..5089266a4a2 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.h @@ -51,6 +51,7 @@ namespace Qt4ProjectManager { namespace Internal { class MaemoDeviceConfig; +class MaemoUsedPortsGatherer; /** * A dialog that runs a test of a device configuration. @@ -67,12 +68,15 @@ private slots: void processSshOutput(const QByteArray &output); void handleConnectionError(); void handleTestProcessFinished(int exitStatus); + void handlePortListReady(); + void handlePortListFailure(const QString &errMsg); private: void startConfigTest(); QString parseTestOutput(); void handleGeneralTestResult(int exitStatus); void handleMadDeveloperTestResult(int exitStatus); + void finish(); Ui_MaemoConfigTestDialog *m_ui; QPushButton *m_closeButton; @@ -81,6 +85,7 @@ private: QSharedPointer m_testProcessRunner; QString m_deviceTestOutput; bool m_qtVersionOk; + MaemoUsedPortsGatherer *const m_portsGatherer; enum DeviceTest { GeneralTest, MadDeveloperTest }; DeviceTest m_currentTest; diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.ui b/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.ui index e91549702c3..9afda1b87f3 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.ui +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoconfigtestdialog.ui @@ -6,8 +6,8 @@ 0 0 - 661 - 324 + 684 + 544 diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h index 1426d16718d..ede7ae12400 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeviceconfigurations.h @@ -72,6 +72,19 @@ public: m_ranges.removeFirst(); return next; } + QString toString() const + { + QString stringRep; + foreach (const Range &range, m_ranges) { + stringRep += QString::number(range.first); + if (range.second != range.first) + stringRep += QLatin1Char('-') + QString::number(range.second); + stringRep += QLatin1Char(','); + } + if (!stringRep.isEmpty()) + stringRep.remove(stringRep.length() - 1, 1); // Trailing comma. + return stringRep; + } private: QList m_ranges; diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemousedportsgatherer.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemousedportsgatherer.cpp new file mode 100644 index 00000000000..eb82bbf6791 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemousedportsgatherer.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Creator. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "maemousedportsgatherer.h" + +#include "maemoglobal.h" + +#include + +using namespace Core; + +namespace Qt4ProjectManager { +namespace Internal { + +MaemoUsedPortsGatherer::MaemoUsedPortsGatherer(QObject *parent) : + QObject(parent), m_running(false) +{ +} + +MaemoUsedPortsGatherer::~MaemoUsedPortsGatherer() {} + +void MaemoUsedPortsGatherer::start(const Core::SshConnection::Ptr &connection, + const MaemoPortList &portList) +{ + if (m_running) + qWarning("Unexpected call of %s in running state", Q_FUNC_INFO); + m_remoteStdout.clear(); + m_remoteStderr.clear(); + m_procRunner = SshRemoteProcessRunner::create(connection); + connect(m_procRunner.data(), SIGNAL(connectionError(Core::SshError)), + SLOT(handleConnectionError())); + connect(m_procRunner.data(), SIGNAL(processClosed(int)), + SLOT(handleProcessClosed(int))); + connect(m_procRunner.data(), SIGNAL(processOutputAvailable(QByteArray)), + SLOT(handleRemoteStdOut(QByteArray))); + connect(m_procRunner.data(), SIGNAL(processErrorOutputAvailable(QByteArray)), + SLOT(handleRemoteStdErr(QByteArray))); + const QString command = MaemoGlobal::remoteSudo() + + QLatin1String(" lsof -nPi4tcp:") + portList.toString() + + QLatin1String(" -F n |grep '^n' |sed -r 's/[^:]*:([[:digit:]]+).*/\\1/g' |sort -n |uniq"); + m_procRunner->run(command.toUtf8()); + m_running = true; +} + +void MaemoUsedPortsGatherer::stop() +{ + if (!m_running) + return; + m_running = false; + disconnect(m_procRunner->connection().data(), 0, this, 0); + if (m_procRunner->process()) + m_procRunner->process()->closeChannel(); +} + +QList MaemoUsedPortsGatherer::usedPorts() const +{ + QList ports; + const QList &portStrings = m_remoteStdout.split('\n'); + foreach (const QByteArray &portString, portStrings) { + if (portString.isEmpty()) + continue; + bool ok; + const int port = portString.toInt(&ok); + if (ok) { + ports << port; + } else { + qWarning("%s: Unexpected string '%s' is not a port.", + Q_FUNC_INFO, portString.data()); + } + } + return ports; +} + +void MaemoUsedPortsGatherer::handleConnectionError() +{ + if (!m_running) + return; + emit error(tr("Connection error: %1"). + arg(m_procRunner->connection()->errorString())); + stop(); +} + +void MaemoUsedPortsGatherer::handleProcessClosed(int exitStatus) +{ + if (!m_running) + return; + QString errMsg; + switch (exitStatus) { + case SshRemoteProcess::FailedToStart: + errMsg = tr("Could not start remote process: %1") + .arg(m_procRunner->process()->errorString()); + break; + case SshRemoteProcess::KilledBySignal: + errMsg = tr("Remote process crashed: %1") + .arg(m_procRunner->process()->errorString()); + break; + case SshRemoteProcess::ExitedNormally: + if (m_procRunner->process()->exitCode() == 0) { + emit portListReady(); + } else { + errMsg = tr("Remote process failed: %1") + .arg(m_procRunner->process()->errorString()); + } + break; + default: + Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid exit status"); + } + + if (!errMsg.isEmpty()) { + if (!m_remoteStderr.isEmpty()) { + errMsg += tr("\nRemote error output was: %1") + .arg(QString::fromUtf8(m_remoteStderr)); + } + emit error(errMsg); + } + stop(); +} + +void MaemoUsedPortsGatherer::handleRemoteStdOut(const QByteArray &output) +{ + m_remoteStdout += output; +} + +void MaemoUsedPortsGatherer::handleRemoteStdErr(const QByteArray &output) +{ + m_remoteStderr += output; +} + +} // namespace Internal +} // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemousedportsgatherer.h b/src/plugins/qt4projectmanager/qt-maemo/maemousedportsgatherer.h new file mode 100644 index 00000000000..f3cbc8ccc47 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemousedportsgatherer.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Creator. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef MAEMOUSEDPORTSGATHERER_H +#define MAEMOUSEDPORTSGATHERER_H + +#include "maemodeviceconfigurations.h" + +#include +#include +#include +#include + +namespace Core { +class SshConnection; +class SshRemoteProcessRunner; +} + +namespace Qt4ProjectManager { +namespace Internal { + +class MaemoUsedPortsGatherer : public QObject +{ + Q_OBJECT +public: + explicit MaemoUsedPortsGatherer(QObject *parent = 0); + ~MaemoUsedPortsGatherer(); + void start(const QSharedPointer &connection, + const MaemoPortList &portList); + void stop(); + QList usedPorts() const; + +signals: + void error(const QString &errMsg); + void portListReady(); + +private slots: + void handleConnectionError(); + void handleProcessClosed(int exitStatus); + void handleRemoteStdOut(const QByteArray &output); + void handleRemoteStdErr(const QByteArray &output); + +private: + QSharedPointer m_procRunner; + QByteArray m_remoteStdout; + QByteArray m_remoteStderr; + bool m_running; +}; + +} // namespace Internal +} // namespace Qt4ProjectManager + +#endif // MAEMOUSEDPORTSGATHERER_H diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri index a36c4a3365e..185e248d49e 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri +++ b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri @@ -32,7 +32,8 @@ HEADERS += \ $$PWD/maemotemplatesmanager.h \ $$PWD/maemomountspecification.h \ $$PWD/maemoremotemounter.h \ - $$PWD/maemoprofilesupdatedialog.h + $$PWD/maemoprofilesupdatedialog.h \ + $$PWD/maemousedportsgatherer.h SOURCES += \ $$PWD/maemoconfigtestdialog.cpp \ @@ -66,7 +67,8 @@ SOURCES += \ $$PWD/maemotemplatesmanager.cpp \ $$PWD/maemomountspecification.cpp \ $$PWD/maemoremotemounter.cpp \ - $$PWD/maemoprofilesupdatedialog.cpp + $$PWD/maemoprofilesupdatedialog.cpp \ + $$PWD/maemousedportsgatherer.cpp FORMS += \ $$PWD/maemoconfigtestdialog.ui \