diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp deleted file mode 100644 index bd3fe0aa95d9ee379f50e8346dabeda249219106..0000000000000000000000000000000000000000 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "localqmlprofilerrunner.h" -#include "qmlprofilerplugin.h" -#include "qmlprofilerruncontrol.h" - -#include <projectexplorer/runconfiguration.h> -#include <projectexplorer/environmentaspect.h> -#include <projectexplorer/devicesupport/idevice.h> -#include <projectexplorer/kitinformation.h> -#include <projectexplorer/projectexplorer.h> -#include <projectexplorer/target.h> - -#include <qmldebug/qmldebugcommandlinearguments.h> - -#include <utils/temporaryfile.h> - -#include <QTcpServer> -#include <QTemporaryFile> - -using namespace ProjectExplorer; - -namespace QmlProfiler { - -QString LocalQmlProfilerRunner::findFreeSocket() -{ - Utils::TemporaryFile file("qmlprofiler-freesocket"); - if (file.open()) { - return file.fileName(); - } else { - qWarning() << "Could not open a temporary file to find a debug socket."; - return QString(); - } -} - -Utils::Port 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 Utils::Port(); - } - host = server.serverAddress().toString(); - return Utils::Port(server.serverPort()); -} - -LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuration, - QmlProfilerRunner *runner) : - QObject(runner->runControl()), - m_runControl(runner->runControl()), - m_configuration(configuration) -{ - auto runControl = runner->runControl(); - connect(&m_launcher, &ApplicationLauncher::appendMessage, - this, &LocalQmlProfilerRunner::appendMessage); - connect(this, &LocalQmlProfilerRunner::stopped, - runner, &QmlProfilerRunner::notifyRemoteFinished); - connect(this, &LocalQmlProfilerRunner::appendMessage, - runControl, &RunControl::appendMessage); - connect(runControl, &RunControl::starting, - this, &LocalQmlProfilerRunner::start); - connect(runControl, &RunControl::finished, - this, &LocalQmlProfilerRunner::stop); - - m_outputParser.setNoOutputText(ApplicationLauncher::msgWinCannotRetrieveDebuggingOutput()); - - connect(runControl, &RunControl::appendMessageRequested, - this, [this](RunControl *runControl, const QString &msg, Utils::OutputFormat format) { - Q_UNUSED(runControl); - Q_UNUSED(format); - m_outputParser.processOutput(msg); - }); - - connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort, - runControl, [this, runControl, runner](Utils::Port port) { - runControl->notifyRemoteSetupDone(port); - runner->notifyRemoteSetupDone(port); - }); - - connect(&m_outputParser, &QmlDebug::QmlOutputParser::noOutputMessage, - runControl, [this, runControl, runner]() { - runControl->notifyRemoteSetupDone(Utils::Port()); - runner->notifyRemoteSetupDone(Utils::Port()); - }); - - connect(&m_outputParser, &QmlDebug::QmlOutputParser::connectingToSocketMessage, - runControl, [this, runControl, runner]() { - runControl->notifyRemoteSetupDone(Utils::Port()); - runner->notifyRemoteSetupDone(Utils::Port()); - }); - - connect(&m_outputParser, &QmlDebug::QmlOutputParser::errorMessage, - runControl, [this, runControl, runner](const QString &message) { - runControl->notifyRemoteSetupFailed(message); - runner->notifyRemoteSetupFailed(message); - }); -} - -void LocalQmlProfilerRunner::start() -{ - QTC_ASSERT(!m_configuration.socket.isEmpty() || m_configuration.port.isValid(), return); - - StandardRunnable runnable = m_configuration.debuggee; - QString arguments = m_configuration.socket.isEmpty() ? - QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, - m_configuration.port) : - QmlDebug::qmlDebugLocalArguments(QmlDebug::QmlProfilerServices, - m_configuration.socket); - - - if (!m_configuration.debuggee.commandLineArguments.isEmpty()) - arguments += QLatin1Char(' ') + m_configuration.debuggee.commandLineArguments; - - runnable.commandLineArguments = arguments; - runnable.runMode = ApplicationLauncher::Gui; - - // queue this, as the process can already die in the call to start(). - // We want the started() signal to be emitted before the stopped() signal. - connect(&m_launcher, &ApplicationLauncher::processExited, - this, &LocalQmlProfilerRunner::spontaneousStop, - Qt::QueuedConnection); - m_launcher.start(runnable); - - emit started(); -} - -void LocalQmlProfilerRunner::spontaneousStop(int exitCode, QProcess::ExitStatus status) -{ - Q_UNUSED(exitCode); - Q_UNUSED(status); - disconnect(&m_launcher, &ApplicationLauncher::processExited, - this, &LocalQmlProfilerRunner::spontaneousStop); - - emit stopped(); -} - -void LocalQmlProfilerRunner::stop() -{ - if (m_launcher.isRunning()) - m_launcher.stop(); -} - -} // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.h b/src/plugins/qmlprofiler/localqmlprofilerrunner.h deleted file mode 100644 index 4758405a7aaca51e8844f0920d11245dbaa808c2..0000000000000000000000000000000000000000 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "qmlprofiler_global.h" -#include <utils/environment.h> -#include <utils/port.h> -#include <projectexplorer/applicationlauncher.h> -#include <projectexplorer/runnables.h> -#include <qmldebug/qmloutputparser.h> - -namespace QmlProfiler { - -class QmlProfilerRunner; - -class QMLPROFILER_EXPORT LocalQmlProfilerRunner : public QObject -{ - Q_OBJECT - -public: - struct Configuration { - ProjectExplorer::StandardRunnable debuggee; - Utils::Port port; - QString socket; - }; - - LocalQmlProfilerRunner(const Configuration &configuration, - QmlProfilerRunner *runner); - - static Utils::Port findFreePort(QString &host); - static QString findFreeSocket(); - -signals: - void started(); - void stopped(); - void appendMessage(const QString &message, Utils::OutputFormat format); - -private: - void spontaneousStop(int exitCode, QProcess::ExitStatus status); - void start(); - void stop(); - - ProjectExplorer::RunControl *m_runControl; - Configuration m_configuration; - ProjectExplorer::ApplicationLauncher m_launcher; - QmlDebug::QmlOutputParser m_outputParser; -}; - -} // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmlprofiler.pro b/src/plugins/qmlprofiler/qmlprofiler.pro index 799b627abf9b1012a69f555ef622ed2efef19e69..0995840d2bc3c22a10f1b062151a15dee96f223a 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.pro +++ b/src/plugins/qmlprofiler/qmlprofiler.pro @@ -9,7 +9,6 @@ SOURCES += \ flamegraphmodel.cpp \ flamegraphview.cpp \ inputeventsmodel.cpp \ - localqmlprofilerrunner.cpp \ memoryusagemodel.cpp \ pixmapcachemodel.cpp \ qmlevent.cpp \ @@ -50,7 +49,6 @@ HEADERS += \ flamegraphmodel.h \ flamegraphview.h \ inputeventsmodel.h \ - localqmlprofilerrunner.h \ memoryusagemodel.h \ pixmapcachemodel.h \ qmlevent.h \ diff --git a/src/plugins/qmlprofiler/qmlprofiler.qbs b/src/plugins/qmlprofiler/qmlprofiler.qbs index 5202d0eb37535213ff31c0a4f6b70bb366ed63df..b509ac07a365d05f06ae422a848bd76f7ff5ca16 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.qbs +++ b/src/plugins/qmlprofiler/qmlprofiler.qbs @@ -24,7 +24,6 @@ QtcPlugin { "flamegraphmodel.cpp", "flamegraphmodel.h", "flamegraphview.cpp", "flamegraphview.h", "inputeventsmodel.cpp", "inputeventsmodel.h", - "localqmlprofilerrunner.cpp", "localqmlprofilerrunner.h", "memoryusagemodel.cpp", "memoryusagemodel.h", "pixmapcachemodel.cpp", "pixmapcachemodel.h", "qmlevent.cpp", "qmlevent.h", diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h index 91fc6b278cbb35c6d5f5cf914ffa7f1bdf149288..8cce222c513daddc5905c855bfd2fdd5db0d4bd2 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h @@ -37,6 +37,8 @@ #include <QObject> #include <functional> +namespace ProjectExplorer { class RunConfiguration; } + namespace QmlProfiler { class QmlProfilerModelManager; class QmlProfilerNotesModel; diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp index 337467dfb78b6d71339f65e395d61329d183e203..fb74804aa2ac5f93c3863ed7ccbde7b0478ec383 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp @@ -23,9 +23,10 @@ ** ****************************************************************************/ +#include "qmlprofilerclientmanager.h" #include "qmlprofilerruncontrol.h" -#include "localqmlprofilerrunner.h" #include "qmlprofilertool.h" +#include "qmlprofilerplugin.h" #include <debugger/analyzer/analyzermanager.h> #include <debugger/analyzer/analyzerstartparameters.h> @@ -33,30 +34,38 @@ #include <coreplugin/icore.h> #include <coreplugin/helpmanager.h> +#include <projectexplorer/devicesupport/idevice.h> #include <projectexplorer/environmentaspect.h> #include <projectexplorer/kitinformation.h> #include <projectexplorer/localapplicationruncontrol.h> +#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorericons.h> +#include <projectexplorer/runconfiguration.h> #include <projectexplorer/runnables.h> #include <projectexplorer/target.h> #include <qtsupport/qtsupportconstants.h> + #include <qmldebug/qmloutputparser.h> +#include <qmldebug/qmldebugcommandlinearguments.h> #include <utils/qtcassert.h> +#include <utils/temporaryfile.h> +#include <QApplication> #include <QMainWindow> #include <QMessageBox> -#include <QTimer> -#include <QTcpServer> -#include <QApplication> #include <QMessageBox> #include <QPushButton> +#include <QTcpServer> +#include <QTemporaryFile> +#include <QTimer> using namespace Debugger; using namespace Core; using namespace ProjectExplorer; +using namespace QmlProfiler::Internal; namespace QmlProfiler { @@ -69,6 +78,10 @@ class QmlProfilerRunner::QmlProfilerRunnerPrivate public: QmlProfilerStateManager *m_profilerState = 0; QTimer m_noDebugOutputTimer; + bool m_isLocal = false; + QmlProfilerRunner::Configuration m_configuration; + ProjectExplorer::ApplicationLauncher m_launcher; + QmlDebug::QmlOutputParser m_outputParser; }; // @@ -100,20 +113,48 @@ QmlProfilerRunner::~QmlProfilerRunner() void QmlProfilerRunner::start() { - runControl()->reportApplicationStart(); Internal::QmlProfilerTool::instance()->finalizeRunControl(this); - QTC_ASSERT(d->m_profilerState, runControl()->reportApplicationStop(); return); + QTC_ASSERT(d->m_profilerState, return); - QTC_ASSERT(connection().is<AnalyzerConnection>(), runControl()->reportApplicationStop(); return); + QTC_ASSERT(connection().is<AnalyzerConnection>(), return); auto conn = connection().as<AnalyzerConnection>(); - if (conn.analyzerPort.isValid()) - emit processRunning(conn.analyzerPort); + if (conn.analyzerPort.isValid()) { + auto clientManager = Internal::QmlProfilerTool::clientManager(); + clientManager->setTcpConnection(conn.analyzerHost, conn.analyzerPort); + clientManager->connectToTcpServer(); + } else if (conn.analyzerSocket.isEmpty()) d->m_noDebugOutputTimer.start(); d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning); - emit runControl()->starting(); + + if (d->m_isLocal) { + QTC_ASSERT(!d->m_configuration.socket.isEmpty() || d->m_configuration.port.isValid(), return); + + StandardRunnable debuggee = runnable().as<StandardRunnable>(); + QString arguments = d->m_configuration.socket.isEmpty() ? + QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, + d->m_configuration.port) : + QmlDebug::qmlDebugLocalArguments(QmlDebug::QmlProfilerServices, + d->m_configuration.socket); + + + if (!debuggee.commandLineArguments.isEmpty()) + arguments += ' ' + debuggee.commandLineArguments; + + debuggee.commandLineArguments = arguments; + debuggee.runMode = ApplicationLauncher::Gui; + + // queue this, as the process can already die in the call to start(). + // We want the started() signal to be emitted before the stopped() signal. + connect(&d->m_launcher, &ApplicationLauncher::processExited, + this, &QmlProfilerRunner::spontaneousStop, + Qt::QueuedConnection); + d->m_launcher.start(debuggee); + + emit localRunnerStarted(); + } } void QmlProfilerRunner::stop() @@ -148,7 +189,6 @@ void QmlProfilerRunner::notifyRemoteFinished() switch (d->m_profilerState->currentState()) { case QmlProfilerStateManager::AppRunning: d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying); - runControl()->reportApplicationStop(); break; case QmlProfilerStateManager::Idle: break; @@ -177,7 +217,7 @@ void QmlProfilerRunner::cancelProcess() return; } } - runControl()->reportApplicationStop(); + runControl()->initiateStop(); } void QmlProfilerRunner::notifyRemoteSetupFailed(const QString &errorMessage) @@ -200,7 +240,6 @@ void QmlProfilerRunner::notifyRemoteSetupFailed(const QString &errorMessage) // KILL d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying); d->m_noDebugOutputTimer.stop(); - runControl()->reportApplicationStop(); } void QmlProfilerRunner::wrongSetupMessageBoxFinished(int button) @@ -219,8 +258,11 @@ void QmlProfilerRunner::notifyRemoteSetupDone(Utils::Port port) QTC_ASSERT(connection().is<AnalyzerConnection>(), return); port = connection().as<AnalyzerConnection>().analyzerPort; } - if (port.isValid()) - emit processRunning(port); + if (port.isValid()) { + auto clientManager = Internal::QmlProfilerTool::clientManager(); + clientManager->setTcpConnection(connection().as<AnalyzerConnection>().analyzerHost, port); + clientManager->connectToTcpServer(); + } } void QmlProfilerRunner::registerProfilerStateManager( QmlProfilerStateManager *profilerState ) @@ -242,7 +284,6 @@ void QmlProfilerRunner::profilerStateChanged() { switch (d->m_profilerState->currentState()) { case QmlProfilerStateManager::Idle: - runControl()->reportApplicationStop(); d->m_noDebugOutputTimer.stop(); break; default: @@ -250,4 +291,82 @@ void QmlProfilerRunner::profilerStateChanged() } } +QString QmlProfilerRunner::findFreeSocket() +{ + Utils::TemporaryFile file("qmlprofiler-freesocket"); + if (file.open()) { + return file.fileName(); + } else { + qWarning() << "Could not open a temporary file to find a debug socket."; + return QString(); + } +} + +Utils::Port QmlProfilerRunner::findFreePort(QString &host) +{ + QTcpServer server; + if (!server.listen(QHostAddress::LocalHost) + && !server.listen(QHostAddress::LocalHostIPv6)) { + qWarning() << "Cannot open port on host for QML profiling."; + return Utils::Port(); + } + host = server.serverAddress().toString(); + return Utils::Port(server.serverPort()); +} + +void QmlProfilerRunner::setLocalConfiguration(const Configuration &configuration) +{ + d->m_isLocal = true; + d->m_configuration = configuration; + connect(&d->m_launcher, &ApplicationLauncher::appendMessage, + this, &QmlProfilerRunner::appendMessage); + connect(this, &QmlProfilerRunner::localRunnerStopped, + this, &QmlProfilerRunner::notifyRemoteFinished); + connect(runControl(), &RunControl::finished, + this, &QmlProfilerRunner::stopLocalRunner); + + d->m_outputParser.setNoOutputText(ApplicationLauncher::msgWinCannotRetrieveDebuggingOutput()); + + connect(runControl(), &RunControl::appendMessageRequested, + this, [this](RunControl *, const QString &msg, Utils::OutputFormat) { + d->m_outputParser.processOutput(msg); + }); + + connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort, + this, [this](Utils::Port port) { + notifyRemoteSetupDone(port); + }); + + connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::noOutputMessage, + this, [this] { + notifyRemoteSetupDone(Utils::Port()); + }); + + connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::connectingToSocketMessage, + this, [this] { + notifyRemoteSetupDone(Utils::Port()); + }); + + connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::errorMessage, + this, [this](const QString &message) { + notifyRemoteSetupFailed(message); + }); +} + +void QmlProfilerRunner::spontaneousStop(int exitCode, QProcess::ExitStatus status) +{ + Q_UNUSED(exitCode); + Q_UNUSED(status); + disconnect(&d->m_launcher, &ApplicationLauncher::processExited, + this, &QmlProfilerRunner::spontaneousStop); + + emit localRunnerStopped(); +} + +void QmlProfilerRunner::stopLocalRunner() +{ + if (d->m_launcher.isRunning()) + d->m_launcher.stop(); +} + } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h index 9ff6106d36f7eafa6de59f303636fd79ba8d3f06..00979d01a7f247b6ff324b10561363f3c39971f8 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h @@ -28,7 +28,12 @@ #include "qmlprofilerstatemanager.h" #include <projectexplorer/runconfiguration.h> +#include <projectexplorer/runnables.h> + #include <utils/outputformat.h> +#include <utils/port.h> + +#include <qmldebug/qmloutputparser.h> namespace QmlProfiler { @@ -40,22 +45,37 @@ public: QmlProfilerRunner(ProjectExplorer::RunControl *runControl); ~QmlProfilerRunner() override; + struct Configuration { + Utils::Port port; + QString socket; + }; + void setLocalConfiguration(const Configuration &conf); + void registerProfilerStateManager( QmlProfilerStateManager *profilerState ); void notifyRemoteSetupDone(Utils::Port port); void notifyRemoteSetupFailed(const QString &errorMessage); - void start() override; - void stop() override; void cancelProcess(); void notifyRemoteFinished(); + static Utils::Port findFreePort(QString &host); + static QString findFreeSocket(); + signals: - void processRunning(Utils::Port port); + void localRunnerStarted(); + void localRunnerStopped(); private: + void start() override; + void stop() override; + void wrongSetupMessageBoxFinished(int); void profilerStateChanged(); + void spontaneousStop(int exitCode, QProcess::ExitStatus status); + void startLocalRunner(); + void stopLocalRunner(); + class QmlProfilerRunnerPrivate; QmlProfilerRunnerPrivate *d; }; diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp index e6cf9ee79ea0d130ce8d386c9c4529b4069cfbe9..c1239ef67428e5fbc6daf527b4f2efcb3602a66e 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp @@ -24,7 +24,6 @@ ****************************************************************************/ #include "qmlprofilerruncontrolfactory.h" -#include "localqmlprofilerrunner.h" #include "qmlprofilerruncontrol.h" #include "qmlprofilerrunconfigurationaspect.h" @@ -60,6 +59,8 @@ static bool isLocal(RunConfiguration *runConfiguration) QmlProfilerRunControlFactory::QmlProfilerRunControlFactory(QObject *parent) : IRunControlFactory(parent) { + RunControl::registerWorkerCreator(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, + [this](RunControl *runControl) { return new QmlProfilerRunner(runControl); }); } bool QmlProfilerRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const @@ -67,44 +68,33 @@ bool QmlProfilerRunControlFactory::canRun(RunConfiguration *runConfiguration, Co return mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE && isLocal(runConfiguration); } -RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) +RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *) { QTC_ASSERT(canRun(runConfiguration, mode), return 0); QTC_ASSERT(runConfiguration->runnable().is<StandardRunnable>(), return 0); - auto runnable = runConfiguration->runnable().as<StandardRunnable>(); - - if (runnable.executable.isEmpty()) { - if (errorMessage) - *errorMessage = tr("No executable file to launch."); - return 0; - } Kit *kit = runConfiguration->target()->kit(); AnalyzerConnection connection; const QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit); if (version) { if (version->qtVersion() >= QtSupport::QtVersionNumber(5, 6, 0)) - connection.analyzerSocket = LocalQmlProfilerRunner::findFreeSocket(); + connection.analyzerSocket = QmlProfilerRunner::findFreeSocket(); else - connection.analyzerPort = LocalQmlProfilerRunner::findFreePort(connection.analyzerHost); + connection.analyzerPort = QmlProfilerRunner::findFreePort(connection.analyzerHost); } else { qWarning() << "Running QML profiler on Kit without Qt version??"; - connection.analyzerPort = LocalQmlProfilerRunner::findFreePort(connection.analyzerHost); + connection.analyzerPort = QmlProfilerRunner::findFreePort(connection.analyzerHost); } auto runControl = new RunControl(runConfiguration, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); - auto runWorker = runControl->createWorker(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); - runControl->setRunnable(runnable); runControl->setConnection(connection); - LocalQmlProfilerRunner::Configuration conf; - conf.debuggee = runnable; - if (EnvironmentAspect *environment = runConfiguration->extraAspect<EnvironmentAspect>()) - conf.debuggee.environment = environment->environment(); + QmlProfilerRunner::Configuration conf; conf.socket = connection.analyzerSocket; conf.port = connection.analyzerPort; - (void) new LocalQmlProfilerRunner(conf, qobject_cast<QmlProfilerRunner *>(runWorker)); + auto runner = new QmlProfilerRunner(runControl); + runner->setLocalConfiguration(conf); return runControl; } diff --git a/src/plugins/qmlprofiler/qmlprofilertextmark.cpp b/src/plugins/qmlprofiler/qmlprofilertextmark.cpp index 3060c8f1400ac0c88833f0c139a373c0ced90b04..a0bdaed6cc118e6e4c467818122e5570bb2429af 100644 --- a/src/plugins/qmlprofiler/qmlprofilertextmark.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertextmark.cpp @@ -25,8 +25,9 @@ #include "qmlprofilertextmark.h" #include "qmlprofilerconstants.h" -#include <QPainter> +#include <QLabel> #include <QLayout> +#include <QPainter> namespace QmlProfiler { namespace Internal { diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 0c57588fc15c7a4b2478d97346e5c074077be3d6..0a087b38354e49f9a7b1743d4cdb90e9e10da182 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -247,17 +247,12 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent) // is available, then we can populate the file finder d->m_profilerModelManager->populateFileFinder(); - auto runWorkerCreator = [this](RunControl *runControl) { - return createRunner(runControl, Debugger::startupRunConfiguration()); - }; - QString description = tr("The QML Profiler can be used to find performance " "bottlenecks in applications using QML."); d->m_startAction = Debugger::createStartAction(); d->m_stopAction = Debugger::createStopAction(); - RunControl::registerWorkerCreator(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, runWorkerCreator); act = new QAction(tr("QML Profiler"), this); act->setToolTip(description); menu->addAction(ActionManager::registerAction(act, "QmlProfiler.Local"), @@ -328,11 +323,13 @@ void QmlProfilerTool::updateRunActions() } } -RunWorker *QmlProfilerTool::createRunner(RunControl *runControl, RunConfiguration *runConfiguration) +void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker) { d->m_toolBusy = true; + auto runControl = runWorker->runControl(); + auto runConfiguration = runControl->runConfiguration(); if (runConfiguration) { - QmlProfilerRunConfigurationAspect *aspect = static_cast<QmlProfilerRunConfigurationAspect *>( + auto aspect = static_cast<QmlProfilerRunConfigurationAspect *>( runConfiguration->extraAspect(Constants::SETTINGS)); if (aspect) { if (QmlProfilerSettings *settings = static_cast<QmlProfilerSettings *>(aspect->currentSettings())) { @@ -343,7 +340,6 @@ RunWorker *QmlProfilerTool::createRunner(RunControl *runControl, RunConfiguratio } } - auto runWorker = new QmlProfilerRunner(runControl); connect(runControl, &RunControl::finished, this, [this, runControl] { d->m_toolBusy = false; updateRunActions(); @@ -353,11 +349,6 @@ RunWorker *QmlProfilerTool::createRunner(RunControl *runControl, RunConfiguratio connect(d->m_stopAction, &QAction::triggered, runControl, &RunControl::stop); updateRunActions(); - return runWorker; -} - -void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker) -{ runWorker->registerProfilerStateManager(d->m_profilerState); QmlProfilerClientManager *clientManager = d->m_profilerConnections; @@ -376,20 +367,10 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker) // Initialize m_projectFinder // - auto runControl = runWorker->runControl(); - RunConfiguration *runConfiguration = runControl->runConfiguration(); if (runConfiguration) { d->m_profilerModelManager->populateFileFinder(runConfiguration); } - if (connection.analyzerSocket.isEmpty()) { - QString host = connection.analyzerHost; - connect(runWorker, &QmlProfilerRunner::processRunning, - clientManager, [clientManager, host](Utils::Port port) { - clientManager->setTcpConnection(host, port); - clientManager->connectToTcpServer(); - }); - } connect(clientManager, &QmlProfilerClientManager::connectionFailed, runWorker, [this, clientManager, runWorker]() { QMessageBox *infoBox = new QMessageBox(ICore::mainWindow()); @@ -873,6 +854,11 @@ void QmlProfilerTool::showNonmodalWarning(const QString &warningMsg) noExecWarning->show(); } +QmlProfilerClientManager *QmlProfilerTool::clientManager() +{ + return s_instance->d->m_profilerConnections; +} + void QmlProfilerTool::profilerStateChanged() { switch (d->m_profilerState->currentState()) { diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h index aeffca178b7a696d90e9d5f5d1a188b76da2581c..17ecd0c80615bc5b8be332e21b93b5b713d7b18e 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.h +++ b/src/plugins/qmlprofiler/qmlprofilertool.h @@ -29,11 +29,8 @@ #include "qmlprofilerconstants.h" #include "qmlprofilereventtypes.h" -#include <debugger/analyzer/analyzermanager.h> - -QT_BEGIN_NAMESPACE -class QMessageBox; -QT_END_NAMESPACE +#include <QAction> +#include <QObject> namespace QmlProfiler { @@ -41,6 +38,8 @@ class QmlProfilerRunner; namespace Internal { +class QmlProfilerClientManager; + class QMLPROFILER_EXPORT QmlProfilerTool : public QObject { Q_OBJECT @@ -51,8 +50,6 @@ public: static QmlProfilerTool *instance(); - ProjectExplorer::RunWorker *createRunner(ProjectExplorer::RunControl *runControl, - ProjectExplorer::RunConfiguration *runConfiguration = 0); void finalizeRunControl(QmlProfilerRunner *runWorker); bool prepareTool(); @@ -68,6 +65,8 @@ public: static void logError(const QString &msg); static void showNonmodalWarning(const QString &warningMsg); + static QmlProfilerClientManager *clientManager(); + public slots: void profilerStateChanged(); void clientRecordingChanged(); diff --git a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp index 48d316549265a394596cd6444bf9f5a84ff9e541..db97b33ef4d2572a0dbeffcea82c9d70d4f11259 100644 --- a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp +++ b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp @@ -29,9 +29,14 @@ #include <debugger/analyzer/analyzermanager.h> #include <debugger/analyzer/analyzerstartparameters.h> + +#include <projectexplorer/runnables.h> + #include <QtTest> #include <QTcpServer> +using namespace ProjectExplorer; + namespace QmlProfiler { namespace Internal { @@ -39,14 +44,14 @@ LocalQmlProfilerRunnerTest::LocalQmlProfilerRunnerTest(QObject *parent) : QObjec { } -void LocalQmlProfilerRunnerTest::connectRunner(LocalQmlProfilerRunner *runner) +void LocalQmlProfilerRunnerTest::connectRunner(QmlProfilerRunner *runner) { - connect(runner, &LocalQmlProfilerRunner::started, this, [this] { + connect(runner, &QmlProfilerRunner::localRunnerStarted, this, [this] { QVERIFY(!running); ++runCount; running = true; }); - connect(runner, &LocalQmlProfilerRunner::stopped, this, [this] { + connect(runner, &QmlProfilerRunner::localRunnerStopped, this, [this] { QVERIFY(running); running = false; }); @@ -54,16 +59,17 @@ void LocalQmlProfilerRunnerTest::connectRunner(LocalQmlProfilerRunner *runner) void LocalQmlProfilerRunnerTest::testRunner() { - configuration.debuggee.executable = "\\-/|\\-/"; - configuration.debuggee.environment = Utils::Environment::systemEnvironment(); + debuggee.executable = "\\-/|\\-/"; + debuggee.environment = Utils::Environment::systemEnvironment(); // should not be used anywhere but cannot be empty configuration.socket = connection.analyzerSocket = QString("invalid"); rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); - auto worker = new QmlProfilerRunner(rc); + rc->setRunnable(debuggee); rc->setConnection(connection); - auto runner = new LocalQmlProfilerRunner(configuration, worker); + auto runner = new QmlProfilerRunner(rc); + runner->setLocalConfiguration(configuration); connectRunner(runner); rc->initiateStart(); @@ -75,17 +81,18 @@ void LocalQmlProfilerRunnerTest::testRunner1() QTRY_COMPARE_WITH_TIMEOUT(runCount, 1, 10000); QTRY_VERIFY_WITH_TIMEOUT(!running, 10000); - configuration.socket = connection.analyzerSocket = LocalQmlProfilerRunner::findFreeSocket(); - configuration.debuggee.executable = QCoreApplication::applicationFilePath(); + configuration.socket = connection.analyzerSocket = QmlProfilerRunner::findFreeSocket(); + debuggee.executable = QCoreApplication::applicationFilePath(); // comma is used to specify a test function. In this case, an invalid one. - configuration.debuggee.commandLineArguments = QString("-test QmlProfiler,"); + debuggee.commandLineArguments = QString("-test QmlProfiler,"); delete rc; rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); - auto worker = new QmlProfilerRunner(rc); + rc->setRunnable(debuggee); rc->setConnection(connection); - auto runner = new LocalQmlProfilerRunner(configuration, worker); + auto runner = new QmlProfilerRunner(rc); + runner->setLocalConfiguration(configuration); connectRunner(runner); rc->initiateStart(); QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner2); @@ -98,15 +105,16 @@ void LocalQmlProfilerRunnerTest::testRunner2() delete rc; - configuration.debuggee.commandLineArguments.clear(); + debuggee.commandLineArguments.clear(); configuration.socket.clear(); connection.analyzerSocket.clear(); configuration.port = connection.analyzerPort = - LocalQmlProfilerRunner::findFreePort(connection.analyzerHost); + QmlProfilerRunner::findFreePort(connection.analyzerHost); rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); - auto worker = new QmlProfilerRunner(rc); + rc->setRunnable(debuggee); rc->setConnection(connection); - auto runner = new LocalQmlProfilerRunner(configuration, worker); + auto runner = new QmlProfilerRunner(rc); + runner->setLocalConfiguration(configuration); connectRunner(runner); rc->initiateStart(); @@ -129,7 +137,7 @@ void LocalQmlProfilerRunnerTest::testRunner4() void LocalQmlProfilerRunnerTest::testFindFreePort() { QString host; - Utils::Port port = LocalQmlProfilerRunner::findFreePort(host); + Utils::Port port = QmlProfilerRunner::findFreePort(host); QVERIFY(port.isValid()); QVERIFY(!host.isEmpty()); QTcpServer server; @@ -138,7 +146,7 @@ void LocalQmlProfilerRunnerTest::testFindFreePort() void LocalQmlProfilerRunnerTest::testFindFreeSocket() { - QString socket = LocalQmlProfilerRunner::findFreeSocket(); + QString socket = QmlProfilerRunner::findFreeSocket(); QVERIFY(!socket.isEmpty()); QVERIFY(!QFile::exists(socket)); QFile file(socket); @@ -146,6 +154,5 @@ void LocalQmlProfilerRunnerTest::testFindFreeSocket() file.close(); } - } // namespace Internal } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.h b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.h index de538e70a89e21ba93a1ebb1b115642333be37b1..69c1604bcec8a976f000d24c64f3eb069f322e3d 100644 --- a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.h +++ b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.h @@ -25,8 +25,8 @@ #pragma once -#include <qmlprofiler/localqmlprofilerrunner.h> #include <qmlprofiler/qmlprofilermodelmanager.h> +#include <qmlprofiler/qmlprofilerruncontrol.h> #include <debugger/analyzer/analyzerstartparameters.h> namespace QmlProfiler { @@ -44,7 +44,7 @@ private slots: void testFindFreeSocket(); private: - void connectRunner(LocalQmlProfilerRunner *runner); + void connectRunner(QmlProfilerRunner *runner); void testRunner1(); void testRunner2(); void testRunner3(); @@ -53,8 +53,9 @@ private: bool running = false; int runCount = 0; ProjectExplorer::RunControl *rc = nullptr; + ProjectExplorer::StandardRunnable debuggee; Debugger::AnalyzerConnection connection; - LocalQmlProfilerRunner::Configuration configuration; + QmlProfilerRunner::Configuration configuration; }; } // namespace Internal diff --git a/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp b/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp index fed9b53d32587e7b16becb4e261363fc2ac5854e..f898782ec1778e0efd1954dc22c59303568017a9 100644 --- a/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp +++ b/src/plugins/qmlprofiler/tests/qmlprofilerclientmanager_test.cpp @@ -24,7 +24,7 @@ ****************************************************************************/ #include "qmlprofilerclientmanager_test.h" -#include <qmlprofiler/localqmlprofilerrunner.h> +#include <qmlprofiler/qmlprofilerruncontrol.h> #include <qmldebug/qpacketprotocol.h> #include <projectexplorer/applicationlauncher.h> @@ -69,7 +69,7 @@ void QmlProfilerClientManagerTest::testConnectionFailure_data() QVarLengthArray<QmlProfilerStateManager *> stateManagers({nullptr, &stateManager}); QString hostName; - Utils::Port port = LocalQmlProfilerRunner::findFreePort(hostName); + Utils::Port port = QmlProfilerRunner::findFreePort(hostName); QTest::addColumn<QString>("host"); QVarLengthArray<QString> hosts({"", "/-/|\\-\\|/-", hostName}); @@ -78,8 +78,7 @@ void QmlProfilerClientManagerTest::testConnectionFailure_data() QVarLengthArray<Utils::Port> ports({Utils::Port(), Utils::Port(5), port}); QTest::addColumn<QString>("socket"); - QVarLengthArray<QString> sockets({"", "/-/|\\-\\|/-", - LocalQmlProfilerRunner::findFreeSocket()}); + QVarLengthArray<QString> sockets({"", "/-/|\\-\\|/-", QmlProfilerRunner::findFreeSocket()}); foreach (QmlProfilerModelManager *modelManager, modelManagers) { foreach (QmlProfilerStateManager *stateManager, stateManagers) { @@ -174,7 +173,7 @@ void QmlProfilerClientManagerTest::testUnresponsiveTcp() clientManager.setModelManager(&modelManager); QString hostName; - Utils::Port port = LocalQmlProfilerRunner::findFreePort(hostName); + Utils::Port port = QmlProfilerRunner::findFreePort(hostName); QTcpServer server; server.listen(QHostAddress(hostName), port.number()); @@ -203,7 +202,7 @@ void QmlProfilerClientManagerTest::testUnresponsiveLocal() clientManager.setProfilerStateManager(&stateManager); clientManager.setModelManager(&modelManager); - QString socketFile = LocalQmlProfilerRunner::findFreeSocket(); + QString socketFile = QmlProfilerRunner::findFreeSocket(); QLocalSocket socket; QSignalSpy connectionSpy(&socket, SIGNAL(connected())); @@ -256,7 +255,7 @@ void QmlProfilerClientManagerTest::testResponsiveTcp() QFETCH(quint32, flushInterval); QString hostName; - Utils::Port port = LocalQmlProfilerRunner::findFreePort(hostName); + Utils::Port port = QmlProfilerRunner::findFreePort(hostName); QSignalSpy openedSpy(&clientManager, SIGNAL(connectionOpened())); QSignalSpy closedSpy(&clientManager, SIGNAL(connectionClosed())); @@ -315,7 +314,7 @@ void QmlProfilerClientManagerTest::testResponsiveLocal() { QFETCH(quint32, flushInterval); - QString socketFile = LocalQmlProfilerRunner::findFreeSocket(); + QString socketFile = QmlProfilerRunner::findFreeSocket(); QSignalSpy openedSpy(&clientManager, SIGNAL(connectionOpened())); QSignalSpy closedSpy(&clientManager, SIGNAL(connectionClosed())); @@ -381,7 +380,7 @@ void QmlProfilerClientManagerTest::testInvalidData() clientManager.setModelManager(&modelManager); QString hostName; - Utils::Port port = LocalQmlProfilerRunner::findFreePort(hostName); + Utils::Port port = QmlProfilerRunner::findFreePort(hostName); bool dataSent = false; QTcpServer server; @@ -412,7 +411,7 @@ void QmlProfilerClientManagerTest::testInvalidData() void QmlProfilerClientManagerTest::testStopRecording() { - QString socketFile = LocalQmlProfilerRunner::findFreeSocket(); + QString socketFile = QmlProfilerRunner::findFreeSocket(); { QmlProfilerClientManager clientManager;