From 9321967d8423497a71d616e1eaacc2b5d027fa34 Mon Sep 17 00:00:00 2001 From: Benjamin Zeller Date: Fri, 12 Jun 2015 18:14:00 +0200 Subject: [PATCH] QmlProfiler: Make creation of local RunControls more flexible In order for plugins to create a RunControl for locally running applications that do not use LocalApplicationRunConfiguration it is required to export an API that takes care of the internal setup. Also this removes the hard dependency on LocalApplicationRunConfiguration. We don't want to expose Internal classes in public API, so we have to make QmlProfiler::Internal::QmlProfilerRunControl and QmlProfiler::Internal::QmlProfilerStateManager public. Also, AbstractQmlProfilerRunner doesn't do anything useful and can be removed. Change-Id: I0403e5b17e14ac894addd818ad7b249c51a8ed8d Reviewed-by: hjk Reviewed-by: Benjamin Zeller Reviewed-by: Daniel Teske --- .../qmlprofiler/abstractqmlprofilerrunner.h | 63 ----------------- .../qmlprofiler/localqmlprofilerrunner.cpp | 69 +++++++++++++------ .../qmlprofiler/localqmlprofilerrunner.h | 33 +++++---- src/plugins/qmlprofiler/qmlprofiler.pro | 1 - src/plugins/qmlprofiler/qmlprofilerengine.cpp | 2 - src/plugins/qmlprofiler/qmlprofilerengine.h | 2 - .../qmlprofilerruncontrolfactory.cpp | 42 ++--------- .../qmlprofiler/qmlprofilerstatemanager.cpp | 2 - .../qmlprofiler/qmlprofilerstatemanager.h | 2 - .../qmlprofiler/qmlprofilertraceview.h | 3 +- .../qmlprofiler/qmlprofilerviewmanager.h | 2 +- 11 files changed, 76 insertions(+), 145 deletions(-) delete mode 100644 src/plugins/qmlprofiler/abstractqmlprofilerrunner.h diff --git a/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h b/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h deleted file mode 100644 index 9d472a5f1cf..00000000000 --- a/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing -** -** 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 The Qt Company. For licensing terms and -** conditions see http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef ABSTRACTQMLPROFILERRUNNER_H -#define ABSTRACTQMLPROFILERRUNNER_H - -#include -#include - -namespace QmlProfiler { -namespace Internal { - -class AbstractQmlProfilerRunner : public QObject -{ - Q_OBJECT - -public: - explicit AbstractQmlProfilerRunner(QObject *parent = 0) : QObject(parent) { } - - virtual quint16 debugPort() const = 0; - -public slots: - virtual void start() = 0; - virtual void stop() = 0; - -signals: - void started(); - void stopped(); - - void appendMessage(const QString &message, Utils::OutputFormat format); -}; - -} // namespace Internal -} // namespace QmlProfiler - -#endif // ABSTRACTQMLPROFILERRUNNER_H diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp index 02e2458c9ae..4f9aab14df2 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp @@ -32,31 +32,44 @@ #include "qmlprofilerplugin.h" #include "qmlprofilerengine.h" +#include +#include #include #include #include #include +#include +#include +#include + +#include using namespace QmlProfiler; -using namespace QmlProfiler::Internal; using namespace ProjectExplorer; -LocalQmlProfilerRunner *LocalQmlProfilerRunner::createLocalRunner( +Analyzer::AnalyzerRunControl *LocalQmlProfilerRunner::createLocalRunControl( RunConfiguration *runConfiguration, const Analyzer::AnalyzerStartParameters &sp, - QString *errorMessage, - QmlProfilerRunControl *engine) + QString *errorMessage) { - LocalApplicationRunConfiguration *larc = - qobject_cast(runConfiguration); - QTC_ASSERT(larc, return 0); - EnvironmentAspect *environment = runConfiguration->extraAspect(); - QTC_ASSERT(environment, return 0); + // only desktop device is supported + const IDevice::ConstPtr device = DeviceKitInformation::device( + runConfiguration->target()->kit()); + QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return 0); + + Analyzer::AnalyzerRunControl *rc = Analyzer::AnalyzerManager::createRunControl( + sp, runConfiguration); + QmlProfilerRunControl *engine = qobject_cast(rc); + if (!engine) { + delete rc; + return 0; + } + Configuration conf; - conf.executable = larc->executable(); - conf.executableArguments = larc->commandLineArguments(); - conf.workingDirectory = larc->workingDirectory(); - conf.environment = environment->environment(); + conf.executable = sp.debuggee; + conf.executableArguments = sp.debuggeeArgs; + conf.workingDirectory = sp.workingDirectory; + conf.environment = sp.environment; conf.port = sp.analyzerPort; @@ -65,12 +78,33 @@ LocalQmlProfilerRunner *LocalQmlProfilerRunner::createLocalRunner( *errorMessage = tr("No executable file to launch."); return 0; } - return new LocalQmlProfilerRunner(conf, engine); + + LocalQmlProfilerRunner *runner = new LocalQmlProfilerRunner(conf, engine); + + QObject::connect(runner, SIGNAL(stopped()), engine, SLOT(notifyRemoteFinished())); + QObject::connect(runner, SIGNAL(appendMessage(QString,Utils::OutputFormat)), + engine, SLOT(logApplicationMessage(QString,Utils::OutputFormat))); + QObject::connect(engine, SIGNAL(starting(const Analyzer::AnalyzerRunControl*)), runner, + SLOT(start())); + QObject::connect(rc, SIGNAL(finished()), runner, SLOT(stop())); + return rc; +} + +quint16 LocalQmlProfilerRunner::findFreePort(QString &host) +{ + QTcpServer server; + if (!server.listen(QHostAddress::LocalHost) + && !server.listen(QHostAddress::LocalHostIPv6)) { + qWarning() << "Cannot open port on host for QML profiling."; + return 0; + } + host = server.serverAddress().toString(); + return server.serverPort(); } LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuration, QmlProfilerRunControl *engine) : - AbstractQmlProfilerRunner(engine), + QObject(engine), m_configuration(configuration), m_engine(engine) { @@ -132,8 +166,3 @@ void LocalQmlProfilerRunner::stop() if (m_launcher.isRunning()) m_launcher.stop(); } - -quint16 LocalQmlProfilerRunner::debugPort() const -{ - return m_configuration.port; -} diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.h b/src/plugins/qmlprofiler/localqmlprofilerrunner.h index 4f5a8df55b6..57063e7b4fc 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.h +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.h @@ -31,19 +31,20 @@ #ifndef LOCALQMLPROFILERRUNNER_H #define LOCALQMLPROFILERRUNNER_H -#include "abstractqmlprofilerrunner.h" - +#include "qmlprofiler_global.h" #include #include namespace ProjectExplorer { class RunConfiguration; } -namespace Analyzer { class AnalyzerStartParameters; } +namespace Analyzer { + class AnalyzerStartParameters; + class AnalyzerRunControl; +} namespace QmlProfiler { -namespace Internal { class QmlProfilerRunControl; -class LocalQmlProfilerRunner : public AbstractQmlProfilerRunner +class QMLPROFILER_EXPORT LocalQmlProfilerRunner : public QObject { Q_OBJECT @@ -56,31 +57,33 @@ public: Utils::Environment environment; }; - static LocalQmlProfilerRunner *createLocalRunner(ProjectExplorer::RunConfiguration *runConfiguration, - const Analyzer::AnalyzerStartParameters &sp, - QString *errorMessage, - QmlProfilerRunControl *engine); + static Analyzer::AnalyzerRunControl *createLocalRunControl( + ProjectExplorer::RunConfiguration *runConfiguration, + const Analyzer::AnalyzerStartParameters &sp, + QString *errorMessage); + + static quint16 findFreePort(QString &host); ~LocalQmlProfilerRunner(); - // AbstractQmlProfilerRunner - virtual void start(); - virtual void stop(); - virtual quint16 debugPort() const; +signals: + void started(); + void stopped(); + void appendMessage(const QString &message, Utils::OutputFormat format); private slots: void spontaneousStop(int exitCode, QProcess::ExitStatus status); + void start(); + void stop(); private: LocalQmlProfilerRunner(const Configuration &configuration, QmlProfilerRunControl *engine); -private: Configuration m_configuration; ProjectExplorer::ApplicationLauncher m_launcher; QmlProfilerRunControl *m_engine; }; -} // namespace Internal } // namespace QmlProfiler #endif // LOCALQMLPROFILERRUNNER_H diff --git a/src/plugins/qmlprofiler/qmlprofiler.pro b/src/plugins/qmlprofiler/qmlprofiler.pro index ed7d77f2c9d..b53244a7f92 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.pro +++ b/src/plugins/qmlprofiler/qmlprofiler.pro @@ -32,7 +32,6 @@ SOURCES += \ qmlprofilerviewmanager.cpp HEADERS += \ - abstractqmlprofilerrunner.h \ localqmlprofilerrunner.h \ qmlprofiler_global.h \ qmlprofileranimationsmodel.h \ diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.cpp b/src/plugins/qmlprofiler/qmlprofilerengine.cpp index 9937ee2eb79..ef9db29eabc 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerengine.cpp @@ -58,7 +58,6 @@ using namespace Core; using namespace ProjectExplorer; namespace QmlProfiler { -namespace Internal { // // QmlProfilerEnginePrivate @@ -306,5 +305,4 @@ void QmlProfilerRunControl::profilerStateChanged() } } -} // namespace Internal } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.h b/src/plugins/qmlprofiler/qmlprofilerengine.h index 69c466c165c..41c49c3fead 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.h +++ b/src/plugins/qmlprofiler/qmlprofilerengine.h @@ -37,7 +37,6 @@ #include namespace QmlProfiler { -namespace Internal { class QmlProfilerRunControl : public Analyzer::AnalyzerRunControl { @@ -81,7 +80,6 @@ private: QmlProfilerEnginePrivate *d; }; -} // namespace Internal } // namespace QmlProfiler #endif // QMLPROFILERENGINE_H diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp index 68a4b168b90..916b0b7a5dd 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp @@ -33,9 +33,6 @@ #include "qmlprofilerengine.h" #include -#include -#include -#include #include @@ -49,8 +46,6 @@ #include -#include - using namespace Analyzer; using namespace ProjectExplorer; @@ -84,16 +79,11 @@ static AnalyzerStartParameters createQmlProfilerStartParameters(RunConfiguration sp.debuggeeArgs = rc->commandLineArguments(); sp.displayName = rc->displayName(); - const IDevice::ConstPtr device = DeviceKitInformation::device(runConfiguration->target()->kit()); - if (device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) { - QTcpServer server; - if (!server.listen(QHostAddress::LocalHost) && !server.listen(QHostAddress::LocalHostIPv6)) { - qWarning() << "Cannot open port on host for QML profiling."; - return sp; - } - sp.analyzerHost = server.serverAddress().toString(); - sp.analyzerPort = server.serverPort(); - } + quint16 localPort = LocalQmlProfilerRunner::findFreePort(sp.analyzerHost); + if (localPort == 0) + return sp; + sp.analyzerPort = localPort; + sp.startMode = StartLocal; return sp; } @@ -104,27 +94,7 @@ RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfigurat AnalyzerStartParameters sp = createQmlProfilerStartParameters(runConfiguration); sp.runMode = mode; - - // only desktop device is supported - const IDevice::ConstPtr device = DeviceKitInformation::device(runConfiguration->target()->kit()); - QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return 0); - - AnalyzerRunControl *rc = AnalyzerManager::createRunControl(sp, runConfiguration); - QmlProfilerRunControl *engine = qobject_cast(rc); - if (!engine) { - delete rc; - return 0; - } - LocalQmlProfilerRunner *runner = LocalQmlProfilerRunner::createLocalRunner(runConfiguration, sp, errorMessage, engine); - if (!runner) - return 0; - connect(runner, SIGNAL(stopped()), engine, SLOT(notifyRemoteFinished())); - connect(runner, SIGNAL(appendMessage(QString,Utils::OutputFormat)), - engine, SLOT(logApplicationMessage(QString,Utils::OutputFormat))); - connect(engine, SIGNAL(starting(const Analyzer::AnalyzerRunControl*)), runner, - SLOT(start())); - connect(rc, SIGNAL(finished()), runner, SLOT(stop())); - return rc; + return LocalQmlProfilerRunner::createLocalRunControl(runConfiguration, sp, errorMessage); } } // namespace Internal diff --git a/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp b/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp index b3aff787eb9..ba4757cee39 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp @@ -37,7 +37,6 @@ //#define _DEBUG_PROFILERSTATE_ namespace QmlProfiler { -namespace Internal { inline QString stringForState(int state) { switch (state) { @@ -190,4 +189,3 @@ void QmlProfilerStateManager::setRecordingFeatures(quint64 features) } } -} diff --git a/src/plugins/qmlprofiler/qmlprofilerstatemanager.h b/src/plugins/qmlprofiler/qmlprofilerstatemanager.h index 91854489a40..444ea12d034 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatemanager.h +++ b/src/plugins/qmlprofiler/qmlprofilerstatemanager.h @@ -34,7 +34,6 @@ #include namespace QmlProfiler { -namespace Internal { class QmlProfilerStateManager : public QObject { @@ -78,7 +77,6 @@ private: QmlProfilerStateManagerPrivate *d; }; -} } #endif // QMLPROFILERSTATEMANAGER_H diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.h b/src/plugins/qmlprofiler/qmlprofilertraceview.h index a0683c38d4a..3ecdddaf3e1 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceview.h +++ b/src/plugins/qmlprofiler/qmlprofilertraceview.h @@ -41,9 +41,10 @@ namespace QmlProfiler { class QmlProfilerModelManager; +class QmlProfilerStateManager; + namespace Internal { -class QmlProfilerStateManager; class QmlProfilerTool; class QmlProfilerViewManager; diff --git a/src/plugins/qmlprofiler/qmlprofilerviewmanager.h b/src/plugins/qmlprofiler/qmlprofilerviewmanager.h index 3aa3ada7752..80cea2d3c0a 100644 --- a/src/plugins/qmlprofiler/qmlprofilerviewmanager.h +++ b/src/plugins/qmlprofiler/qmlprofilerviewmanager.h @@ -35,11 +35,11 @@ namespace QmlProfiler { class QmlProfilerModelManager; +class QmlProfilerStateManager; namespace Internal { class QmlProfilerTool; -class QmlProfilerStateManager; class QmlProfilerViewManager : public QObject {