forked from qt-creator/qt-creator
QmlProfiler: Merge LocalQmlProfilerRunner and QmlProfilerRunner
Also streamline code paths in the result. Change-Id: Id7d96343a8f778ba8f415b1a850cc78576afa475 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -9,7 +9,6 @@ SOURCES += \
|
|||||||
flamegraphmodel.cpp \
|
flamegraphmodel.cpp \
|
||||||
flamegraphview.cpp \
|
flamegraphview.cpp \
|
||||||
inputeventsmodel.cpp \
|
inputeventsmodel.cpp \
|
||||||
localqmlprofilerrunner.cpp \
|
|
||||||
memoryusagemodel.cpp \
|
memoryusagemodel.cpp \
|
||||||
pixmapcachemodel.cpp \
|
pixmapcachemodel.cpp \
|
||||||
qmlevent.cpp \
|
qmlevent.cpp \
|
||||||
@@ -50,7 +49,6 @@ HEADERS += \
|
|||||||
flamegraphmodel.h \
|
flamegraphmodel.h \
|
||||||
flamegraphview.h \
|
flamegraphview.h \
|
||||||
inputeventsmodel.h \
|
inputeventsmodel.h \
|
||||||
localqmlprofilerrunner.h \
|
|
||||||
memoryusagemodel.h \
|
memoryusagemodel.h \
|
||||||
pixmapcachemodel.h \
|
pixmapcachemodel.h \
|
||||||
qmlevent.h \
|
qmlevent.h \
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ QtcPlugin {
|
|||||||
"flamegraphmodel.cpp", "flamegraphmodel.h",
|
"flamegraphmodel.cpp", "flamegraphmodel.h",
|
||||||
"flamegraphview.cpp", "flamegraphview.h",
|
"flamegraphview.cpp", "flamegraphview.h",
|
||||||
"inputeventsmodel.cpp", "inputeventsmodel.h",
|
"inputeventsmodel.cpp", "inputeventsmodel.h",
|
||||||
"localqmlprofilerrunner.cpp", "localqmlprofilerrunner.h",
|
|
||||||
"memoryusagemodel.cpp", "memoryusagemodel.h",
|
"memoryusagemodel.cpp", "memoryusagemodel.h",
|
||||||
"pixmapcachemodel.cpp", "pixmapcachemodel.h",
|
"pixmapcachemodel.cpp", "pixmapcachemodel.h",
|
||||||
"qmlevent.cpp", "qmlevent.h",
|
"qmlevent.cpp", "qmlevent.h",
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
namespace ProjectExplorer { class RunConfiguration; }
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
class QmlProfilerModelManager;
|
class QmlProfilerModelManager;
|
||||||
class QmlProfilerNotesModel;
|
class QmlProfilerNotesModel;
|
||||||
|
|||||||
@@ -23,9 +23,10 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qmlprofilerclientmanager.h"
|
||||||
#include "qmlprofilerruncontrol.h"
|
#include "qmlprofilerruncontrol.h"
|
||||||
#include "localqmlprofilerrunner.h"
|
|
||||||
#include "qmlprofilertool.h"
|
#include "qmlprofilertool.h"
|
||||||
|
#include "qmlprofilerplugin.h"
|
||||||
|
|
||||||
#include <debugger/analyzer/analyzermanager.h>
|
#include <debugger/analyzer/analyzermanager.h>
|
||||||
#include <debugger/analyzer/analyzerstartparameters.h>
|
#include <debugger/analyzer/analyzerstartparameters.h>
|
||||||
@@ -33,30 +34,38 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/helpmanager.h>
|
#include <coreplugin/helpmanager.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/devicesupport/idevice.h>
|
||||||
#include <projectexplorer/environmentaspect.h>
|
#include <projectexplorer/environmentaspect.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
#include <projectexplorer/localapplicationruncontrol.h>
|
#include <projectexplorer/localapplicationruncontrol.h>
|
||||||
|
#include <projectexplorer/projectexplorer.h>
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
#include <projectexplorer/projectexplorericons.h>
|
#include <projectexplorer/projectexplorericons.h>
|
||||||
|
#include <projectexplorer/runconfiguration.h>
|
||||||
#include <projectexplorer/runnables.h>
|
#include <projectexplorer/runnables.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
#include <qtsupport/qtsupportconstants.h>
|
#include <qtsupport/qtsupportconstants.h>
|
||||||
|
|
||||||
#include <qmldebug/qmloutputparser.h>
|
#include <qmldebug/qmloutputparser.h>
|
||||||
|
#include <qmldebug/qmldebugcommandlinearguments.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/temporaryfile.h>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QTimer>
|
|
||||||
#include <QTcpServer>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QTcpServer>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
using namespace Debugger;
|
using namespace Debugger;
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
using namespace QmlProfiler::Internal;
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
|
|
||||||
@@ -69,6 +78,10 @@ class QmlProfilerRunner::QmlProfilerRunnerPrivate
|
|||||||
public:
|
public:
|
||||||
QmlProfilerStateManager *m_profilerState = 0;
|
QmlProfilerStateManager *m_profilerState = 0;
|
||||||
QTimer m_noDebugOutputTimer;
|
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()
|
void QmlProfilerRunner::start()
|
||||||
{
|
{
|
||||||
runControl()->reportApplicationStart();
|
|
||||||
Internal::QmlProfilerTool::instance()->finalizeRunControl(this);
|
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>();
|
auto conn = connection().as<AnalyzerConnection>();
|
||||||
|
|
||||||
if (conn.analyzerPort.isValid())
|
if (conn.analyzerPort.isValid()) {
|
||||||
emit processRunning(conn.analyzerPort);
|
auto clientManager = Internal::QmlProfilerTool::clientManager();
|
||||||
|
clientManager->setTcpConnection(conn.analyzerHost, conn.analyzerPort);
|
||||||
|
clientManager->connectToTcpServer();
|
||||||
|
}
|
||||||
else if (conn.analyzerSocket.isEmpty())
|
else if (conn.analyzerSocket.isEmpty())
|
||||||
d->m_noDebugOutputTimer.start();
|
d->m_noDebugOutputTimer.start();
|
||||||
|
|
||||||
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning);
|
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()
|
void QmlProfilerRunner::stop()
|
||||||
@@ -148,7 +189,6 @@ void QmlProfilerRunner::notifyRemoteFinished()
|
|||||||
switch (d->m_profilerState->currentState()) {
|
switch (d->m_profilerState->currentState()) {
|
||||||
case QmlProfilerStateManager::AppRunning:
|
case QmlProfilerStateManager::AppRunning:
|
||||||
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying);
|
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying);
|
||||||
runControl()->reportApplicationStop();
|
|
||||||
break;
|
break;
|
||||||
case QmlProfilerStateManager::Idle:
|
case QmlProfilerStateManager::Idle:
|
||||||
break;
|
break;
|
||||||
@@ -177,7 +217,7 @@ void QmlProfilerRunner::cancelProcess()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
runControl()->reportApplicationStop();
|
runControl()->initiateStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlProfilerRunner::notifyRemoteSetupFailed(const QString &errorMessage)
|
void QmlProfilerRunner::notifyRemoteSetupFailed(const QString &errorMessage)
|
||||||
@@ -200,7 +240,6 @@ void QmlProfilerRunner::notifyRemoteSetupFailed(const QString &errorMessage)
|
|||||||
// KILL
|
// KILL
|
||||||
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying);
|
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying);
|
||||||
d->m_noDebugOutputTimer.stop();
|
d->m_noDebugOutputTimer.stop();
|
||||||
runControl()->reportApplicationStop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlProfilerRunner::wrongSetupMessageBoxFinished(int button)
|
void QmlProfilerRunner::wrongSetupMessageBoxFinished(int button)
|
||||||
@@ -219,8 +258,11 @@ void QmlProfilerRunner::notifyRemoteSetupDone(Utils::Port port)
|
|||||||
QTC_ASSERT(connection().is<AnalyzerConnection>(), return);
|
QTC_ASSERT(connection().is<AnalyzerConnection>(), return);
|
||||||
port = connection().as<AnalyzerConnection>().analyzerPort;
|
port = connection().as<AnalyzerConnection>().analyzerPort;
|
||||||
}
|
}
|
||||||
if (port.isValid())
|
if (port.isValid()) {
|
||||||
emit processRunning(port);
|
auto clientManager = Internal::QmlProfilerTool::clientManager();
|
||||||
|
clientManager->setTcpConnection(connection().as<AnalyzerConnection>().analyzerHost, port);
|
||||||
|
clientManager->connectToTcpServer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlProfilerRunner::registerProfilerStateManager( QmlProfilerStateManager *profilerState )
|
void QmlProfilerRunner::registerProfilerStateManager( QmlProfilerStateManager *profilerState )
|
||||||
@@ -242,7 +284,6 @@ void QmlProfilerRunner::profilerStateChanged()
|
|||||||
{
|
{
|
||||||
switch (d->m_profilerState->currentState()) {
|
switch (d->m_profilerState->currentState()) {
|
||||||
case QmlProfilerStateManager::Idle:
|
case QmlProfilerStateManager::Idle:
|
||||||
runControl()->reportApplicationStop();
|
|
||||||
d->m_noDebugOutputTimer.stop();
|
d->m_noDebugOutputTimer.stop();
|
||||||
break;
|
break;
|
||||||
default:
|
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
|
} // namespace QmlProfiler
|
||||||
|
|||||||
@@ -28,7 +28,12 @@
|
|||||||
#include "qmlprofilerstatemanager.h"
|
#include "qmlprofilerstatemanager.h"
|
||||||
|
|
||||||
#include <projectexplorer/runconfiguration.h>
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
#include <projectexplorer/runnables.h>
|
||||||
|
|
||||||
#include <utils/outputformat.h>
|
#include <utils/outputformat.h>
|
||||||
|
#include <utils/port.h>
|
||||||
|
|
||||||
|
#include <qmldebug/qmloutputparser.h>
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
|
|
||||||
@@ -40,22 +45,37 @@ public:
|
|||||||
QmlProfilerRunner(ProjectExplorer::RunControl *runControl);
|
QmlProfilerRunner(ProjectExplorer::RunControl *runControl);
|
||||||
~QmlProfilerRunner() override;
|
~QmlProfilerRunner() override;
|
||||||
|
|
||||||
|
struct Configuration {
|
||||||
|
Utils::Port port;
|
||||||
|
QString socket;
|
||||||
|
};
|
||||||
|
void setLocalConfiguration(const Configuration &conf);
|
||||||
|
|
||||||
void registerProfilerStateManager( QmlProfilerStateManager *profilerState );
|
void registerProfilerStateManager( QmlProfilerStateManager *profilerState );
|
||||||
|
|
||||||
void notifyRemoteSetupDone(Utils::Port port);
|
void notifyRemoteSetupDone(Utils::Port port);
|
||||||
void notifyRemoteSetupFailed(const QString &errorMessage);
|
void notifyRemoteSetupFailed(const QString &errorMessage);
|
||||||
void start() override;
|
|
||||||
void stop() override;
|
|
||||||
void cancelProcess();
|
void cancelProcess();
|
||||||
void notifyRemoteFinished();
|
void notifyRemoteFinished();
|
||||||
|
|
||||||
|
static Utils::Port findFreePort(QString &host);
|
||||||
|
static QString findFreeSocket();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void processRunning(Utils::Port port);
|
void localRunnerStarted();
|
||||||
|
void localRunnerStopped();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void start() override;
|
||||||
|
void stop() override;
|
||||||
|
|
||||||
void wrongSetupMessageBoxFinished(int);
|
void wrongSetupMessageBoxFinished(int);
|
||||||
void profilerStateChanged();
|
void profilerStateChanged();
|
||||||
|
|
||||||
|
void spontaneousStop(int exitCode, QProcess::ExitStatus status);
|
||||||
|
void startLocalRunner();
|
||||||
|
void stopLocalRunner();
|
||||||
|
|
||||||
class QmlProfilerRunnerPrivate;
|
class QmlProfilerRunnerPrivate;
|
||||||
QmlProfilerRunnerPrivate *d;
|
QmlProfilerRunnerPrivate *d;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qmlprofilerruncontrolfactory.h"
|
#include "qmlprofilerruncontrolfactory.h"
|
||||||
#include "localqmlprofilerrunner.h"
|
|
||||||
#include "qmlprofilerruncontrol.h"
|
#include "qmlprofilerruncontrol.h"
|
||||||
#include "qmlprofilerrunconfigurationaspect.h"
|
#include "qmlprofilerrunconfigurationaspect.h"
|
||||||
|
|
||||||
@@ -60,6 +59,8 @@ static bool isLocal(RunConfiguration *runConfiguration)
|
|||||||
QmlProfilerRunControlFactory::QmlProfilerRunControlFactory(QObject *parent) :
|
QmlProfilerRunControlFactory::QmlProfilerRunControlFactory(QObject *parent) :
|
||||||
IRunControlFactory(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
|
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);
|
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(canRun(runConfiguration, mode), return 0);
|
||||||
QTC_ASSERT(runConfiguration->runnable().is<StandardRunnable>(), 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();
|
Kit *kit = runConfiguration->target()->kit();
|
||||||
AnalyzerConnection connection;
|
AnalyzerConnection connection;
|
||||||
const QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit);
|
const QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit);
|
||||||
if (version) {
|
if (version) {
|
||||||
if (version->qtVersion() >= QtSupport::QtVersionNumber(5, 6, 0))
|
if (version->qtVersion() >= QtSupport::QtVersionNumber(5, 6, 0))
|
||||||
connection.analyzerSocket = LocalQmlProfilerRunner::findFreeSocket();
|
connection.analyzerSocket = QmlProfilerRunner::findFreeSocket();
|
||||||
else
|
else
|
||||||
connection.analyzerPort = LocalQmlProfilerRunner::findFreePort(connection.analyzerHost);
|
connection.analyzerPort = QmlProfilerRunner::findFreePort(connection.analyzerHost);
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "Running QML profiler on Kit without Qt version??";
|
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 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);
|
runControl->setConnection(connection);
|
||||||
|
|
||||||
LocalQmlProfilerRunner::Configuration conf;
|
QmlProfilerRunner::Configuration conf;
|
||||||
conf.debuggee = runnable;
|
|
||||||
if (EnvironmentAspect *environment = runConfiguration->extraAspect<EnvironmentAspect>())
|
|
||||||
conf.debuggee.environment = environment->environment();
|
|
||||||
conf.socket = connection.analyzerSocket;
|
conf.socket = connection.analyzerSocket;
|
||||||
conf.port = connection.analyzerPort;
|
conf.port = connection.analyzerPort;
|
||||||
|
|
||||||
(void) new LocalQmlProfilerRunner(conf, qobject_cast<QmlProfilerRunner *>(runWorker));
|
auto runner = new QmlProfilerRunner(runControl);
|
||||||
|
runner->setLocalConfiguration(conf);
|
||||||
return runControl;
|
return runControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,9 @@
|
|||||||
#include "qmlprofilertextmark.h"
|
#include "qmlprofilertextmark.h"
|
||||||
#include "qmlprofilerconstants.h"
|
#include "qmlprofilerconstants.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QLabel>
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|||||||
@@ -247,17 +247,12 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
|
|||||||
// is available, then we can populate the file finder
|
// is available, then we can populate the file finder
|
||||||
d->m_profilerModelManager->populateFileFinder();
|
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 "
|
QString description = tr("The QML Profiler can be used to find performance "
|
||||||
"bottlenecks in applications using QML.");
|
"bottlenecks in applications using QML.");
|
||||||
|
|
||||||
d->m_startAction = Debugger::createStartAction();
|
d->m_startAction = Debugger::createStartAction();
|
||||||
d->m_stopAction = Debugger::createStopAction();
|
d->m_stopAction = Debugger::createStopAction();
|
||||||
|
|
||||||
RunControl::registerWorkerCreator(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, runWorkerCreator);
|
|
||||||
act = new QAction(tr("QML Profiler"), this);
|
act = new QAction(tr("QML Profiler"), this);
|
||||||
act->setToolTip(description);
|
act->setToolTip(description);
|
||||||
menu->addAction(ActionManager::registerAction(act, "QmlProfiler.Local"),
|
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;
|
d->m_toolBusy = true;
|
||||||
|
auto runControl = runWorker->runControl();
|
||||||
|
auto runConfiguration = runControl->runConfiguration();
|
||||||
if (runConfiguration) {
|
if (runConfiguration) {
|
||||||
QmlProfilerRunConfigurationAspect *aspect = static_cast<QmlProfilerRunConfigurationAspect *>(
|
auto aspect = static_cast<QmlProfilerRunConfigurationAspect *>(
|
||||||
runConfiguration->extraAspect(Constants::SETTINGS));
|
runConfiguration->extraAspect(Constants::SETTINGS));
|
||||||
if (aspect) {
|
if (aspect) {
|
||||||
if (QmlProfilerSettings *settings = static_cast<QmlProfilerSettings *>(aspect->currentSettings())) {
|
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] {
|
connect(runControl, &RunControl::finished, this, [this, runControl] {
|
||||||
d->m_toolBusy = false;
|
d->m_toolBusy = false;
|
||||||
updateRunActions();
|
updateRunActions();
|
||||||
@@ -353,11 +349,6 @@ RunWorker *QmlProfilerTool::createRunner(RunControl *runControl, RunConfiguratio
|
|||||||
connect(d->m_stopAction, &QAction::triggered, runControl, &RunControl::stop);
|
connect(d->m_stopAction, &QAction::triggered, runControl, &RunControl::stop);
|
||||||
|
|
||||||
updateRunActions();
|
updateRunActions();
|
||||||
return runWorker;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker)
|
|
||||||
{
|
|
||||||
runWorker->registerProfilerStateManager(d->m_profilerState);
|
runWorker->registerProfilerStateManager(d->m_profilerState);
|
||||||
QmlProfilerClientManager *clientManager = d->m_profilerConnections;
|
QmlProfilerClientManager *clientManager = d->m_profilerConnections;
|
||||||
|
|
||||||
@@ -376,20 +367,10 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker)
|
|||||||
// Initialize m_projectFinder
|
// Initialize m_projectFinder
|
||||||
//
|
//
|
||||||
|
|
||||||
auto runControl = runWorker->runControl();
|
|
||||||
RunConfiguration *runConfiguration = runControl->runConfiguration();
|
|
||||||
if (runConfiguration) {
|
if (runConfiguration) {
|
||||||
d->m_profilerModelManager->populateFileFinder(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,
|
connect(clientManager, &QmlProfilerClientManager::connectionFailed,
|
||||||
runWorker, [this, clientManager, runWorker]() {
|
runWorker, [this, clientManager, runWorker]() {
|
||||||
QMessageBox *infoBox = new QMessageBox(ICore::mainWindow());
|
QMessageBox *infoBox = new QMessageBox(ICore::mainWindow());
|
||||||
@@ -873,6 +854,11 @@ void QmlProfilerTool::showNonmodalWarning(const QString &warningMsg)
|
|||||||
noExecWarning->show();
|
noExecWarning->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QmlProfilerClientManager *QmlProfilerTool::clientManager()
|
||||||
|
{
|
||||||
|
return s_instance->d->m_profilerConnections;
|
||||||
|
}
|
||||||
|
|
||||||
void QmlProfilerTool::profilerStateChanged()
|
void QmlProfilerTool::profilerStateChanged()
|
||||||
{
|
{
|
||||||
switch (d->m_profilerState->currentState()) {
|
switch (d->m_profilerState->currentState()) {
|
||||||
|
|||||||
@@ -29,11 +29,8 @@
|
|||||||
#include "qmlprofilerconstants.h"
|
#include "qmlprofilerconstants.h"
|
||||||
#include "qmlprofilereventtypes.h"
|
#include "qmlprofilereventtypes.h"
|
||||||
|
|
||||||
#include <debugger/analyzer/analyzermanager.h>
|
#include <QAction>
|
||||||
|
#include <QObject>
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
class QMessageBox;
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
|
|
||||||
@@ -41,6 +38,8 @@ class QmlProfilerRunner;
|
|||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class QmlProfilerClientManager;
|
||||||
|
|
||||||
class QMLPROFILER_EXPORT QmlProfilerTool : public QObject
|
class QMLPROFILER_EXPORT QmlProfilerTool : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -51,8 +50,6 @@ public:
|
|||||||
|
|
||||||
static QmlProfilerTool *instance();
|
static QmlProfilerTool *instance();
|
||||||
|
|
||||||
ProjectExplorer::RunWorker *createRunner(ProjectExplorer::RunControl *runControl,
|
|
||||||
ProjectExplorer::RunConfiguration *runConfiguration = 0);
|
|
||||||
void finalizeRunControl(QmlProfilerRunner *runWorker);
|
void finalizeRunControl(QmlProfilerRunner *runWorker);
|
||||||
|
|
||||||
bool prepareTool();
|
bool prepareTool();
|
||||||
@@ -68,6 +65,8 @@ public:
|
|||||||
static void logError(const QString &msg);
|
static void logError(const QString &msg);
|
||||||
static void showNonmodalWarning(const QString &warningMsg);
|
static void showNonmodalWarning(const QString &warningMsg);
|
||||||
|
|
||||||
|
static QmlProfilerClientManager *clientManager();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void profilerStateChanged();
|
void profilerStateChanged();
|
||||||
void clientRecordingChanged();
|
void clientRecordingChanged();
|
||||||
|
|||||||
@@ -29,9 +29,14 @@
|
|||||||
|
|
||||||
#include <debugger/analyzer/analyzermanager.h>
|
#include <debugger/analyzer/analyzermanager.h>
|
||||||
#include <debugger/analyzer/analyzerstartparameters.h>
|
#include <debugger/analyzer/analyzerstartparameters.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/runnables.h>
|
||||||
|
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
#include <QTcpServer>
|
#include <QTcpServer>
|
||||||
|
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
namespace Internal {
|
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);
|
QVERIFY(!running);
|
||||||
++runCount;
|
++runCount;
|
||||||
running = true;
|
running = true;
|
||||||
});
|
});
|
||||||
connect(runner, &LocalQmlProfilerRunner::stopped, this, [this] {
|
connect(runner, &QmlProfilerRunner::localRunnerStopped, this, [this] {
|
||||||
QVERIFY(running);
|
QVERIFY(running);
|
||||||
running = false;
|
running = false;
|
||||||
});
|
});
|
||||||
@@ -54,16 +59,17 @@ void LocalQmlProfilerRunnerTest::connectRunner(LocalQmlProfilerRunner *runner)
|
|||||||
|
|
||||||
void LocalQmlProfilerRunnerTest::testRunner()
|
void LocalQmlProfilerRunnerTest::testRunner()
|
||||||
{
|
{
|
||||||
configuration.debuggee.executable = "\\-/|\\-/";
|
debuggee.executable = "\\-/|\\-/";
|
||||||
configuration.debuggee.environment = Utils::Environment::systemEnvironment();
|
debuggee.environment = Utils::Environment::systemEnvironment();
|
||||||
|
|
||||||
// should not be used anywhere but cannot be empty
|
// should not be used anywhere but cannot be empty
|
||||||
configuration.socket = connection.analyzerSocket = QString("invalid");
|
configuration.socket = connection.analyzerSocket = QString("invalid");
|
||||||
|
|
||||||
rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
|
rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
|
||||||
auto worker = new QmlProfilerRunner(rc);
|
rc->setRunnable(debuggee);
|
||||||
rc->setConnection(connection);
|
rc->setConnection(connection);
|
||||||
auto runner = new LocalQmlProfilerRunner(configuration, worker);
|
auto runner = new QmlProfilerRunner(rc);
|
||||||
|
runner->setLocalConfiguration(configuration);
|
||||||
connectRunner(runner);
|
connectRunner(runner);
|
||||||
|
|
||||||
rc->initiateStart();
|
rc->initiateStart();
|
||||||
@@ -75,17 +81,18 @@ void LocalQmlProfilerRunnerTest::testRunner1()
|
|||||||
QTRY_COMPARE_WITH_TIMEOUT(runCount, 1, 10000);
|
QTRY_COMPARE_WITH_TIMEOUT(runCount, 1, 10000);
|
||||||
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
|
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
|
||||||
|
|
||||||
configuration.socket = connection.analyzerSocket = LocalQmlProfilerRunner::findFreeSocket();
|
configuration.socket = connection.analyzerSocket = QmlProfilerRunner::findFreeSocket();
|
||||||
configuration.debuggee.executable = QCoreApplication::applicationFilePath();
|
|
||||||
|
|
||||||
|
debuggee.executable = QCoreApplication::applicationFilePath();
|
||||||
// comma is used to specify a test function. In this case, an invalid one.
|
// 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;
|
delete rc;
|
||||||
rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
|
rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
|
||||||
auto worker = new QmlProfilerRunner(rc);
|
rc->setRunnable(debuggee);
|
||||||
rc->setConnection(connection);
|
rc->setConnection(connection);
|
||||||
auto runner = new LocalQmlProfilerRunner(configuration, worker);
|
auto runner = new QmlProfilerRunner(rc);
|
||||||
|
runner->setLocalConfiguration(configuration);
|
||||||
connectRunner(runner);
|
connectRunner(runner);
|
||||||
rc->initiateStart();
|
rc->initiateStart();
|
||||||
QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner2);
|
QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner2);
|
||||||
@@ -98,15 +105,16 @@ void LocalQmlProfilerRunnerTest::testRunner2()
|
|||||||
|
|
||||||
delete rc;
|
delete rc;
|
||||||
|
|
||||||
configuration.debuggee.commandLineArguments.clear();
|
debuggee.commandLineArguments.clear();
|
||||||
configuration.socket.clear();
|
configuration.socket.clear();
|
||||||
connection.analyzerSocket.clear();
|
connection.analyzerSocket.clear();
|
||||||
configuration.port = connection.analyzerPort =
|
configuration.port = connection.analyzerPort =
|
||||||
LocalQmlProfilerRunner::findFreePort(connection.analyzerHost);
|
QmlProfilerRunner::findFreePort(connection.analyzerHost);
|
||||||
rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
|
rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
|
||||||
auto worker = new QmlProfilerRunner(rc);
|
rc->setRunnable(debuggee);
|
||||||
rc->setConnection(connection);
|
rc->setConnection(connection);
|
||||||
auto runner = new LocalQmlProfilerRunner(configuration, worker);
|
auto runner = new QmlProfilerRunner(rc);
|
||||||
|
runner->setLocalConfiguration(configuration);
|
||||||
connectRunner(runner);
|
connectRunner(runner);
|
||||||
rc->initiateStart();
|
rc->initiateStart();
|
||||||
|
|
||||||
@@ -129,7 +137,7 @@ void LocalQmlProfilerRunnerTest::testRunner4()
|
|||||||
void LocalQmlProfilerRunnerTest::testFindFreePort()
|
void LocalQmlProfilerRunnerTest::testFindFreePort()
|
||||||
{
|
{
|
||||||
QString host;
|
QString host;
|
||||||
Utils::Port port = LocalQmlProfilerRunner::findFreePort(host);
|
Utils::Port port = QmlProfilerRunner::findFreePort(host);
|
||||||
QVERIFY(port.isValid());
|
QVERIFY(port.isValid());
|
||||||
QVERIFY(!host.isEmpty());
|
QVERIFY(!host.isEmpty());
|
||||||
QTcpServer server;
|
QTcpServer server;
|
||||||
@@ -138,7 +146,7 @@ void LocalQmlProfilerRunnerTest::testFindFreePort()
|
|||||||
|
|
||||||
void LocalQmlProfilerRunnerTest::testFindFreeSocket()
|
void LocalQmlProfilerRunnerTest::testFindFreeSocket()
|
||||||
{
|
{
|
||||||
QString socket = LocalQmlProfilerRunner::findFreeSocket();
|
QString socket = QmlProfilerRunner::findFreeSocket();
|
||||||
QVERIFY(!socket.isEmpty());
|
QVERIFY(!socket.isEmpty());
|
||||||
QVERIFY(!QFile::exists(socket));
|
QVERIFY(!QFile::exists(socket));
|
||||||
QFile file(socket);
|
QFile file(socket);
|
||||||
@@ -146,6 +154,5 @@ void LocalQmlProfilerRunnerTest::testFindFreeSocket()
|
|||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace QmlProfiler
|
} // namespace QmlProfiler
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <qmlprofiler/localqmlprofilerrunner.h>
|
|
||||||
#include <qmlprofiler/qmlprofilermodelmanager.h>
|
#include <qmlprofiler/qmlprofilermodelmanager.h>
|
||||||
|
#include <qmlprofiler/qmlprofilerruncontrol.h>
|
||||||
#include <debugger/analyzer/analyzerstartparameters.h>
|
#include <debugger/analyzer/analyzerstartparameters.h>
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
@@ -44,7 +44,7 @@ private slots:
|
|||||||
void testFindFreeSocket();
|
void testFindFreeSocket();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void connectRunner(LocalQmlProfilerRunner *runner);
|
void connectRunner(QmlProfilerRunner *runner);
|
||||||
void testRunner1();
|
void testRunner1();
|
||||||
void testRunner2();
|
void testRunner2();
|
||||||
void testRunner3();
|
void testRunner3();
|
||||||
@@ -53,8 +53,9 @@ private:
|
|||||||
bool running = false;
|
bool running = false;
|
||||||
int runCount = 0;
|
int runCount = 0;
|
||||||
ProjectExplorer::RunControl *rc = nullptr;
|
ProjectExplorer::RunControl *rc = nullptr;
|
||||||
|
ProjectExplorer::StandardRunnable debuggee;
|
||||||
Debugger::AnalyzerConnection connection;
|
Debugger::AnalyzerConnection connection;
|
||||||
LocalQmlProfilerRunner::Configuration configuration;
|
QmlProfilerRunner::Configuration configuration;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qmlprofilerclientmanager_test.h"
|
#include "qmlprofilerclientmanager_test.h"
|
||||||
#include <qmlprofiler/localqmlprofilerrunner.h>
|
#include <qmlprofiler/qmlprofilerruncontrol.h>
|
||||||
#include <qmldebug/qpacketprotocol.h>
|
#include <qmldebug/qpacketprotocol.h>
|
||||||
#include <projectexplorer/applicationlauncher.h>
|
#include <projectexplorer/applicationlauncher.h>
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ void QmlProfilerClientManagerTest::testConnectionFailure_data()
|
|||||||
QVarLengthArray<QmlProfilerStateManager *> stateManagers({nullptr, &stateManager});
|
QVarLengthArray<QmlProfilerStateManager *> stateManagers({nullptr, &stateManager});
|
||||||
|
|
||||||
QString hostName;
|
QString hostName;
|
||||||
Utils::Port port = LocalQmlProfilerRunner::findFreePort(hostName);
|
Utils::Port port = QmlProfilerRunner::findFreePort(hostName);
|
||||||
|
|
||||||
QTest::addColumn<QString>("host");
|
QTest::addColumn<QString>("host");
|
||||||
QVarLengthArray<QString> hosts({"", "/-/|\\-\\|/-", hostName});
|
QVarLengthArray<QString> hosts({"", "/-/|\\-\\|/-", hostName});
|
||||||
@@ -78,8 +78,7 @@ void QmlProfilerClientManagerTest::testConnectionFailure_data()
|
|||||||
QVarLengthArray<Utils::Port> ports({Utils::Port(), Utils::Port(5), port});
|
QVarLengthArray<Utils::Port> ports({Utils::Port(), Utils::Port(5), port});
|
||||||
|
|
||||||
QTest::addColumn<QString>("socket");
|
QTest::addColumn<QString>("socket");
|
||||||
QVarLengthArray<QString> sockets({"", "/-/|\\-\\|/-",
|
QVarLengthArray<QString> sockets({"", "/-/|\\-\\|/-", QmlProfilerRunner::findFreeSocket()});
|
||||||
LocalQmlProfilerRunner::findFreeSocket()});
|
|
||||||
|
|
||||||
foreach (QmlProfilerModelManager *modelManager, modelManagers) {
|
foreach (QmlProfilerModelManager *modelManager, modelManagers) {
|
||||||
foreach (QmlProfilerStateManager *stateManager, stateManagers) {
|
foreach (QmlProfilerStateManager *stateManager, stateManagers) {
|
||||||
@@ -174,7 +173,7 @@ void QmlProfilerClientManagerTest::testUnresponsiveTcp()
|
|||||||
clientManager.setModelManager(&modelManager);
|
clientManager.setModelManager(&modelManager);
|
||||||
|
|
||||||
QString hostName;
|
QString hostName;
|
||||||
Utils::Port port = LocalQmlProfilerRunner::findFreePort(hostName);
|
Utils::Port port = QmlProfilerRunner::findFreePort(hostName);
|
||||||
|
|
||||||
QTcpServer server;
|
QTcpServer server;
|
||||||
server.listen(QHostAddress(hostName), port.number());
|
server.listen(QHostAddress(hostName), port.number());
|
||||||
@@ -203,7 +202,7 @@ void QmlProfilerClientManagerTest::testUnresponsiveLocal()
|
|||||||
clientManager.setProfilerStateManager(&stateManager);
|
clientManager.setProfilerStateManager(&stateManager);
|
||||||
clientManager.setModelManager(&modelManager);
|
clientManager.setModelManager(&modelManager);
|
||||||
|
|
||||||
QString socketFile = LocalQmlProfilerRunner::findFreeSocket();
|
QString socketFile = QmlProfilerRunner::findFreeSocket();
|
||||||
QLocalSocket socket;
|
QLocalSocket socket;
|
||||||
QSignalSpy connectionSpy(&socket, SIGNAL(connected()));
|
QSignalSpy connectionSpy(&socket, SIGNAL(connected()));
|
||||||
|
|
||||||
@@ -256,7 +255,7 @@ void QmlProfilerClientManagerTest::testResponsiveTcp()
|
|||||||
QFETCH(quint32, flushInterval);
|
QFETCH(quint32, flushInterval);
|
||||||
|
|
||||||
QString hostName;
|
QString hostName;
|
||||||
Utils::Port port = LocalQmlProfilerRunner::findFreePort(hostName);
|
Utils::Port port = QmlProfilerRunner::findFreePort(hostName);
|
||||||
|
|
||||||
QSignalSpy openedSpy(&clientManager, SIGNAL(connectionOpened()));
|
QSignalSpy openedSpy(&clientManager, SIGNAL(connectionOpened()));
|
||||||
QSignalSpy closedSpy(&clientManager, SIGNAL(connectionClosed()));
|
QSignalSpy closedSpy(&clientManager, SIGNAL(connectionClosed()));
|
||||||
@@ -315,7 +314,7 @@ void QmlProfilerClientManagerTest::testResponsiveLocal()
|
|||||||
{
|
{
|
||||||
QFETCH(quint32, flushInterval);
|
QFETCH(quint32, flushInterval);
|
||||||
|
|
||||||
QString socketFile = LocalQmlProfilerRunner::findFreeSocket();
|
QString socketFile = QmlProfilerRunner::findFreeSocket();
|
||||||
|
|
||||||
QSignalSpy openedSpy(&clientManager, SIGNAL(connectionOpened()));
|
QSignalSpy openedSpy(&clientManager, SIGNAL(connectionOpened()));
|
||||||
QSignalSpy closedSpy(&clientManager, SIGNAL(connectionClosed()));
|
QSignalSpy closedSpy(&clientManager, SIGNAL(connectionClosed()));
|
||||||
@@ -381,7 +380,7 @@ void QmlProfilerClientManagerTest::testInvalidData()
|
|||||||
clientManager.setModelManager(&modelManager);
|
clientManager.setModelManager(&modelManager);
|
||||||
|
|
||||||
QString hostName;
|
QString hostName;
|
||||||
Utils::Port port = LocalQmlProfilerRunner::findFreePort(hostName);
|
Utils::Port port = QmlProfilerRunner::findFreePort(hostName);
|
||||||
|
|
||||||
bool dataSent = false;
|
bool dataSent = false;
|
||||||
QTcpServer server;
|
QTcpServer server;
|
||||||
@@ -412,7 +411,7 @@ void QmlProfilerClientManagerTest::testInvalidData()
|
|||||||
|
|
||||||
void QmlProfilerClientManagerTest::testStopRecording()
|
void QmlProfilerClientManagerTest::testStopRecording()
|
||||||
{
|
{
|
||||||
QString socketFile = LocalQmlProfilerRunner::findFreeSocket();
|
QString socketFile = QmlProfilerRunner::findFreeSocket();
|
||||||
|
|
||||||
{
|
{
|
||||||
QmlProfilerClientManager clientManager;
|
QmlProfilerClientManager clientManager;
|
||||||
|
|||||||
Reference in New Issue
Block a user