diff --git a/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h b/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h index 2554b257048b51a948ccb8bbc3342cf4b42dd3da..b1ce6f11cf08e5549b1525aeb1396f006ebaa30b 100644 --- a/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h +++ b/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h @@ -49,6 +49,8 @@ public: virtual void start() = 0; virtual void stop() = 0; + virtual int debugPort() const = 0; + signals: void started(); void stopped(); diff --git a/src/plugins/qmlprofiler/codaqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/codaqmlprofilerrunner.cpp index b8fb7bc617dea762da4a728dd305d8c97c08b1ae..4e4b91559c203768609e80353d8307c6c1d346f7 100644 --- a/src/plugins/qmlprofiler/codaqmlprofilerrunner.cpp +++ b/src/plugins/qmlprofiler/codaqmlprofilerrunner.cpp @@ -49,6 +49,7 @@ using namespace QmlProfiler::Internal; CodaQmlProfilerRunner::CodaQmlProfilerRunner(S60DeviceRunConfiguration *configuration, QObject *parent) : AbstractQmlProfilerRunner(parent), + m_configuration(configuration), m_runControl(new CodaRunControl(configuration, Analyzer::Constants::MODE_ANALYZE)) { connect(m_runControl, SIGNAL(finished()), this, SIGNAL(stopped())); @@ -80,3 +81,8 @@ void CodaQmlProfilerRunner::appendMessage(ProjectExplorer::RunControl *, const Q emit appendMessage(message, format); } +int QmlProfiler::Internal::CodaQmlProfilerRunner::debugPort() const +{ + return m_configuration->qmlDebugServerPort(); +} + diff --git a/src/plugins/qmlprofiler/codaqmlprofilerrunner.h b/src/plugins/qmlprofiler/codaqmlprofilerrunner.h index 9ebacaf4374d1360a58488a2db11e97476a6dbbe..82dbe97d399f93a63d88ccf422acc9e8d52cb61f 100644 --- a/src/plugins/qmlprofiler/codaqmlprofilerrunner.h +++ b/src/plugins/qmlprofiler/codaqmlprofilerrunner.h @@ -57,11 +57,13 @@ public: // AbstractQmlProfilerRunner virtual void start(); virtual void stop(); + virtual int debugPort() const; private slots: void appendMessage(ProjectExplorer::RunControl *, const QString &message, Utils::OutputFormat format); private: + Qt4ProjectManager::S60DeviceRunConfiguration *m_configuration; ProjectExplorer::RunControl *m_runControl; }; diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp index 7b11c4186474bdbf877d24530f9eccefca6b4f32..38eb80e78d0f41c2e66b6c0d87fb96385407aac9 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp @@ -85,3 +85,8 @@ void LocalQmlProfilerRunner::stop() m_launcher.stop(); } } + +int LocalQmlProfilerRunner::debugPort() const +{ + return m_configuration.port; +} diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.h b/src/plugins/qmlprofiler/localqmlprofilerrunner.h index 6aa6ff968a0f8aaed35cc8e36e72182a3deb7a1d..c50ed7620208ba83c9bbc97c7acfaa55e4c9368a 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.h +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.h @@ -61,6 +61,7 @@ public: // AbstractQmlProfilerRunner virtual void start(); virtual void stop(); + virtual int debugPort() const; private slots: void spontaneousStop(int exitCode); diff --git a/src/plugins/qmlprofiler/qmlprofiler.pro b/src/plugins/qmlprofiler/qmlprofiler.pro index 9d8e129b27de855ee9dcfbd7b4e50d003898b89c..c99254c5d636ba141961d565d8aa9949c1e09ef5 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.pro +++ b/src/plugins/qmlprofiler/qmlprofiler.pro @@ -10,6 +10,7 @@ include(../../plugins/qmlprojectmanager/qmlprojectmanager.pri) include(../../plugins/qt4projectmanager/qt4projectmanager.pri) include(../../plugins/remotelinux/remotelinux.pri) include(../../libs/qmljsdebugclient/qmljsdebugclient-lib.pri) +include(../../libs/extensionsystem/extensionsystem.pri) QT += network script declarative @@ -26,6 +27,7 @@ SOURCES += \ qmlprojectanalyzerruncontrolfactory.cpp \ localqmlprofilerrunner.cpp \ codaqmlprofilerrunner.cpp \ + remotelinuxqmlprofilerrunner.cpp \ qmlprofilercalleeview.cpp \ qmlprofilercallerview.cpp @@ -43,6 +45,7 @@ HEADERS += \ abstractqmlprofilerrunner.h \ localqmlprofilerrunner.h \ codaqmlprofilerrunner.h \ + remotelinuxqmlprofilerrunner.h \ qmlprofilercalleeview.h \ qmlprofilercallerview.h diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.cpp b/src/plugins/qmlprofiler/qmlprofilerengine.cpp index 04eaf8dbe0220ea5ebdcf6716560cf57ec44df83..c233bc5b744b54467c3771d1e11c2b321cb1740e 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerengine.cpp @@ -37,6 +37,7 @@ #include "qmlprofilertool.h" #include "localqmlprofilerrunner.h" #include "codaqmlprofilerrunner.h" +#include "remotelinuxqmlprofilerrunner.h" #include <analyzerbase/analyzermanager.h> #include <analyzerbase/analyzerconstants.h> @@ -45,6 +46,7 @@ #include <qmljsdebugclient/qdeclarativedebugclient_p.h> #include <qt4projectmanager/qt-s60/s60devicerunconfiguration.h> +#include <remotelinux/remotelinuxrunconfiguration.h> #include <utils/qtcassert.h> @@ -106,6 +108,9 @@ QmlProfilerEngine::QmlProfilerEnginePrivate::createRunner(ProjectExplorer::RunCo if (Qt4ProjectManager::S60DeviceRunConfiguration *s60Config = qobject_cast<Qt4ProjectManager::S60DeviceRunConfiguration*>(configuration)) { runner = new CodaQmlProfilerRunner(s60Config, parent); + } else if (RemoteLinux::RemoteLinuxRunConfiguration *rmConfig + = qobject_cast<RemoteLinux::RemoteLinuxRunConfiguration*>(configuration)){ + runner = new RemoteLinuxQmlProfilerRunner(rmConfig, parent); } } return runner; @@ -208,7 +213,7 @@ void QmlProfilerEngine::filterApplicationMessage(const QString &msg) QString errorMessage; if (status.startsWith(waitingForConnection)) { - emit processRunning(); + emit processRunning(d->m_runner->debugPort()); } else if (status.startsWith(unableToListen)) { //: Error message shown after 'Could not connect ... debugger:" errorMessage = tr("The port seems to be in use."); @@ -240,7 +245,7 @@ void QmlProfilerEngine::filterApplicationMessage(const QString &msg) } } else if (msg.contains(cannotRetrieveDebuggingOutput)) { // we won't get debugging output, so just try to connect ... - emit processRunning(); + emit processRunning(d->m_runner->debugPort()); } } diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.h b/src/plugins/qmlprofiler/qmlprofilerengine.h index 35ca9b1c9115c22ecdd512288f8cb865dca9fee9..85a041dfe5234c6b36e9908cc00bab9922222beb 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.h +++ b/src/plugins/qmlprofiler/qmlprofilerengine.h @@ -49,7 +49,7 @@ public: ~QmlProfilerEngine(); signals: - void processRunning(); + void processRunning(int port); void stopRecording(); public slots: diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 82446698ed59b526d6334c4c59dc90c01c4f91f2..791708f82ae4a65570beb68121aa3f211822ae37 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -181,7 +181,7 @@ IAnalyzerEngine *QmlProfilerTool::createEngine(const AnalyzerStartParameters &sp connect(d->m_project, SIGNAL(fileListChanged()), this, SLOT(updateProjectFileList())); } - connect(engine, SIGNAL(processRunning()), this, SLOT(connectClient())); + connect(engine, SIGNAL(processRunning(int)), this, SLOT(connectClient(int))); connect(engine, SIGNAL(finished()), this, SLOT(disconnectClient())); connect(engine, SIGNAL(stopRecording()), this, SLOT(stopRecording())); connect(d->m_traceWindow, SIGNAL(viewUpdated()), engine, SLOT(dataReceived())); @@ -320,7 +320,7 @@ QWidget *QmlProfilerTool::createControlWidget() return toolbarWidget; } -void QmlProfilerTool::connectClient() +void QmlProfilerTool::connectClient(int port) { QTC_ASSERT(!d->m_client, return;) d->m_client = new QDeclarativeDebugConnection; @@ -328,6 +328,7 @@ void QmlProfilerTool::connectClient() connect(d->m_client, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(connectionStateChanged())); d->m_connectionTimer.start(); + d->m_tcpPort = port; } void QmlProfilerTool::connectToClient() @@ -440,7 +441,7 @@ void QmlProfilerTool::attach() d->m_tcpPort = dialog.port(); d->m_tcpHost = dialog.address(); - connectClient(); + connectClient(d->m_tcpPort); AnalyzerManager::instance()->showMode(); //AnalyzerManager::instance()->popupOutputPane(); } else { diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h index f1a208045aaad273ae2f99693c381f70dbc707db..759bb84290d696ccdc244c3ca07c12a1f3f7b8b9 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.h +++ b/src/plugins/qmlprofiler/qmlprofilertool.h @@ -64,7 +64,7 @@ public: bool canRunRemotely() const; public slots: - void connectClient(); + void connectClient(int port); void disconnectClient(); void startRecording(); diff --git a/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aecb8940ab0351fc982aa1dde263fe7c2b41fd1d --- /dev/null +++ b/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp @@ -0,0 +1,169 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** 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. +** +**************************************************************************/ + +#include "remotelinuxqmlprofilerrunner.h" +#include <extensionsystem/pluginmanager.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <remotelinux/remotelinuxapplicationrunner.h> +#include <utils/qtcassert.h> + +using namespace ExtensionSystem; +using namespace ProjectExplorer; +using namespace QmlProfiler::Internal; +using namespace RemoteLinux; + +RemoteLinuxQmlProfilerRunner::RemoteLinuxQmlProfilerRunner( + RemoteLinuxRunConfiguration *runConfiguration, QObject *parent) + : AbstractQmlProfilerRunner(parent) + , m_port(-1) + , m_runControl(0) +{ + // find run control factory + IRunControlFactory *runControlFactory = 0; + QList<IRunControlFactory*> runControlFactories + = PluginManager::instance()->getObjects<IRunControlFactory>(); + + foreach (IRunControlFactory *factory, runControlFactories) { + if (factory->canRun(runConfiguration, ProjectExplorer::Constants::RUNMODE)) { + runControlFactory = factory; + break; + } + } + + QTC_ASSERT(runControlFactory, return); + + // create run control + RunControl *runControl = runControlFactory->create(runConfiguration, + ProjectExplorer::Constants::RUNMODE); + + 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))); +} + +RemoteLinuxQmlProfilerRunner::~RemoteLinuxQmlProfilerRunner() +{ + delete m_runControl; +} + +void RemoteLinuxQmlProfilerRunner::start() +{ + QTC_ASSERT(runner(), return); + runner()->start(); +} + +void RemoteLinuxQmlProfilerRunner::stop() +{ + QTC_ASSERT(runner(), return); + runner()->stop(); +} + +int RemoteLinuxQmlProfilerRunner::debugPort() const +{ + return m_port; +} + +void RemoteLinuxQmlProfilerRunner::getPorts() +{ + QTC_ASSERT(runner(), return); + m_port = runner()->freePorts()->getNext(); + if (m_port == -1) { + emit appendMessage(tr("Not enough free ports on device for analyzing.\n"), + Utils::ErrorMessageFormat); + runner()->stop(); + } else { + emit appendMessage(tr("Starting remote process ...\n"), Utils::NormalMessageFormat); + + QString arguments = runner()->arguments(); + if (!arguments.isEmpty()) + arguments.append(QLatin1Char(' ')); + arguments.append(QString(QLatin1String("-qmljsdebugger=port:%1,block")).arg(m_port)); + + runner()->startExecution(QString::fromLocal8Bit("%1 %2 %3") + .arg(runner()->commandPrefix()) + .arg(runner()->remoteExecutable()) + .arg(arguments).toUtf8()); + } +} + +void RemoteLinuxQmlProfilerRunner::handleError(const QString &msg) +{ + emit appendMessage(msg + QLatin1Char('\n'), Utils::ErrorMessageFormat); +} + +void RemoteLinuxQmlProfilerRunner::handleStdErr(const QByteArray &msg) +{ + emit appendMessage(QString::fromUtf8(msg), Utils::StdErrFormat); +} + +void RemoteLinuxQmlProfilerRunner::handleStdOut(const QByteArray &msg) +{ + emit appendMessage(QString::fromUtf8(msg), Utils::StdOutFormat); +} + +void RemoteLinuxQmlProfilerRunner::handleRemoteProcessStarted() +{ + emit started(); +} + +void RemoteLinuxQmlProfilerRunner::handleRemoteProcessFinished(qint64 exitCode) +{ + if (exitCode != RemoteLinuxApplicationRunner::InvalidExitCode) { + appendMessage(tr("Finished running remote process. Exit code was %1.\n") + .arg(exitCode), Utils::NormalMessageFormat); + } + + emit stopped(); +} + +void RemoteLinuxQmlProfilerRunner::handleProgressReport(const QString &progressString) +{ + appendMessage(progressString + QLatin1Char('\n'), Utils::NormalMessageFormat); +} + +RemoteLinuxApplicationRunner *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 new file mode 100644 index 0000000000000000000000000000000000000000..a6b24f7e6e6aa375913bd4a54caa98387d3d9f87 --- /dev/null +++ b/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.h @@ -0,0 +1,79 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** 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 info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef REMOTELINUXQMLPROFILERRUNNER_H +#define REMOTELINUXQMLPROFILERRUNNER_H + +#include "abstractqmlprofilerrunner.h" +#include <remotelinux/remotelinuxrunconfiguration.h> +#include <remotelinux/remotelinuxruncontrol.h> + +namespace QmlProfiler { +namespace Internal { + +class RemoteLinuxQmlProfilerRunner : public AbstractQmlProfilerRunner +{ + Q_OBJECT + Q_DISABLE_COPY(RemoteLinuxQmlProfilerRunner) + + using AbstractQmlProfilerRunner::appendMessage; // don't hide signal +public: + explicit RemoteLinuxQmlProfilerRunner(RemoteLinux::RemoteLinuxRunConfiguration *configuration, + QObject *parent = 0); + ~RemoteLinuxQmlProfilerRunner(); + + // AbstractQmlProfilerRunner + virtual void start(); + virtual void stop(); + virtual int 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 handleProgressReport(const QString &progressString); + +private: + RemoteLinux::RemoteLinuxApplicationRunner *runner() const; + + int m_port; + RemoteLinux::AbstractRemoteLinuxRunControl *m_runControl; +}; + +} // namespace Internal +} // namespace QmlProfiler + +#endif // REMOTELINUXQMLPROFILERRUNNER_H