diff options
368 files changed, 5315 insertions, 5203 deletions
diff --git a/.qmake.conf b/.qmake.conf index fc13c75da5..3bc6c0a02b 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -2,4 +2,4 @@ load(qt_build_config) CONFIG += qt_example_installs CONFIG += warning_clean -MODULE_VERSION = 5.6.0 +MODULE_VERSION = 5.7.0 diff --git a/src/imports/folderlistmodel/fileinfothread.cpp b/src/imports/folderlistmodel/fileinfothread.cpp index ebdfba42a8..731eb45460 100644 --- a/src/imports/folderlistmodel/fileinfothread.cpp +++ b/src/imports/folderlistmodel/fileinfothread.cpp @@ -52,7 +52,8 @@ FileInfoThread::FileInfoThread(QObject *parent) showDirsFirst(false), showDotAndDotDot(false), showHidden(false), - showOnlyReadable(false) + showOnlyReadable(false), + caseSensitive(true) { #ifndef QT_NO_FILESYSTEMWATCHER watcher = new QFileSystemWatcher(this); @@ -190,6 +191,14 @@ void FileInfoThread::setShowOnlyReadable(bool on) condition.wakeAll(); } +void FileInfoThread::setCaseSensitive(bool on) +{ + QMutexLocker locker(&mutex); + caseSensitive = on; + folderUpdate = true; + condition.wakeAll(); +} + #ifndef QT_NO_FILESYSTEMWATCHER void FileInfoThread::updateFile(const QString &path) { @@ -228,7 +237,8 @@ void FileInfoThread::run() void FileInfoThread::getFileInfos(const QString &path) { QDir::Filters filter; - filter = QDir::CaseSensitive; + if (caseSensitive) + filter = QDir::CaseSensitive; if (showFiles) filter = filter | QDir::Files; if (showDirs) diff --git a/src/imports/folderlistmodel/fileinfothread_p.h b/src/imports/folderlistmodel/fileinfothread_p.h index b375584ff8..5f62f39a20 100644 --- a/src/imports/folderlistmodel/fileinfothread_p.h +++ b/src/imports/folderlistmodel/fileinfothread_p.h @@ -79,6 +79,7 @@ public: void setShowDotAndDotDot(bool on); void setShowHidden(bool on); void setShowOnlyReadable(bool on); + void setCaseSensitive(bool on); public Q_SLOTS: #ifndef QT_NO_FILESYSTEMWATCHER @@ -113,6 +114,7 @@ private: bool showDotAndDotDot; bool showHidden; bool showOnlyReadable; + bool caseSensitive; }; #endif // FILEINFOTHREAD_P_H diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp index a2536bdc7d..7280fcd1dc 100644 --- a/src/imports/folderlistmodel/plugin.cpp +++ b/src/imports/folderlistmodel/plugin.cpp @@ -52,6 +52,7 @@ public: qmlRegisterType<QQuickFolderListModel>(uri,1,0,"FolderListModel"); qmlRegisterType<QQuickFolderListModel>(uri,2,0,"FolderListModel"); qmlRegisterType<QQuickFolderListModel,1>(uri,2,1,"FolderListModel"); + qmlRegisterType<QQuickFolderListModel,2>(uri,2,2,"FolderListModel"); #endif } }; diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp index 8bfbf09769..839e0f42c7 100644 --- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp +++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp @@ -49,7 +49,7 @@ public: : q_ptr(q), sortField(QQuickFolderListModel::Name), sortReversed(false), showFiles(true), showDirs(true), showDirsFirst(false), showDotAndDotDot(false), showOnlyReadable(false), - showHidden(false) + showHidden(false), caseSensitive(true) { nameFilters << QLatin1String("*"); } @@ -70,6 +70,7 @@ public: bool showDotAndDotDot; bool showOnlyReadable; bool showHidden; + bool caseSensitive; ~QQuickFolderListModelPrivate() {} void init(); @@ -762,6 +763,30 @@ void QQuickFolderListModel::setShowOnlyReadable(bool on) } /*! + * \qmlproperty bool FolderListModel::caseSensitive + * \since 5.7 + * + * Use case sensitive pattern matching. + * + * By default, this property is true. + * + */ +bool QQuickFolderListModel::caseSensitive() const +{ + Q_D(const QQuickFolderListModel); + return d->caseSensitive; +} + +void QQuickFolderListModel::setCaseSensitive(bool on) +{ + Q_D(QQuickFolderListModel); + + if (on != d->caseSensitive) { + d->fileInfoThread.setCaseSensitive(on); + } +} + +/*! \qmlmethod var FolderListModel::get(int index, string property) Get the folder property for the given index. The following properties diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h index fcfec56c87..4b540742b4 100644 --- a/src/imports/folderlistmodel/qquickfolderlistmodel.h +++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h @@ -67,6 +67,7 @@ class QQuickFolderListModel : public QAbstractListModel, public QQmlParserStatus Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot) Q_PROPERTY(bool showHidden READ showHidden WRITE setShowHidden REVISION 1) Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable) + Q_PROPERTY(bool caseSensitive READ caseSensitive WRITE setCaseSensitive REVISION 2) Q_PROPERTY(int count READ count NOTIFY countChanged) //![class props] @@ -128,6 +129,8 @@ public: void setShowHidden(bool on); bool showOnlyReadable() const; void setShowOnlyReadable(bool on); + bool caseSensitive() const; + void setCaseSensitive(bool on); //![prop funcs] Q_INVOKABLE bool isFolder(int index) const; diff --git a/src/plugins/qmltooling/packetprotocol/packetprotocol.pro b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro new file mode 100644 index 0000000000..383e32b54e --- /dev/null +++ b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro @@ -0,0 +1,13 @@ +TARGET = QtPacketProtocol +QT = core-private qml-private +CONFIG += static internal_module + +HEADERS = \ + qpacketprotocol_p.h \ + qpacket_p.h + +SOURCES = \ + qpacketprotocol.cpp \ + qpacket.cpp + +load(qt_module) diff --git a/src/plugins/qmltooling/packetprotocol/qpacket.cpp b/src/plugins/qmltooling/packetprotocol/qpacket.cpp new file mode 100644 index 0000000000..1bb611ab25 --- /dev/null +++ b/src/plugins/qmltooling/packetprotocol/qpacket.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpacket_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QPacket + \internal + + \brief The QPacket class encapsulates an unfragmentable packet of data to be + transmitted by QPacketProtocol. + + The QPacket class works together with QPacketProtocol to make it simple to + send arbitrary sized data "packets" across fragmented transports such as TCP + and UDP. + + QPacket provides a QDataStream interface to an unfragmentable packet. + Applications should construct a QPacket, propagate it with data and then + transmit it over a QPacketProtocol instance. For example: + \code + int version = QDataStream::Qt_DefaultCompiledVersion; + QPacketProtocol protocol(...); + + QPacket myPacket(version); + myPacket << "Hello world!" << 123; + protocol.send(myPacket.data()); + \endcode + + As long as both ends of the connection are using the QPacketProtocol class + and the same data stream version, the data within this packet will be + delivered unfragmented at the other end, ready for extraction. + + \code + QByteArray greeting; + int count; + + QPacket myPacket(version, protocol.read()); + + myPacket >> greeting >> count; + \endcode + + Only packets constructed from raw byte arrays may be read from. Empty QPacket + instances are for transmission only and are considered "write only". Attempting + to read data from them will result in undefined behavior. + + \ingroup io + \sa QPacketProtocol + */ + + +/*! + Constructs an empty write-only packet. + */ +QPacket::QPacket(int version) +{ + buf.open(QIODevice::WriteOnly); + setDevice(&buf); + setVersion(version); +} + +/*! + Constructs a read-only packet. + */ +QPacket::QPacket(int version, const QByteArray &data) +{ + buf.setData(data); + buf.open(QIODevice::ReadOnly); + setDevice(&buf); + setVersion(version); +} + +/*! + Returns raw packet data. + */ +QByteArray QPacket::data() const +{ + return buf.data(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/shared/qpacketprotocol.h b/src/plugins/qmltooling/packetprotocol/qpacket_p.h index c571e8d2b8..dda152dfd1 100644 --- a/src/plugins/qmltooling/shared/qpacketprotocol.h +++ b/src/plugins/qmltooling/packetprotocol/qpacket_p.h @@ -31,81 +31,37 @@ ** ****************************************************************************/ -#ifndef QPACKETPROTOCOL_H -#define QPACKETPROTOCOL_H +#ifndef QPACKET_H +#define QPACKET_H -#include <QtCore/qobject.h> #include <QtCore/qdatastream.h> +#include <QtCore/qbuffer.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// QT_BEGIN_NAMESPACE -class QIODevice; -class QBuffer; -class QPacket; -class QPacketAutoSend; -class QPacketProtocolPrivate; - -class QPacketProtocol : public QObject -{ - Q_OBJECT -public: - explicit QPacketProtocol(QIODevice *dev, QObject *parent = 0); - virtual ~QPacketProtocol(); - - qint32 maximumPacketSize() const; - qint32 setMaximumPacketSize(qint32); - - QPacketAutoSend send(); - void send(const QPacket &); - - qint64 packetsAvailable() const; - QPacket read(); - - bool waitForReadyRead(int msecs = 3000); - - void clear(); - - QIODevice *device(); - -Q_SIGNALS: - void readyRead(); - void invalidPacket(); - void packetWritten(); - -private: - QPacketProtocolPrivate *d; -}; - - class QPacket : public QDataStream { public: - QPacket(); - QPacket(const QPacket &); - virtual ~QPacket(); - - void clear(); - bool isEmpty() const; + QPacket(int version); + explicit QPacket(int version, const QByteArray &ba); QByteArray data() const; -protected: - friend class QPacketProtocol; - QPacket(const QByteArray &ba); - QByteArray b; - QBuffer *buf; -}; - -class QPacketAutoSend : public QPacket -{ -public: - virtual ~QPacketAutoSend(); - private: - friend class QPacketProtocol; - QPacketAutoSend(QPacketProtocol *); - QPacketProtocol *p; + void init(QIODevice::OpenMode mode); + QBuffer buf; }; QT_END_NAMESPACE -#endif +#endif // QPACKET_H diff --git a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp new file mode 100644 index 0000000000..d576e74e53 --- /dev/null +++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp @@ -0,0 +1,293 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpacketprotocol_p.h" + +#include <QtCore/QElapsedTimer> +#include <private/qiodevice_p.h> +#include <private/qobject_p.h> + +QT_BEGIN_NAMESPACE + +static const int MAX_PACKET_SIZE = 0x7FFFFFFF; + +/*! + \class QPacketProtocol + \internal + + \brief The QPacketProtocol class encapsulates communicating discrete packets + across fragmented IO channels, such as TCP sockets. + + QPacketProtocol makes it simple to send arbitrary sized data "packets" across + fragmented transports such as TCP and UDP. + + As transmission boundaries are not respected, sending packets over protocols + like TCP frequently involves "stitching" them back together at the receiver. + QPacketProtocol makes this easier by performing this task for you. Packet + data sent using QPacketProtocol is prepended with a 4-byte size header + allowing the receiving QPacketProtocol to buffer the packet internally until + it has all been received. QPacketProtocol does not perform any sanity + checking on the size or on the data, so this class should only be used in + prototyping or trusted situations where DOS attacks are unlikely. + + QPacketProtocol does not perform any communications itself. Instead it can + operate on any QIODevice that supports the QIODevice::readyRead() signal. A + logical "packet" is simply a QByteArray. The following example how to send + data using QPacketProtocol. + + \code + QTcpSocket socket; + // ... connect socket ... + + QPacketProtocol protocol(&socket); + + // Send a packet + QDataStream packet; + packet << "Hello world" << 123; + protocol.send(packet.data()); + \endcode + + Likewise, the following shows how to read data from QPacketProtocol, assuming + that the QPacketProtocol::readyRead() signal has been emitted. + + \code + // ... QPacketProtocol::readyRead() is emitted ... + + int a; + QByteArray b; + + // Receive packet + QDataStream packet(protocol.read()); + p >> a >> b; + \endcode + + \ingroup io +*/ + +class QPacketProtocolPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QPacketProtocol) +public: + QPacketProtocolPrivate(QIODevice *dev); + + QList<qint64> sendingPackets; + QList<QByteArray> packets; + QByteArray inProgress; + qint32 inProgressSize; + bool waitingForPacket; + QIODevice *dev; +}; + +/*! + Construct a QPacketProtocol instance that works on \a dev with the + specified \a parent. + */ +QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent) + : QObject(*(new QPacketProtocolPrivate(dev)), parent) +{ + Q_ASSERT(4 == sizeof(qint32)); + Q_ASSERT(dev); + + QObject::connect(dev, SIGNAL(readyRead()), + this, SLOT(readyToRead())); + QObject::connect(dev, SIGNAL(aboutToClose()), + this, SLOT(aboutToClose())); + QObject::connect(dev, SIGNAL(bytesWritten(qint64)), + this, SLOT(bytesWritten(qint64))); +} + +/*! + \fn void QPacketProtocol::send(const QByteArray &data) + + Transmit the \a packet. + */ +void QPacketProtocol::send(const QByteArray &data) +{ + Q_D(QPacketProtocol); + + if (data.isEmpty()) + return; // We don't send empty packets + qint64 sendSize = data.size() + sizeof(qint32); + + d->sendingPackets.append(sendSize); + qint32 sendSize32 = sendSize; + qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32)); + Q_UNUSED(writeBytes); + Q_ASSERT(writeBytes == sizeof(qint32)); + writeBytes = d->dev->write(data); + Q_ASSERT(writeBytes == data.size()); +} + +/*! + Returns the number of received packets yet to be read. + */ +qint64 QPacketProtocol::packetsAvailable() const +{ + Q_D(const QPacketProtocol); + return d->packets.count(); +} + +/*! + Return the next unread packet, or an empty QByteArray if no packets + are available. This method does NOT block. + */ +QByteArray QPacketProtocol::read() +{ + Q_D(QPacketProtocol); + return d->packets.isEmpty() ? QByteArray() : d->packets.takeFirst(); +} + +/*! + This function locks until a new packet is available for reading and the + \l{QIODevice::}{readyRead()} signal has been emitted. The function + will timeout after \a msecs milliseconds; the default timeout is + 30000 milliseconds. + + The function returns true if the readyRead() signal is emitted and + there is new data available for reading; otherwise it returns false + (if an error occurred or the operation timed out). + */ + +bool QPacketProtocol::waitForReadyRead(int msecs) +{ + Q_D(QPacketProtocol); + if (!d->packets.isEmpty()) + return true; + + QElapsedTimer stopWatch; + stopWatch.start(); + + d->waitingForPacket = true; + do { + if (!d->dev->waitForReadyRead(msecs)) + return false; + if (!d->waitingForPacket) + return true; + msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed()); + } while (true); +} + +/*! + Return the QIODevice passed to the QPacketProtocol constructor. +*/ +void QPacketProtocol::aboutToClose() +{ + Q_D(QPacketProtocol); + d->inProgress.clear(); + d->sendingPackets.clear(); + d->inProgressSize = -1; +} + +void QPacketProtocol::bytesWritten(qint64 bytes) +{ + Q_D(QPacketProtocol); + Q_ASSERT(!d->sendingPackets.isEmpty()); + + while (bytes) { + if (d->sendingPackets.at(0) > bytes) { + d->sendingPackets[0] -= bytes; + bytes = 0; + } else { + bytes -= d->sendingPackets.at(0); + d->sendingPackets.removeFirst(); + } + } +} + +void QPacketProtocol::readyToRead() +{ + Q_D(QPacketProtocol); + while (true) { + // Need to get trailing data + if (-1 == d->inProgressSize) { + // We need a size header of sizeof(qint32) + if (sizeof(qint32) > (uint)d->dev->bytesAvailable()) + return; + + // Read size header + int read = d->dev->read((char *)&d->inProgressSize, sizeof(qint32)); + Q_ASSERT(read == sizeof(qint32)); + Q_UNUSED(read); + + // Check sizing constraints + if (d->inProgressSize > MAX_PACKET_SIZE) { + QObject::disconnect(d->dev, SIGNAL(readyRead()), + this, SLOT(readyToRead())); + QObject::disconnect(d->dev, SIGNAL(aboutToClose()), + this, SLOT(aboutToClose())); + QObject::disconnect(d->dev, SIGNAL(bytesWritten(qint64)), + this, SLOT(bytesWritten(qint64))); + d->dev = 0; + emit invalidPacket(); + return; + } + + d->inProgressSize -= sizeof(qint32); + } else { + d->inProgress.append(d->dev->read(d->inProgressSize - d->inProgress.size())); + + if (d->inProgressSize == d->inProgress.size()) { + // Packet has arrived! + d->packets.append(d->inProgress); + d->inProgressSize = -1; + d->inProgress.clear(); + + d->waitingForPacket = false; + emit readyRead(); + } else + return; + } + } +} + +QPacketProtocolPrivate::QPacketProtocolPrivate(QIODevice *dev) : + inProgressSize(-1), waitingForPacket(false), dev(dev) +{ +} + +/*! + \fn void QPacketProtocol::readyRead() + + Emitted whenever a new packet is received. Applications may use + QPacketProtocol::read() to retrieve this packet. + */ + +/*! + \fn void QPacketProtocol::invalidPacket() + + A packet larger than the maximum allowable packet size was received. The + packet will be discarded and, as it indicates corruption in the protocol, no + further packets will be received. + */ + +QT_END_NAMESPACE diff --git a/tools/qmlprofiler/qpacketprotocol.h b/src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h index 17608033f4..20bbc66418 100644 --- a/tools/qmlprofiler/qpacketprotocol.h +++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h @@ -31,79 +31,49 @@ ** ****************************************************************************/ -#ifndef QPACKETPROTOCOL_H -#define QPACKETPROTOCOL_H +#ifndef QPACKETPROTOCOL_P_H +#define QPACKETPROTOCOL_P_H #include <QtCore/qobject.h> -#include <QtCore/qdatastream.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// QT_BEGIN_NAMESPACE + class QIODevice; -class QBuffer; -QT_END_NAMESPACE -class QPacket; -class QPacketAutoSend; -class QPacketProtocolPrivate; +class QPacketProtocolPrivate; class QPacketProtocol : public QObject { Q_OBJECT + Q_DECLARE_PRIVATE(QPacketProtocol) public: explicit QPacketProtocol(QIODevice *dev, QObject *parent = 0); - virtual ~QPacketProtocol(); - - qint32 maximumPacketSize() const; - qint32 setMaximumPacketSize(qint32); - - QPacketAutoSend send(); - void send(const QPacket &); + void send(const QByteArray &data); qint64 packetsAvailable() const; - QPacket read(); - + QByteArray read(); bool waitForReadyRead(int msecs = 3000); - void clear(); - - QIODevice *device(); - Q_SIGNALS: void readyRead(); void invalidPacket(); - void packetWritten(); - -private: - QPacketProtocolPrivate *d; -}; - - -class QPacket : public QDataStream -{ -public: - QPacket(); - QPacket(const QPacket &); - virtual ~QPacket(); - - void clear(); - bool isEmpty() const; - QByteArray data() const; -protected: - friend class QPacketProtocol; - QPacket(const QByteArray &ba); - QByteArray b; - QBuffer *buf; +private Q_SLOTS: + void aboutToClose(); + void bytesWritten(qint64 bytes); + void readyToRead(); }; -class QPacketAutoSend : public QPacket -{ -public: - virtual ~QPacketAutoSend(); - -private: - friend class QPacketProtocol; - QPacketAutoSend(QPacketProtocol *); - QPacketProtocol *p; -}; +QT_END_NAMESPACE -#endif +#endif // QPACKETPROTOCOL_P_H diff --git a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp index 6bccec08b1..6880417f1d 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp @@ -32,51 +32,48 @@ ****************************************************************************/ #include "qdebugmessageservice.h" +#include "qqmldebugpacket.h" #include <private/qqmldebugconnector_p.h> -#include <QDataStream> - QT_BEGIN_NAMESPACE -const QString QDebugMessageService::s_key = QStringLiteral("DebugMessages"); - void DebugMessageHandler(QtMsgType type, const QMessageLogContext &ctxt, const QString &buf) { - QQmlDebugConnector::service<QDebugMessageService>()->sendDebugMessage(type, ctxt, buf); + QQmlDebugConnector::service<QDebugMessageServiceImpl>()->sendDebugMessage(type, ctxt, buf); } -QDebugMessageService::QDebugMessageService(QObject *parent) : - QQmlDebugService(s_key, 2, parent), oldMsgHandler(0), +QDebugMessageServiceImpl::QDebugMessageServiceImpl(QObject *parent) : + QDebugMessageService(2, parent), oldMsgHandler(0), prevState(QQmlDebugService::NotConnected) { // don't execute stateChanged() in parallel QMutexLocker lock(&initMutex); + timer.start(); if (state() == Enabled) { oldMsgHandler = qInstallMessageHandler(DebugMessageHandler); prevState = Enabled; } } -void QDebugMessageService::sendDebugMessage(QtMsgType type, +void QDebugMessageServiceImpl::sendDebugMessage(QtMsgType type, const QMessageLogContext &ctxt, const QString &buf) { //We do not want to alter the message handling mechanism //We just eavesdrop and forward the messages to a port //only if a client is connected to it. - QByteArray message; - QQmlDebugStream ws(&message, QIODevice::WriteOnly); + QQmlDebugPacket ws; ws << QByteArray("MESSAGE") << type << buf.toUtf8(); - ws << QString::fromLatin1(ctxt.file).toUtf8(); - ws << ctxt.line << QString::fromLatin1(ctxt.function).toUtf8(); + ws << QByteArray(ctxt.file) << ctxt.line << QByteArray(ctxt.function); + ws << QByteArray(ctxt.category) << timer.nsecsElapsed(); - emit messageToClient(name(), message); + emit messageToClient(name(), ws.data()); if (oldMsgHandler) (*oldMsgHandler)(type, ctxt, buf); } -void QDebugMessageService::stateChanged(State state) +void QDebugMessageServiceImpl::stateChanged(State state) { QMutexLocker lock(&initMutex); @@ -93,4 +90,10 @@ void QDebugMessageService::stateChanged(State state) prevState = state; } +void QDebugMessageServiceImpl::synchronizeTime(const QElapsedTimer &otherTimer) +{ + QMutexLocker lock(&initMutex); + timer = otherTimer; +} + QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h b/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h index c0dc41bcd0..a5ff1fc3d7 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.h @@ -45,36 +45,35 @@ // We mean it. // -#include <private/qqmldebugservice_p.h> +#include <private/qqmldebugserviceinterfaces_p.h> #include <QtCore/qlogging.h> #include <QtCore/qmutex.h> +#include <QtCore/qelapsedtimer.h> QT_BEGIN_NAMESPACE class QDebugMessageServicePrivate; -class QDebugMessageService : public QQmlDebugService +class QDebugMessageServiceImpl : public QDebugMessageService { Q_OBJECT public: - QDebugMessageService(QObject *parent = 0); + QDebugMessageServiceImpl(QObject *parent = 0); - void sendDebugMessage(QtMsgType type, const QMessageLogContext &ctxt, - const QString &buf); + void sendDebugMessage(QtMsgType type, const QMessageLogContext &ctxt, const QString &buf); + void synchronizeTime(const QElapsedTimer &otherTimer); protected: - static const QString s_key; - void stateChanged(State); private: - friend class QQmlDebugConnector; friend class QQmlDebuggerServiceFactory; QtMessageHandler oldMsgHandler; QQmlDebugService::State prevState; QMutex initMutex; + QElapsedTimer timer; }; QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro b/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro index 8d1a54e9e4..9db38d2dfe 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro +++ b/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro @@ -1,5 +1,5 @@ TARGET = qmldbg_debugger -QT = qml-private core-private +QT = qml-private core-private packetprotocol-private PLUGIN_TYPE = qmltooling PLUGIN_CLASS_NAME = QQmlDebuggerServiceFactory @@ -12,17 +12,21 @@ SOURCES += \ $$PWD/qqmlnativedebugservice.cpp \ $$PWD/qqmlwatcher.cpp \ $$PWD/qv4debugservice.cpp \ + $$PWD/qv4debugger.cpp \ $$PWD/qv4debuggeragent.cpp \ $$PWD/qv4datacollector.cpp + HEADERS += \ $$PWD/../shared/qqmlconfigurabledebugservice.h \ + $$PWD/../shared/qqmldebugpacket.h \ $$PWD/qdebugmessageservice.h \ $$PWD/qqmldebuggerservicefactory.h \ $$PWD/qqmlenginedebugservice.h \ $$PWD/qqmlnativedebugservice.h \ $$PWD/qqmlwatcher.h \ $$PWD/qv4debugservice.h \ + $$PWD/qv4debugger.h \ $$PWD/qv4debuggeragent.h \ $$PWD/qv4datacollector.h diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp index f379352cfa..4690da04d1 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmldebuggerservicefactory.cpp @@ -42,8 +42,8 @@ QT_BEGIN_NAMESPACE QQmlDebugService *QQmlDebuggerServiceFactory::create(const QString &key) { - if (key == QDebugMessageService::s_key) - return new QDebugMessageService(this); + if (key == QDebugMessageServiceImpl::s_key) + return new QDebugMessageServiceImpl(this); if (key == QQmlEngineDebugServiceImpl::s_key) return new QQmlEngineDebugServiceImpl(this); diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp index 8f53dc6d50..3775a2c1b4 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp @@ -33,6 +33,7 @@ #include "qqmlenginedebugservice.h" #include "qqmlwatcher.h" +#include "qqmldebugpacket.h" #include <private/qqmldebugstatesdelegate_p.h> #include <private/qqmlboundsignal_p.h> @@ -89,8 +90,7 @@ QDataStream &operator<<(QDataStream &ds, ds << (int)data.type << data.name; // check first whether the data can be saved // (otherwise we assert in QVariant::operator<<) - QByteArray buffer; - QDataStream fakeStream(&buffer, QIODevice::WriteOnly); + QQmlDebugPacket fakeStream; if (QMetaType::save(fakeStream, data.value.type(), data.value.constData())) ds << data.value; else @@ -440,21 +440,20 @@ QList<QObject*> QQmlEngineDebugServiceImpl::objectForLocationInfo(const QString void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message) { - QQmlDebugStream ds(message); + QQmlDebugPacket ds(message); QByteArray type; int queryId; ds >> type >> queryId; - QByteArray reply; - QQmlDebugStream rs(&reply, QIODevice::WriteOnly); + QQmlDebugPacket rs; if (type == "LIST_ENGINES") { rs << QByteArray("LIST_ENGINES_R"); rs << queryId << m_engines.count(); for (int ii = 0; ii < m_engines.count(); ++ii) { - QQmlEngine *engine = m_engines.at(ii); + QJSEngine *engine = m_engines.at(ii); QString engineName = engine->objectName(); int engineId = QQmlDebugService::idForObject(engine); @@ -617,7 +616,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message) rs << QByteArray("SET_METHOD_BODY_R") << queryId << ok; } - emit messageToClient(name(), reply); + emit messageToClient(name(), rs.data()); } bool QQmlEngineDebugServiceImpl::setBinding(int objectId, @@ -769,15 +768,12 @@ bool QQmlEngineDebugServiceImpl::setMethodBody(int objectId, const QString &meth void QQmlEngineDebugServiceImpl::propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value) { - QByteArray reply; - QQmlDebugStream rs(&reply, QIODevice::WriteOnly); - + QQmlDebugPacket rs; rs << QByteArray("UPDATE_WATCH") << id << objectId << QByteArray(property.name()) << valueContents(value); - - emit messageToClient(name(), reply); + emit messageToClient(name(), rs.data()); } -void QQmlEngineDebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) +void QQmlEngineDebugServiceImpl::engineAboutToBeAdded(QJSEngine *engine) { Q_ASSERT(engine); Q_ASSERT(!m_engines.contains(engine)); @@ -786,7 +782,7 @@ void QQmlEngineDebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) emit attachedToEngine(engine); } -void QQmlEngineDebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine) +void QQmlEngineDebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine) { Q_ASSERT(engine); Q_ASSERT(m_engines.contains(engine)); @@ -795,7 +791,7 @@ void QQmlEngineDebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine) emit detachedFromEngine(engine); } -void QQmlEngineDebugServiceImpl::objectCreated(QQmlEngine *engine, QObject *object) +void QQmlEngineDebugServiceImpl::objectCreated(QJSEngine *engine, QObject *object) { Q_ASSERT(engine); Q_ASSERT(m_engines.contains(engine)); @@ -804,12 +800,11 @@ void QQmlEngineDebugServiceImpl::objectCreated(QQmlEngine *engine, QObject *obje int objectId = QQmlDebugService::idForObject(object); int parentId = QQmlDebugService::idForObject(object->parent()); - QByteArray reply; - QQmlDebugStream rs(&reply, QIODevice::WriteOnly); + QQmlDebugPacket rs; //unique queryId -1 rs << QByteArray("OBJECT_CREATED") << -1 << engineId << objectId << parentId; - emit messageToClient(name(), reply); + emit messageToClient(name(), rs.data()); } void QQmlEngineDebugServiceImpl::setStatesDelegate(QQmlDebugStatesDelegate *delegate) diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h index 19a4827f89..a12aa495c3 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h @@ -89,9 +89,9 @@ public: bool hasNotifySignal; }; - void engineAboutToBeAdded(QQmlEngine *); - void engineAboutToBeRemoved(QQmlEngine *); - void objectCreated(QQmlEngine *, QObject *); + void engineAboutToBeAdded(QJSEngine *) Q_DECL_OVERRIDE; + void engineAboutToBeRemoved(QJSEngine *) Q_DECL_OVERRIDE; + void objectCreated(QJSEngine *, QObject *) Q_DECL_OVERRIDE; void setStatesDelegate(QQmlDebugStatesDelegate *); @@ -120,7 +120,7 @@ private: QList<QObject *> objectForLocationInfo(const QString &filename, int lineNumber, int columnNumber); - QList<QQmlEngine *> m_engines; + QList<QJSEngine *> m_engines; QQmlWatcher *m_watch; QQmlDebugStatesDelegate *m_statesDelegate; }; diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp index f5cc78e77f..a57ef56a84 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include "qqmlnativedebugservice.h" +#include "qqmldebugpacket.h" #include <private/qqmldebugconnector_p.h> #include <private/qv4debugging_p.h> @@ -46,8 +47,7 @@ #include <private/qv4isel_moth_p.h> #include <private/qqmldebugserviceinterfaces_p.h> -#include <qqmlengine.h> - +#include <QtQml/qjsengine.h> #include <QtCore/qjsonarray.h> #include <QtCore/qjsondocument.h> #include <QtCore/qjsonobject.h> @@ -313,16 +313,15 @@ void NativeDebugger::handleCommand(QJsonObject *response, const QString &cmd, static QString encodeContext(QV4::ExecutionContext *executionContext) { - QByteArray ba; - QDataStream ds(&ba, QIODevice::WriteOnly); + QQmlDebugPacket ds; ds << quintptr(executionContext); - return QString::fromLatin1(ba.toHex()); + return QString::fromLatin1(ds.data().toHex()); } static void decodeContext(const QString &context, QV4::ExecutionContext **executionContext) { quintptr rawContext; - QDataStream ds(QByteArray::fromHex(context.toLatin1())); + QQmlDebugPacket ds(QByteArray::fromHex(context.toLatin1())); ds >> rawContext; *executionContext = reinterpret_cast<QV4::ExecutionContext *>(rawContext); } @@ -724,7 +723,7 @@ QQmlNativeDebugServiceImpl::~QQmlNativeDebugServiceImpl() delete m_breakHandler; } -void QQmlNativeDebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) +void QQmlNativeDebugServiceImpl::engineAboutToBeAdded(QJSEngine *engine) { TRACE_PROTOCOL("Adding engine" << engine); if (engine) { @@ -741,7 +740,7 @@ void QQmlNativeDebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) QQmlDebugService::engineAboutToBeAdded(engine); } -void QQmlNativeDebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine) +void QQmlNativeDebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine) { TRACE_PROTOCOL("Removing engine" << engine); if (engine) { diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h index 9d0780a203..5ebf0a7f54 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlnativedebugservice.h @@ -68,14 +68,14 @@ class QQmlNativeDebugServiceImpl : public QQmlNativeDebugService public: QQmlNativeDebugServiceImpl(QObject *parent); - ~QQmlNativeDebugServiceImpl(); + ~QQmlNativeDebugServiceImpl() Q_DECL_OVERRIDE; - void engineAboutToBeAdded(QQmlEngine *engine); - void engineAboutToBeRemoved(QQmlEngine *engine); + void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE; + void engineAboutToBeRemoved(QJSEngine *engine) Q_DECL_OVERRIDE; - void stateAboutToBeChanged(State state); + void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE; - void messageReceived(const QByteArray &message); + void messageReceived(const QByteArray &message) Q_DECL_OVERRIDE; void emitAsynchronousMessageToClient(const QJsonObject &message); diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp index 4cca1900de..e3347be14c 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp @@ -40,6 +40,7 @@ #include <private/qv4runtime_p.h> #include <QtCore/qjsonarray.h> +#include <QtCore/qjsonobject.h> QT_BEGIN_NAMESPACE @@ -208,13 +209,13 @@ QV4DataCollector::Ref QV4DataCollector::addScriptRef(const QString &scriptName) return ref; } -void QV4DataCollector::collectScope(QJsonObject *dict, QV4::Debugging::V4Debugger *debugger, - int frameNr, int scopeNr) +void QV4DataCollector::collectScope(QJsonObject *dict, QV4Debugger *debugger, int frameNr, + int scopeNr) { QStringList names; Refs refs; - if (debugger->state() == QV4::Debugging::V4Debugger::Paused) { + if (debugger->state() == QV4Debugger::Paused) { RefHolder holder(this, &refs); ArgumentCollectJob argumentsJob(m_engine, this, &names, frameNr, scopeNr); debugger->runInEngine(&argumentsJob); @@ -344,24 +345,22 @@ const QString &ExpressionEvalJob::exceptionMessage() const return exception; } -GatherSourcesJob::GatherSourcesJob(QV4::ExecutionEngine *engine, int seq) +GatherSourcesJob::GatherSourcesJob(QV4::ExecutionEngine *engine) : engine(engine) - , seq(seq) {} void GatherSourcesJob::run() { - QStringList sources; - foreach (QV4::CompiledData::CompilationUnit *unit, engine->compilationUnits) { QString fileName = unit->fileName(); if (!fileName.isEmpty()) sources.append(fileName); } +} - QV4::Debugging::V4Debugger *debugger - = static_cast<QV4::Debugging::V4Debugger *>(engine->debugger); - emit debugger->sourcesCollected(debugger, sources, seq); +const QStringList &GatherSourcesJob::result() const +{ + return sources; } ArgumentCollectJob::ArgumentCollectJob(QV4::ExecutionEngine *engine, QV4DataCollector *collector, diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h index d0e4a4ad18..bfa3bd2fe1 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h @@ -34,8 +34,9 @@ #ifndef QV4DATACOLLECTOR_H #define QV4DATACOLLECTOR_H +#include "qv4debugger.h" #include <private/qv4engine_p.h> -#include <private/qv4debugging_p.h> +#include <private/qv4persistent_p.h> QT_BEGIN_NAMESPACE @@ -60,8 +61,7 @@ public: Ref addFunctionRef(const QString &functionName); Ref addScriptRef(const QString &scriptName); - void collectScope(QJsonObject *dict, QV4::Debugging::V4Debugger *debugger, int frameNr, - int scopeNr); + void collectScope(QJsonObject *dict, QV4Debugger *debugger, int frameNr, int scopeNr); QV4::ExecutionEngine *engine() const { return m_engine; } @@ -101,7 +101,7 @@ private: QV4DataCollector::Refs *m_previousRefs; }; -class ExpressionEvalJob: public QV4::Debugging::V4Debugger::JavaScriptJob +class ExpressionEvalJob: public QV4Debugger::JavaScriptJob { QV4DataCollector *collector; QString exception; @@ -113,17 +113,18 @@ public: const QString &exceptionMessage() const; }; -class GatherSourcesJob: public QV4::Debugging::V4Debugger::Job +class GatherSourcesJob: public QV4Debugger::Job { QV4::ExecutionEngine *engine; - const int seq; + QStringList sources; public: - GatherSourcesJob(QV4::ExecutionEngine *engine, int seq); + GatherSourcesJob(QV4::ExecutionEngine *engine); void run(); + const QStringList &result() const; }; -class ArgumentCollectJob: public QV4::Debugging::V4Debugger::Job +class ArgumentCollectJob: public QV4Debugger::Job { QV4::ExecutionEngine *engine; QV4DataCollector *collector; @@ -137,7 +138,7 @@ public: void run(); }; -class LocalCollectJob: public QV4::Debugging::V4Debugger::Job +class LocalCollectJob: public QV4Debugger::Job { QV4::ExecutionEngine *engine; QV4DataCollector *collector; @@ -151,7 +152,7 @@ public: void run(); }; -class ThisCollectJob: public QV4::Debugging::V4Debugger::Job +class ThisCollectJob: public QV4Debugger::Job { QV4::ExecutionEngine *engine; QV4DataCollector *collector; @@ -165,7 +166,7 @@ public: bool myRun(); }; -class ExceptionCollectJob: public QV4::Debugging::V4Debugger::Job +class ExceptionCollectJob: public QV4Debugger::Job { QV4::ExecutionEngine *engine; QV4DataCollector *collector; diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp new file mode 100644 index 0000000000..6198e2c039 --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp @@ -0,0 +1,358 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qv4debugger.h" + +#include <private/qv4scopedvalue_p.h> +#include <private/qv4script_p.h> + +QT_BEGIN_NAMESPACE + +QV4Debugger::BreakPoint::BreakPoint(const QString &fileName, int line) + : fileName(fileName), lineNumber(line) +{} + +inline uint qHash(const QV4Debugger::BreakPoint &b, uint seed = 0) Q_DECL_NOTHROW +{ + return qHash(b.fileName, seed) ^ b.lineNumber; +} + +inline bool operator==(const QV4Debugger::BreakPoint &a, + const QV4Debugger::BreakPoint &b) +{ + return a.lineNumber == b.lineNumber && a.fileName == b.fileName; +} + +QV4Debugger::JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, + const QString &script) + : engine(engine) + , frameNr(frameNr) + , script(script) + , resultIsException(false) +{} + +void QV4Debugger::JavaScriptJob::run() +{ + QV4::Scope scope(engine); + + QV4::ExecutionContextSaver saver(scope); + + QV4::ExecutionContext *ctx = engine->currentContext; + if (frameNr > 0) { + for (int i = 0; i < frameNr; ++i) { + ctx = engine->parentContext(ctx); + } + engine->pushContext(ctx); + } + + QV4::Script script(ctx, this->script); + script.strictMode = ctx->d()->strictMode; + // In order for property lookups in QML to work, we need to disable fast v4 lookups. That + // is a side-effect of inheritContext. + script.inheritContext = true; + script.parse(); + QV4::ScopedValue result(scope); + if (!scope.engine->hasException) + result = script.run(); + if (scope.engine->hasException) { + result = scope.engine->catchException(); + resultIsException = true; + } + handleResult(result); +} + +bool QV4Debugger::JavaScriptJob::hasExeption() const +{ + return resultIsException; +} + +class EvalJob: public QV4Debugger::JavaScriptJob +{ + bool result; + +public: + EvalJob(QV4::ExecutionEngine *engine, const QString &script) + : QV4Debugger::JavaScriptJob(engine, /*frameNr*/-1, script) + , result(false) + {} + + virtual void handleResult(QV4::ScopedValue &result) + { + this->result = result->toBoolean(); + } + + bool resultAsBoolean() const + { + return result; + } +}; + +QV4Debugger::QV4Debugger(QV4::ExecutionEngine *engine) + : m_engine(engine) + , m_state(Running) + , m_stepping(NotStepping) + , m_pauseRequested(false) + , m_haveBreakPoints(false) + , m_breakOnThrow(false) + , m_returnedValue(engine, QV4::Primitive::undefinedValue()) + , m_gatherSources(0) + , m_runningJob(0) +{ + static int debuggerId = qRegisterMetaType<QV4Debugger*>(); + static int pauseReasonId = qRegisterMetaType<QV4Debugger::PauseReason>(); + Q_UNUSED(debuggerId); + Q_UNUSED(pauseReasonId); +} + +QV4::ExecutionEngine *QV4Debugger::engine() const +{ + return m_engine; +} + +void QV4Debugger::pause() +{ + QMutexLocker locker(&m_lock); + if (m_state == Paused) + return; + m_pauseRequested = true; +} + +void QV4Debugger::resume(Speed speed) +{ + QMutexLocker locker(&m_lock); + if (m_state != Paused) + return; + + if (!m_returnedValue.isUndefined()) + m_returnedValue.set(m_engine, QV4::Encode::undefined()); + + m_currentContext.set(m_engine, *m_engine->currentContext); + m_stepping = speed; + m_runningCondition.wakeAll(); +} + +QV4Debugger::State QV4Debugger::state() const +{ + return m_state; +} + +void QV4Debugger::addBreakPoint(const QString &fileName, int lineNumber, const QString &condition) +{ + QMutexLocker locker(&m_lock); + m_breakPoints.insert(BreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), + lineNumber), condition); + m_haveBreakPoints = true; +} + +void QV4Debugger::removeBreakPoint(const QString &fileName, int lineNumber) +{ + QMutexLocker locker(&m_lock); + m_breakPoints.remove(BreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), + lineNumber)); + m_haveBreakPoints = !m_breakPoints.isEmpty(); +} + +void QV4Debugger::setBreakOnThrow(bool onoff) +{ + QMutexLocker locker(&m_lock); + + m_breakOnThrow = onoff; +} + +QV4Debugger::ExecutionState QV4Debugger::currentExecutionState() const +{ + ExecutionState state; + state.fileName = getFunction()->sourceFile(); + state.lineNumber = engine()->current->lineNumber; + + return state; +} + +bool QV4Debugger::pauseAtNextOpportunity() const { + return m_pauseRequested || m_haveBreakPoints || m_gatherSources || m_stepping >= StepOver; +} + +QVector<QV4::StackFrame> QV4Debugger::stackTrace(int frameLimit) const +{ + return m_engine->stackTrace(frameLimit); +} + +void QV4Debugger::maybeBreakAtInstruction() +{ + if (m_runningJob) // do not re-enter when we're doing a job for the debugger. + return; + + QMutexLocker locker(&m_lock); + + if (m_gatherSources) { + m_gatherSources->run(); + delete m_gatherSources; + m_gatherSources = 0; + } + + switch (m_stepping) { + case StepOver: + if (m_currentContext.asManaged()->d() != m_engine->current) + break; + // fall through + case StepIn: + pauseAndWait(Step); + return; + case StepOut: + case NotStepping: + break; + } + + if (m_pauseRequested) { // Serve debugging requests from the agent + m_pauseRequested = false; + pauseAndWait(PauseRequest); + } else if (m_haveBreakPoints) { + if (QV4::Function *f = getFunction()) { + const int lineNumber = engine()->current->lineNumber; + if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber)) + pauseAndWait(BreakPointHit); + } + } +} + +void QV4Debugger::enteringFunction() +{ + if (m_runningJob) + return; + QMutexLocker locker(&m_lock); + + if (m_stepping == StepIn) { + m_currentContext.set(m_engine, *m_engine->currentContext); + } +} + +void QV4Debugger::leavingFunction(const QV4::ReturnedValue &retVal) +{ + if (m_runningJob) + return; + Q_UNUSED(retVal); // TODO + + QMutexLocker locker(&m_lock); + + if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->current) { + m_currentContext.set(m_engine, *m_engine->parentContext(m_engine->currentContext)); + m_stepping = StepOver; + m_returnedValue.set(m_engine, retVal); + } +} + +void QV4Debugger::aboutToThrow() +{ + if (!m_breakOnThrow) + return; + + if (m_runningJob) // do not re-enter when we're doing a job for the debugger. + return; + + QMutexLocker locker(&m_lock); + pauseAndWait(Throwing); +} + +QV4::Function *QV4Debugger::getFunction() const +{ + QV4::Scope scope(m_engine); + QV4::ExecutionContext *context = m_engine->currentContext; + QV4::ScopedFunctionObject function(scope, context->getFunctionObject()); + if (function) + return function->function(); + else + return context->d()->engine->globalCode; +} + +void QV4Debugger::pauseAndWait(PauseReason reason) +{ + if (m_runningJob) + return; + + m_state = Paused; + emit debuggerPaused(this, reason); + + while (true) { + m_runningCondition.wait(&m_lock); + if (m_runningJob) { + m_runningJob->run(); + m_jobIsRunning.wakeAll(); + } else { + break; + } + } + + m_state = Running; +} + +bool QV4Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr) +{ + QHash<BreakPoint, QString>::iterator it = m_breakPoints.find( + BreakPoint(filename.mid(filename.lastIndexOf('/') + 1), linenr)); + if (it == m_breakPoints.end()) + return false; + QString condition = it.value(); + if (condition.isEmpty()) + return true; + + Q_ASSERT(m_runningJob == 0); + EvalJob evilJob(m_engine, condition); + m_runningJob = &evilJob; + m_runningJob->run(); + m_runningJob = 0; + + return evilJob.resultAsBoolean(); +} + +void QV4Debugger::runInEngine(QV4Debugger::Job *job) +{ + QMutexLocker locker(&m_lock); + runInEngine_havingLock(job); +} + +void QV4Debugger::runInEngine_havingLock(QV4Debugger::Job *job) +{ + Q_ASSERT(job); + Q_ASSERT(m_runningJob == 0); + + m_runningJob = job; + m_runningCondition.wakeAll(); + m_jobIsRunning.wait(&m_lock); + m_runningJob = 0; +} + +QV4Debugger::Job::~Job() +{ +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h new file mode 100644 index 0000000000..adc58141d0 --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QV4DEBUGGER_H +#define QV4DEBUGGER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qv4debugging_p.h> +#include <private/qv4function_p.h> +#include <private/qv4context_p.h> +#include <private/qv4persistent_p.h> + +#include <QtCore/qmutex.h> +#include <QtCore/qwaitcondition.h> + +QT_BEGIN_NAMESPACE + +class QV4Debugger : public QV4::Debugging::Debugger +{ + Q_OBJECT +public: + struct BreakPoint { + BreakPoint(const QString &fileName, int line); + QString fileName; + int lineNumber; + }; + + class Job + { + public: + virtual ~Job(); + virtual void run() = 0; + }; + + class JavaScriptJob: public Job + { + QV4::ExecutionEngine *engine; + int frameNr; + const QString &script; + bool resultIsException; + + public: + JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, const QString &script); + void run(); + bool hasExeption() const; + + protected: + virtual void handleResult(QV4::ScopedValue &result) = 0; + }; + + enum State { + Running, + Paused + }; + + enum Speed { + FullThrottle = 0, + StepOut, + StepOver, + StepIn, + + NotStepping = FullThrottle + }; + + enum PauseReason { + PauseRequest, + BreakPointHit, + Throwing, + Step + }; + + QV4Debugger(QV4::ExecutionEngine *engine); + + QV4::ExecutionEngine *engine() const; + + void pause(); + void resume(Speed speed); + + State state() const; + + void addBreakPoint(const QString &fileName, int lineNumber, + const QString &condition = QString()); + void removeBreakPoint(const QString &fileName, int lineNumber); + + void setBreakOnThrow(bool onoff); + + // used for testing + struct ExecutionState + { + QString fileName; + int lineNumber; + }; + ExecutionState currentExecutionState() const; + + QVector<QV4::StackFrame> stackTrace(int frameLimit = -1) const; + QVector<QV4::Heap::ExecutionContext::ContextType> getScopeTypes(int frame = 0) const; + + QV4::Function *getFunction() const; + void runInEngine(Job *job); + + // compile-time interface + void maybeBreakAtInstruction() Q_DECL_OVERRIDE; + + // execution hooks + void enteringFunction() Q_DECL_OVERRIDE; + void leavingFunction(const QV4::ReturnedValue &retVal) Q_DECL_OVERRIDE; + void aboutToThrow() Q_DECL_OVERRIDE; + + bool pauseAtNextOpportunity() const Q_DECL_OVERRIDE; + +signals: + void debuggerPaused(QV4Debugger *self, QV4Debugger::PauseReason reason); + +private: + // requires lock to be held + void pauseAndWait(PauseReason reason); + bool reallyHitTheBreakPoint(const QString &filename, int linenr); + void runInEngine_havingLock(QV4Debugger::Job *job); + + QV4::ExecutionEngine *m_engine; + QV4::PersistentValue m_currentContext; + QMutex m_lock; + QWaitCondition m_runningCondition; + State m_state; + Speed m_stepping; + bool m_pauseRequested; + bool m_haveBreakPoints; + bool m_breakOnThrow; + + QHash<BreakPoint, QString> m_breakPoints; + QV4::PersistentValue m_returnedValue; + + Job *m_gatherSources; + Job *m_runningJob; + QWaitCondition m_jobIsRunning; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QV4Debugger::PauseReason) +Q_DECLARE_METATYPE(QV4Debugger*) + +#endif // QV4DEBUGGER_H diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp index e33595c629..da43257b24 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp @@ -44,7 +44,7 @@ QV4DebuggerAgent::QV4DebuggerAgent(QV4DebugServiceImpl *debugService) : m_breakOnThrow(false), m_debugService(debugService) {} -QV4::Debugging::V4Debugger *QV4DebuggerAgent::firstDebugger() const +QV4Debugger *QV4DebuggerAgent::firstDebugger() const { // Currently only 1 single engine is supported, so: if (m_debuggers.isEmpty()) @@ -56,14 +56,13 @@ QV4::Debugging::V4Debugger *QV4DebuggerAgent::firstDebugger() const bool QV4DebuggerAgent::isRunning() const { // Currently only 1 single engine is supported, so: - if (QV4::Debugging::V4Debugger *debugger = firstDebugger()) - return debugger->state() == QV4::Debugging::V4Debugger::Running; + if (QV4Debugger *debugger = firstDebugger()) + return debugger->state() == QV4Debugger::Running; else return false; } -void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::V4Debugger *debugger, - QV4::Debugging::PauseReason reason) +void QV4DebuggerAgent::debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason) { Q_UNUSED(reason); @@ -73,9 +72,9 @@ void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::V4Debugger *debugger, event.insert(QStringLiteral("type"), QStringLiteral("event")); switch (reason) { - case QV4::Debugging::Step: - case QV4::Debugging::PauseRequest: - case QV4::Debugging::BreakPoint: { + case QV4Debugger::Step: + case QV4Debugger::PauseRequest: + case QV4Debugger::BreakPointHit: { event.insert(QStringLiteral("event"), QStringLiteral("break")); QVector<QV4::StackFrame> frames = debugger->stackTrace(1); if (frames.isEmpty()) @@ -92,7 +91,7 @@ void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::V4Debugger *debugger, body.insert(QStringLiteral("breakpoints"), breakPoints); script.insert(QStringLiteral("name"), topFrame.source); } break; - case QV4::Debugging::Throwing: + case QV4Debugger::Throwing: // TODO: complete this! event.insert(QStringLiteral("event"), QStringLiteral("exception")); break; @@ -105,28 +104,7 @@ void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::V4Debugger *debugger, m_debugService->send(event); } -void QV4DebuggerAgent::sourcesCollected(QV4::Debugging::V4Debugger *debugger, - const QStringList &sources, int requestSequenceNr) -{ - QJsonArray body; - foreach (const QString &source, sources) { - QJsonObject src; - src[QLatin1String("name")] = source; - src[QLatin1String("scriptType")] = 4; - body.append(src); - } - - QJsonObject response; - response[QLatin1String("success")] = true; - response[QLatin1String("running")] = debugger->state() == QV4::Debugging::V4Debugger::Running; - response[QLatin1String("body")] = body; - response[QLatin1String("command")] = QStringLiteral("scripts"); - response[QLatin1String("request_seq")] = requestSequenceNr; - response[QLatin1String("type")] = QStringLiteral("response"); - m_debugService->send(response); -} - -void QV4DebuggerAgent::addDebugger(QV4::Debugging::V4Debugger *debugger) +void QV4DebuggerAgent::addDebugger(QV4Debugger *debugger) { Q_ASSERT(!m_debuggers.contains(debugger)); m_debuggers << debugger; @@ -137,57 +115,50 @@ void QV4DebuggerAgent::addDebugger(QV4::Debugging::V4Debugger *debugger) if (breakPoint.enabled) debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition); - connect(debugger, SIGNAL(destroyed(QObject*)), - this, SLOT(handleDebuggerDeleted(QObject*))); - connect(debugger, SIGNAL(sourcesCollected(QV4::Debugging::V4Debugger*,QStringList,int)), - this, SLOT(sourcesCollected(QV4::Debugging::V4Debugger*,QStringList,int)), - Qt::QueuedConnection); - connect(debugger, - SIGNAL(debuggerPaused(QV4::Debugging::V4Debugger*,QV4::Debugging::PauseReason)), - this, SLOT(debuggerPaused(QV4::Debugging::V4Debugger*,QV4::Debugging::PauseReason)), + connect(debugger, &QObject::destroyed, this, &QV4DebuggerAgent::handleDebuggerDeleted); + connect(debugger, &QV4Debugger::debuggerPaused, this, &QV4DebuggerAgent::debuggerPaused, Qt::QueuedConnection); } -void QV4DebuggerAgent::removeDebugger(QV4::Debugging::V4Debugger *debugger) +void QV4DebuggerAgent::removeDebugger(QV4Debugger *debugger) { m_debuggers.removeAll(debugger); - disconnect(debugger, SIGNAL(destroyed(QObject*)), - this, SLOT(handleDebuggerDeleted(QObject*))); - disconnect(debugger, SIGNAL(sourcesCollected(QV4::Debugging::V4Debugger*,QStringList,int)), - this, SLOT(sourcesCollected(QV4::Debugging::V4Debugger*,QStringList,int))); - disconnect(debugger, - SIGNAL(debuggerPaused(QV4::Debugging::V4Debugger*,QV4::Debugging::PauseReason)), - this, - SLOT(debuggerPaused(QV4::Debugging::V4Debugger*,QV4::Debugging::PauseReason))); + disconnect(debugger, &QObject::destroyed, this, &QV4DebuggerAgent::handleDebuggerDeleted); + disconnect(debugger, &QV4Debugger::debuggerPaused, this, &QV4DebuggerAgent::debuggerPaused); +} + +const QList<QV4Debugger *> &QV4DebuggerAgent::debuggers() +{ + return m_debuggers; } void QV4DebuggerAgent::handleDebuggerDeleted(QObject *debugger) { - m_debuggers.removeAll(static_cast<QV4::Debugging::V4Debugger *>(debugger)); + m_debuggers.removeAll(static_cast<QV4Debugger *>(debugger)); } -void QV4DebuggerAgent::pause(QV4::Debugging::V4Debugger *debugger) const +void QV4DebuggerAgent::pause(QV4Debugger *debugger) const { debugger->pause(); } void QV4DebuggerAgent::pauseAll() const { - foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers) + foreach (QV4Debugger *debugger, m_debuggers) pause(debugger); } void QV4DebuggerAgent::resumeAll() const { - foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers) - if (debugger->state() == QV4::Debugging::V4Debugger::Paused) - debugger->resume(QV4::Debugging::V4Debugger::FullThrottle); + foreach (QV4Debugger *debugger, m_debuggers) + if (debugger->state() == QV4Debugger::Paused) + debugger->resume(QV4Debugger::FullThrottle); } int QV4DebuggerAgent::addBreakPoint(const QString &fileName, int lineNumber, bool enabled, const QString &condition) { if (enabled) - foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers) + foreach (QV4Debugger *debugger, m_debuggers) debugger->addBreakPoint(fileName, lineNumber, condition); int id = m_breakPoints.size(); @@ -204,7 +175,7 @@ void QV4DebuggerAgent::removeBreakPoint(int id) m_breakPoints.remove(id); if (breakPoint.enabled) - foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers) + foreach (QV4Debugger *debugger, m_debuggers) debugger->removeBreakPoint(breakPoint.fileName, breakPoint.lineNr); } @@ -222,7 +193,7 @@ void QV4DebuggerAgent::enableBreakPoint(int id, bool onoff) return; breakPoint.enabled = onoff; - foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers) { + foreach (QV4Debugger *debugger, m_debuggers) { if (onoff) debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition); else @@ -245,7 +216,7 @@ void QV4DebuggerAgent::setBreakOnThrow(bool onoff) { if (onoff != m_breakOnThrow) { m_breakOnThrow = onoff; - foreach (QV4::Debugging::V4Debugger *debugger, m_debuggers) + foreach (QV4Debugger *debugger, m_debuggers) debugger->setBreakOnThrow(onoff); } } diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h index eafb408e7a..d133c6954b 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h @@ -34,7 +34,7 @@ #ifndef QV4DEBUGGERAGENT_H #define QV4DEBUGGERAGENT_H -#include <private/qv4debugging_p.h> +#include "qv4debugger.h" QT_BEGIN_NAMESPACE @@ -46,13 +46,14 @@ class QV4DebuggerAgent : public QObject public: QV4DebuggerAgent(QV4DebugServiceImpl *m_debugService); - QV4::Debugging::V4Debugger *firstDebugger() const; + QV4Debugger *firstDebugger() const; bool isRunning() const; - void addDebugger(QV4::Debugging::V4Debugger *debugger); - void removeDebugger(QV4::Debugging::V4Debugger *debugger); + void addDebugger(QV4Debugger *debugger); + void removeDebugger(QV4Debugger *debugger); + const QList<QV4Debugger *> &debuggers(); - void pause(QV4::Debugging::V4Debugger *debugger) const; + void pause(QV4Debugger *debugger) const; void pauseAll() const; void resumeAll() const; int addBreakPoint(const QString &fileName, int lineNumber, bool enabled = true, const QString &condition = QString()); @@ -65,13 +66,11 @@ public: void setBreakOnThrow(bool onoff); public slots: - void debuggerPaused(QV4::Debugging::V4Debugger *debugger, QV4::Debugging::PauseReason reason); - void sourcesCollected(QV4::Debugging::V4Debugger *debugger, const QStringList &sources, - int requestSequenceNr); + void debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason); void handleDebuggerDeleted(QObject *debugger); private: - QList<QV4::Debugging::V4Debugger *> m_debuggers; + QList<QV4Debugger *> m_debuggers; struct BreakPoint { QString fileName; diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp index 5233a09992..dbfbcb25bb 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp @@ -33,11 +33,12 @@ #include "qv4debugservice.h" #include "qqmlengine.h" +#include "qqmldebugpacket.h" + #include <private/qv4engine_p.h> #include <private/qv4isel_moth_p.h> #include <private/qv4function_p.h> #include <private/qqmldebugconnector_p.h> - #include <private/qv8engine_p.h> #include <QtCore/QJsonArray> @@ -63,7 +64,6 @@ QT_BEGIN_NAMESPACE class V8CommandHandler; class UnknownV8CommandHandler; -int QV4DebugServiceImpl::debuggerIndex = 0; int QV4DebugServiceImpl::sequence = 0; class V8CommandHandler @@ -104,7 +104,7 @@ protected: void addCommand() { response.insert(QStringLiteral("command"), cmd); } void addRequestSequence() { response.insert(QStringLiteral("request_seq"), seq); } void addSuccess(bool success) { response.insert(QStringLiteral("success"), success); } - void addBody(const QJsonObject &body) + void addBody(const QJsonValue &body) { response.insert(QStringLiteral("body"), body); } @@ -271,7 +271,7 @@ public: int toFrame = arguments.value(QStringLiteral("toFrame")).toInt(fromFrame + 10); // no idea what the bottom property is for, so we'll ignore it. - QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); + QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); QJsonArray frameArray; QVector<QV4::StackFrame> frames = debugger->stackTrace(toFrame); @@ -308,7 +308,7 @@ public: const int frameNr = arguments.value(QStringLiteral("number")).toInt( debugService->selectedFrame()); - QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); + QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1); if (frameNr < 0 || frameNr >= frames.size()) { createErrorResponse(QStringLiteral("frame command has invalid frame number")); @@ -341,7 +341,7 @@ public: debugService->selectedFrame()); const int scopeNr = arguments.value(QStringLiteral("number")).toInt(0); - QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); + QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1); if (frameNr < 0 || frameNr >= frames.size()) { createErrorResponse(QStringLiteral("scope command has invalid frame number")); @@ -399,10 +399,10 @@ public: // decypher the payload: QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject(); - QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); + QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); if (arguments.empty()) { - debugger->resume(QV4::Debugging::V4Debugger::FullThrottle); + debugger->resume(QV4Debugger::FullThrottle); } else { QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject(); QString stepAction = arguments.value(QStringLiteral("stepaction")).toString(); @@ -411,11 +411,11 @@ public: qWarning() << "Step count other than 1 is not supported."; if (stepAction == QStringLiteral("in")) { - debugger->resume(QV4::Debugging::V4Debugger::StepIn); + debugger->resume(QV4Debugger::StepIn); } else if (stepAction == QStringLiteral("out")) { - debugger->resume(QV4::Debugging::V4Debugger::StepOut); + debugger->resume(QV4Debugger::StepOut); } else if (stepAction == QStringLiteral("next")) { - debugger->resume(QV4::Debugging::V4Debugger::StepOver); + debugger->resume(QV4Debugger::StepOver); } else { createErrorResponse(QStringLiteral("continue command has invalid stepaction")); return; @@ -507,11 +507,23 @@ public: } // do it: - QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); - GatherSourcesJob job(debugger->engine(), requestSequenceNr()); + QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); + GatherSourcesJob job(debugger->engine()); debugger->runInEngine(&job); - // response will be send by + QJsonArray body; + foreach (const QString &source, job.result()) { + QJsonObject src; + src[QLatin1String("name")] = source; + src[QLatin1String("scriptType")] = 4; + body.append(src); + } + + addSuccess(true); + addRunning(); + addBody(body); + addCommand(); + addRequestSequence(); } }; @@ -550,8 +562,8 @@ public: virtual void handleRequest() { - QV4::Debugging::V4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); - if (debugger->state() == QV4::Debugging::V4Debugger::Paused) { + QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger(); + if (debugger->state() == QV4Debugger::Paused) { QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject(); QString expression = arguments.value(QStringLiteral("expression")).toString(); const int frame = arguments.value(QStringLiteral("frame")).toInt(0); @@ -593,7 +605,7 @@ V8CommandHandler *QV4DebugServiceImpl::v8CommandHandler(const QString &command) QV4DebugServiceImpl::QV4DebugServiceImpl(QObject *parent) : QQmlConfigurableDebugService<QV4DebugService>(1, parent), - debuggerAgent(this), version(1), theSelectedFrame(0), + debuggerAgent(this), theSelectedFrame(0), unknownV8CommandHandler(new UnknownV8CommandHandler) { addHandler(new V8VersionRequest); @@ -615,7 +627,7 @@ QV4DebugServiceImpl::~QV4DebugServiceImpl() qDeleteAll(handlers); } -void QV4DebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) +void QV4DebugServiceImpl::engineAboutToBeAdded(QJSEngine *engine) { QMutexLocker lock(&m_configMutex); if (engine) { @@ -623,10 +635,9 @@ void QV4DebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) if (QQmlDebugConnector *server = QQmlDebugConnector::instance()) { if (ee) { ee->iselFactory.reset(new QV4::Moth::ISelFactory); - QV4::Debugging::V4Debugger *debugger = new QV4::Debugging::V4Debugger(ee); + QV4Debugger *debugger = new QV4Debugger(ee); if (state() == Enabled) ee->setDebugger(debugger); - debuggerMap.insert(debuggerIndex++, debugger); debuggerAgent.addDebugger(debugger); debuggerAgent.moveToThread(server->thread()); } @@ -635,25 +646,15 @@ void QV4DebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) QQmlConfigurableDebugService<QV4DebugService>::engineAboutToBeAdded(engine); } -void QV4DebugServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine) +void QV4DebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine) { QMutexLocker lock(&m_configMutex); if (engine){ const QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle()); if (ee) { - QV4::Debugging::V4Debugger *debugger - = qobject_cast<QV4::Debugging::V4Debugger *>(ee->debugger); - if (debugger) { - typedef QMap<int, QV4::Debugging::V4Debugger *>::const_iterator DebuggerMapIterator; - const DebuggerMapIterator end = debuggerMap.constEnd(); - for (DebuggerMapIterator i = debuggerMap.constBegin(); i != end; ++i) { - if (i.value() == debugger) { - debuggerMap.remove(i.key()); - break; - } - } + QV4Debugger *debugger = qobject_cast<QV4Debugger *>(ee->debugger); + if (debugger) debuggerAgent.removeDebugger(debugger); - } } } QQmlConfigurableDebugService<QV4DebugService>::engineAboutToBeRemoved(engine); @@ -663,12 +664,10 @@ void QV4DebugServiceImpl::stateAboutToBeChanged(State state) { QMutexLocker lock(&m_configMutex); if (state == Enabled) { - typedef QMap<int, QV4::Debugging::V4Debugger *>::const_iterator DebuggerMapIterator; - const DebuggerMapIterator end = debuggerMap.constEnd(); - for (DebuggerMapIterator i = debuggerMap.constBegin(); i != end; ++i) { - QV4::ExecutionEngine *ee = i.value()->engine(); + foreach (QV4Debugger *debugger, debuggerAgent.debuggers()) { + QV4::ExecutionEngine *ee = debugger->engine(); if (!ee->debugger) - ee->setDebugger(i.value()); + ee->setDebugger(debugger); } } QQmlConfigurableDebugService<QV4DebugService>::stateAboutToBeChanged(state); @@ -696,7 +695,7 @@ void QV4DebugServiceImpl::messageReceived(const QByteArray &message) { QMutexLocker lock(&m_configMutex); - QQmlDebugStream ms(message); + QQmlDebugPacket ms(message); QByteArray header; ms >> header; @@ -737,11 +736,10 @@ void QV4DebugServiceImpl::messageReceived(const QByteArray &message) void QV4DebugServiceImpl::sendSomethingToSomebody(const char *type, int magicNumber) { - QByteArray response; - QQmlDebugStream rs(&response, QIODevice::WriteOnly); + QQmlDebugPacket rs; rs << QByteArray(type) - << QByteArray::number(version) << QByteArray::number(magicNumber); - emit messageToClient(name(), packMessage(type, response)); + << QByteArray::number(int(version())) << QByteArray::number(magicNumber); + emit messageToClient(name(), packMessage(type, rs.data())); } void QV4DebugServiceImpl::handleV8Request(const QByteArray &payload) @@ -761,11 +759,10 @@ void QV4DebugServiceImpl::handleV8Request(const QByteArray &payload) QByteArray QV4DebugServiceImpl::packMessage(const QByteArray &command, const QByteArray &message) { - QByteArray reply; - QQmlDebugStream rs(&reply, QIODevice::WriteOnly); + QQmlDebugPacket rs; static const QByteArray cmd("V8DEBUG"); rs << cmd << command << message; - return reply; + return rs.data(); } void QV4DebugServiceImpl::send(QJsonObject v8Payload) @@ -790,7 +787,7 @@ void QV4DebugServiceImpl::clearHandles(QV4::ExecutionEngine *engine) } QJsonObject QV4DebugServiceImpl::buildFrame(const QV4::StackFrame &stackFrame, int frameNr, - QV4::Debugging::V4Debugger *debugger) + QV4Debugger *debugger) { QV4DataCollector::Ref ref; @@ -808,7 +805,7 @@ QJsonObject QV4DebugServiceImpl::buildFrame(const QV4::StackFrame &stackFrame, i frame[QLatin1String("column")] = stackFrame.column; QJsonArray scopes; - if (debugger->state() == QV4::Debugging::V4Debugger::Paused) { + if (debugger->state() == QV4Debugger::Paused) { RefHolder holder(theCollector.data(), &collectedRefs); bool foundThis = false; ThisCollectJob job(debugger->engine(), theCollector.data(), frameNr, &foundThis); @@ -857,8 +854,7 @@ int QV4DebugServiceImpl::encodeScopeType(QV4::Heap::ExecutionContext::ContextTyp } } -QJsonObject QV4DebugServiceImpl::buildScope(int frameNr, int scopeNr, - QV4::Debugging::V4Debugger *debugger) +QJsonObject QV4DebugServiceImpl::buildScope(int frameNr, int scopeNr, QV4Debugger *debugger) { QJsonObject scope; @@ -866,7 +862,7 @@ QJsonObject QV4DebugServiceImpl::buildScope(int frameNr, int scopeNr, RefHolder holder(theCollector.data(), &collectedRefs); theCollector->collectScope(&object, debugger, frameNr, scopeNr); - if (debugger->state() == QV4::Debugging::V4Debugger::Paused) { + if (debugger->state() == QV4Debugger::Paused) { QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes = QV4DataCollector::getScopeTypes(debugger->engine(), frameNr); scope[QLatin1String("type")] = encodeScopeType(scopeTypes[scopeNr]); diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h index 273e5ffd62..5e6f466ecf 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h @@ -57,7 +57,6 @@ QT_BEGIN_NAMESPACE namespace QV4 { struct ExecutionEngine; } -class QQmlEngine; class VariableCollector; class V8CommandHandler; class UnknownV8CommandHandler; @@ -68,23 +67,22 @@ class QV4DebugServiceImpl : public QQmlConfigurableDebugService<QV4DebugService> Q_OBJECT public: explicit QV4DebugServiceImpl(QObject *parent = 0); - ~QV4DebugServiceImpl(); + ~QV4DebugServiceImpl() Q_DECL_OVERRIDE; - void engineAboutToBeAdded(QQmlEngine *engine); - void engineAboutToBeRemoved(QQmlEngine *engine); + void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE; + void engineAboutToBeRemoved(QJSEngine *engine) Q_DECL_OVERRIDE; - void stateAboutToBeChanged(State state); + void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE; - void signalEmitted(const QString &signal); + void signalEmitted(const QString &signal) Q_DECL_OVERRIDE; void send(QJsonObject v8Payload); - QJsonObject buildScope(int frameNr, int scopeNr, QV4::Debugging::V4Debugger *debugger); + QJsonObject buildScope(int frameNr, int scopeNr, QV4Debugger *debugger); QJsonArray buildRefs(); QJsonValue lookup(QV4DataCollector::Ref refId); QJsonValue toRef(QV4DataCollector::Ref ref); - QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr, - QV4::Debugging::V4Debugger *debugger); + QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr, QV4Debugger *debugger); int selectedFrame() const; void selectFrame(int frameNr); @@ -95,7 +93,7 @@ public: QV4DataCollector::Refs *refs(); protected: - void messageReceived(const QByteArray &); + void messageReceived(const QByteArray &) Q_DECL_OVERRIDE; void sendSomethingToSomebody(const char *type, int magicNumber = 1); private: @@ -109,10 +107,7 @@ private: int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType); QStringList breakOnSignals; - QMap<int, QV4::Debugging::V4Debugger *> debuggerMap; - static int debuggerIndex; static int sequence; - const int version; QV4DataCollector::Refs collectedRefs; QScopedPointer<QV4DataCollector> theCollector; diff --git a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp index fa6dca7aca..daf620805f 100644 --- a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp +++ b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp @@ -33,6 +33,7 @@ #include "abstractviewinspector.h" #include "abstracttool.h" +#include "qqmldebugpacket.h" #include <QtCore/QDebug> #include <QtQml/QQmlEngine> @@ -262,18 +263,16 @@ void AbstractViewInspector::onQmlObjectDestroyed(QObject *object) QPair<int, int> ids = m_hashObjectsTobeDestroyed.take(object); - QByteArray response; - - QQmlDebugStream rs(&response, QIODevice::WriteOnly); + QQmlDebugPacket rs; rs << QByteArray(RESPONSE) << ids.first << true << ids.second; - emit m_debugService->messageToClient(m_debugService->name(), response); + emit m_debugService->messageToClient(m_debugService->name(), rs.data()); } void AbstractViewInspector::handleMessage(const QByteArray &message) { bool success = true; - QQmlDebugStream ds(message); + QQmlDebugPacket ds(message); QByteArray type; ds >> type; @@ -358,16 +357,14 @@ void AbstractViewInspector::handleMessage(const QByteArray &message) } - QByteArray response; - QQmlDebugStream rs(&response, QIODevice::WriteOnly); + QQmlDebugPacket rs; rs << QByteArray(RESPONSE) << requestId << success; - emit m_debugService->messageToClient(m_debugService->name(), response); + emit m_debugService->messageToClient(m_debugService->name(), rs.data()); } void AbstractViewInspector::sendCurrentObjects(const QList<QObject*> &objects) { - QByteArray message; - QQmlDebugStream ds(&message, QIODevice::WriteOnly); + QQmlDebugPacket ds; ds << QByteArray(EVENT) << m_eventId++ << QByteArray(SELECT); @@ -377,7 +374,7 @@ void AbstractViewInspector::sendCurrentObjects(const QList<QObject*> &objects) debugIds << QQmlDebugService::idForObject(object); ds << debugIds; - emit m_debugService->messageToClient(m_debugService->name(), message); + emit m_debugService->messageToClient(m_debugService->name(), ds.data()); } void AbstractViewInspector::sendQmlFileReloaded(bool success) @@ -387,10 +384,10 @@ void AbstractViewInspector::sendQmlFileReloaded(bool success) QByteArray response; - QQmlDebugStream rs(&response, QIODevice::WriteOnly); + QQmlDebugPacket rs; rs << QByteArray(RESPONSE) << m_reloadEventId << success; - emit m_debugService->messageToClient(m_debugService->name(), response); + emit m_debugService->messageToClient(m_debugService->name(), rs.data()); } QString AbstractViewInspector::idStringForObject(QObject *obj) const diff --git a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro index 1c3e5f387b..dd5cc8ceef 100644 --- a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro +++ b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro @@ -1,5 +1,5 @@ TARGET = qmldbg_inspector -QT += qml-private quick-private core-private gui-private +QT += qml-private quick-private core-private gui-private packetprotocol-private PLUGIN_TYPE = qmltooling PLUGIN_CLASS_NAME = QQmlInspectorServiceFactory @@ -16,6 +16,7 @@ SOURCES += \ $$PWD/qqmlinspectorservice.cpp HEADERS += \ + $$PWD/../shared/qqmldebugpacket.h \ $$PWD/highlight.h \ $$PWD/qquickviewinspector.h \ $$PWD/qqmlinspectorservicefactory.h \ diff --git a/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp b/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp index 1707091df3..6b786024f8 100644 --- a/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp +++ b/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp @@ -50,12 +50,12 @@ class QQmlInspectorServiceImpl : public QQmlInspectorService public: QQmlInspectorServiceImpl(QObject *parent = 0); - void addView(QObject *); - void removeView(QObject *); + void addView(QObject *) Q_DECL_OVERRIDE; + void removeView(QObject *) Q_DECL_OVERRIDE; protected: - virtual void stateChanged(State state); - virtual void messageReceived(const QByteArray &); + virtual void stateChanged(State state) Q_DECL_OVERRIDE; + virtual void messageReceived(const QByteArray &) Q_DECL_OVERRIDE; private Q_SLOTS: void processMessage(const QByteArray &message); diff --git a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp index 057bf9523e..478cbf5514 100644 --- a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp +++ b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp @@ -32,7 +32,6 @@ ****************************************************************************/ #include "qlocalclientconnectionfactory.h" -#include "qpacketprotocol.h" #include "qqmldebugserver.h" #include <QtCore/qplugin.h> diff --git a/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro b/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro index 7dc16b8c44..d490d77e50 100644 --- a/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro +++ b/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro @@ -1,12 +1,19 @@ TARGET = qmldbg_native -QT += qml-private core-private +QT += qml-private core-private packetprotocol-private PLUGIN_TYPE = qmltooling PLUGIN_CLASS_NAME = QQmlNativeDebugConnectorFactory load(qt_plugin) +HEADERS += \ + $$PWD/../shared/qqmldebugpacket.h \ + $$PWD/qqmlnativedebugconnector.h + SOURCES += \ $$PWD/qqmlnativedebugconnector.cpp +INCLUDEPATH += $$PWD \ + $$PWD/../shared + OTHER_FILES += \ $$PWD/qqmlnativedebugconnector.json diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp index 6621eafb27..e4054e100d 100644 --- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp +++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp @@ -31,18 +31,18 @@ ** ****************************************************************************/ -#include <private/qqmldebugconnector_p.h> -#include <private/qhooks_p.h> +#include "qqmlnativedebugconnector.h" +#include "qqmldebugpacket.h" -#include <qqmlengine.h> +#include <private/qhooks_p.h> +#include <QtQml/qjsengine.h> #include <QtCore/qdebug.h> #include <QtCore/qjsonarray.h> #include <QtCore/qjsondocument.h> #include <QtCore/qjsonobject.h> #include <QtCore/qjsonvalue.h> #include <QtCore/qpointer.h> -#include <QtCore/qvector.h> //#define TRACE_PROTOCOL(s) qDebug() << s #define TRACE_PROTOCOL(s) @@ -65,7 +65,7 @@ Q_DECL_EXPORT void qt_qmlDebugConnectorOpen(); // member to some other place. Q_DECL_EXPORT void qt_qmlDebugSetStreamVersion(int version) { - QQmlDebugStream::s_dataStreamVersion = version; + QQmlNativeDebugConnector::setDataStreamVersion(version); } @@ -172,33 +172,6 @@ Q_DECL_EXPORT void qt_qmlDebugConnectorOpen() QT_BEGIN_NAMESPACE -class QQmlNativeDebugConnector : public QQmlDebugConnector -{ - Q_OBJECT - -public: - QQmlNativeDebugConnector(); - ~QQmlNativeDebugConnector(); - - bool blockingMode() const; - QQmlDebugService *service(const QString &name) const; - void addEngine(QQmlEngine *engine); - void removeEngine(QQmlEngine *engine); - bool addService(const QString &name, QQmlDebugService *service); - bool removeService(const QString &name); - bool open(const QVariantHash &configuration); - -private slots: - void sendMessage(const QString &name, const QByteArray &message); - void sendMessages(const QString &name, const QList<QByteArray> &messages); - -private: - void announceObjectAvailability(const QString &objectType, QObject *object, bool available); - - QVector<QQmlDebugService *> m_services; - bool m_blockingMode; -}; - QQmlNativeDebugConnector::QQmlNativeDebugConnector() : m_blockingMode(false) { @@ -250,7 +223,7 @@ QQmlDebugService *QQmlNativeDebugConnector::service(const QString &name) const return 0; } -void QQmlNativeDebugConnector::addEngine(QQmlEngine *engine) +void QQmlNativeDebugConnector::addEngine(QJSEngine *engine) { TRACE_PROTOCOL("Add engine to connector:" << engine); foreach (QQmlDebugService *service, m_services) @@ -262,7 +235,7 @@ void QQmlNativeDebugConnector::addEngine(QQmlEngine *engine) service->engineAdded(engine); } -void QQmlNativeDebugConnector::removeEngine(QQmlEngine *engine) +void QQmlNativeDebugConnector::removeEngine(QJSEngine *engine) { TRACE_PROTOCOL("Remove engine from connector:" << engine); foreach (QQmlDebugService *service, m_services) @@ -338,6 +311,12 @@ bool QQmlNativeDebugConnector::open(const QVariantHash &configuration) return true; } +void QQmlNativeDebugConnector::setDataStreamVersion(int version) +{ + Q_ASSERT(version <= QDataStream::Qt_DefaultCompiledVersion); + s_dataStreamVersion = version; +} + void QQmlNativeDebugConnector::sendMessage(const QString &name, const QByteArray &message) { (*responseBuffer) += name.toUtf8() + ' ' + QByteArray::number(message.size()) + ' ' + message; @@ -363,21 +342,9 @@ void QQmlNativeDebugConnector::sendMessages(const QString &name, const QList<QBy sendMessage(name, messages.at(i)); } -class QQmlNativeDebugConnectorFactory : public QQmlDebugConnectorFactory +QQmlDebugConnector *QQmlNativeDebugConnectorFactory::create(const QString &key) { - Q_OBJECT - - Q_PLUGIN_METADATA(IID QQmlDebugConnectorFactory_iid FILE "qqmlnativedebugconnector.json") - -public: - QQmlNativeDebugConnectorFactory() {} - - QQmlDebugConnector *create(const QString &key) - { - return key == QLatin1String("QQmlNativeDebugConnector") ? new QQmlNativeDebugConnector : 0; - } -}; + return key == QLatin1String("QQmlNativeDebugConnector") ? new QQmlNativeDebugConnector : 0; +} QT_END_NAMESPACE - -#include "qqmlnativedebugconnector.moc" diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h new file mode 100644 index 0000000000..a883608fd4 --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLNATIVEDEBUGCONNECTOR_H +#define QQMLNATIVEDEBUGCONNECTOR_H + +#include <private/qqmldebugconnector_p.h> +#include <QtCore/qvector.h> + +QT_BEGIN_NAMESPACE + +class QQmlNativeDebugConnector : public QQmlDebugConnector +{ + Q_OBJECT + +public: + QQmlNativeDebugConnector(); + ~QQmlNativeDebugConnector() Q_DECL_OVERRIDE; + + bool blockingMode() const Q_DECL_OVERRIDE; + QQmlDebugService *service(const QString &name) const Q_DECL_OVERRIDE; + void addEngine(QJSEngine *engine) Q_DECL_OVERRIDE; + void removeEngine(QJSEngine *engine) Q_DECL_OVERRIDE; + bool addService(const QString &name, QQmlDebugService *service) Q_DECL_OVERRIDE; + bool removeService(const QString &name) Q_DECL_OVERRIDE; + bool open(const QVariantHash &configuration) Q_DECL_OVERRIDE; + static void setDataStreamVersion(int version); + +private slots: + void sendMessage(const QString &name, const QByteArray &message); + void sendMessages(const QString &name, const QList<QByteArray> &messages); + +private: + void announceObjectAvailability(const QString &objectType, QObject *object, bool available); + + QVector<QQmlDebugService *> m_services; + bool m_blockingMode; +}; + +class QQmlNativeDebugConnectorFactory : public QQmlDebugConnectorFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlDebugConnectorFactory_iid FILE "qqmlnativedebugconnector.json") +public: + QQmlDebugConnector *create(const QString &key); +}; + +QT_END_NAMESPACE + +#endif // QQMLNATIVEDEBUGCONNECTOR_H + diff --git a/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro b/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro index e1c4095d88..6efe9eacad 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro +++ b/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro @@ -1,5 +1,5 @@ TARGET = qmldbg_profiler -QT = qml-private core-private +QT = qml-private core-private packetprotocol-private PLUGIN_TYPE = qmltooling PLUGIN_CLASS_NAME = QQmlProfilerServiceFactory @@ -14,6 +14,7 @@ SOURCES += \ HEADERS += \ $$PWD/../shared/qqmlconfigurabledebugservice.h \ + $$PWD/../shared/qqmldebugpacket.h \ $$PWD/qqmlenginecontrolservice.h \ $$PWD/qqmlprofileradapter.h \ $$PWD/qqmlprofilerservice.h \ diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp index 4f131ac481..4da279bb42 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp @@ -32,25 +32,24 @@ ****************************************************************************/ #include "qqmlenginecontrolservice.h" -#include <QQmlEngine> +#include "qqmldebugpacket.h" +#include <QJSEngine> QT_BEGIN_NAMESPACE -const QString QQmlEngineControlService::s_key = QStringLiteral("EngineControl"); - -QQmlEngineControlService::QQmlEngineControlService(QObject *parent) : - QQmlDebugService(s_key, 1, parent) +QQmlEngineControlServiceImpl::QQmlEngineControlServiceImpl(QObject *parent) : + QQmlEngineControlService(1, parent) { } -void QQmlEngineControlService::messageReceived(const QByteArray &message) +void QQmlEngineControlServiceImpl::messageReceived(const QByteArray &message) { QMutexLocker lock(&dataMutex); - QQmlDebugStream d(message); + QQmlDebugPacket d(message); int command; int engineId; d >> command >> engineId; - QQmlEngine *engine = qobject_cast<QQmlEngine *>(objectForId(engineId)); + QJSEngine *engine = qobject_cast<QJSEngine *>(objectForId(engineId)); if (command == StartWaitingEngine && startingEngines.contains(engine)) { startingEngines.removeOne(engine); emit attachedToEngine(engine); @@ -60,7 +59,7 @@ void QQmlEngineControlService::messageReceived(const QByteArray &message) } } -void QQmlEngineControlService::engineAboutToBeAdded(QQmlEngine *engine) +void QQmlEngineControlServiceImpl::engineAboutToBeAdded(QJSEngine *engine) { QMutexLocker lock(&dataMutex); if (state() == Enabled) { @@ -73,7 +72,7 @@ void QQmlEngineControlService::engineAboutToBeAdded(QQmlEngine *engine) } } -void QQmlEngineControlService::engineAboutToBeRemoved(QQmlEngine *engine) +void QQmlEngineControlServiceImpl::engineAboutToBeRemoved(QJSEngine *engine) { QMutexLocker lock(&dataMutex); if (state() == Enabled) { @@ -86,7 +85,7 @@ void QQmlEngineControlService::engineAboutToBeRemoved(QQmlEngine *engine) } } -void QQmlEngineControlService::engineAdded(QQmlEngine *engine) +void QQmlEngineControlServiceImpl::engineAdded(QJSEngine *engine) { if (state() == Enabled) { QMutexLocker lock(&dataMutex); @@ -96,7 +95,7 @@ void QQmlEngineControlService::engineAdded(QQmlEngine *engine) } } -void QQmlEngineControlService::engineRemoved(QQmlEngine *engine) +void QQmlEngineControlServiceImpl::engineRemoved(QJSEngine *engine) { if (state() == Enabled) { QMutexLocker lock(&dataMutex); @@ -106,22 +105,21 @@ void QQmlEngineControlService::engineRemoved(QQmlEngine *engine) } } -void QQmlEngineControlService::sendMessage(QQmlEngineControlService::MessageType type, QQmlEngine *engine) +void QQmlEngineControlServiceImpl::sendMessage(QQmlEngineControlServiceImpl::MessageType type, QJSEngine *engine) { - QByteArray message; - QQmlDebugStream d(&message, QIODevice::WriteOnly); - d << type << idForObject(engine); - emit messageToClient(name(), message); + QQmlDebugPacket d; + d << int(type) << idForObject(engine); + emit messageToClient(name(), d.data()); } -void QQmlEngineControlService::stateChanged(State) +void QQmlEngineControlServiceImpl::stateChanged(State) { // We flush everything for any kind of state change, to avoid complicated timing issues. QMutexLocker lock(&dataMutex); - foreach (QQmlEngine *engine, startingEngines) + foreach (QJSEngine *engine, startingEngines) emit attachedToEngine(engine); startingEngines.clear(); - foreach (QQmlEngine *engine, stoppingEngines) + foreach (QJSEngine *engine, stoppingEngines) emit detachedFromEngine(engine); stoppingEngines.clear(); } diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h index e2a93e562a..028852e964 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h @@ -35,7 +35,7 @@ #define QQMLENGINECONTROLSERVICE_H #include <QMutex> -#include <private/qqmldebugservice_p.h> +#include <private/qqmldebugserviceinterfaces_p.h> // // W A R N I N G @@ -50,11 +50,9 @@ QT_BEGIN_NAMESPACE -class QQmlEngineControlService : public QQmlDebugService +class QQmlEngineControlServiceImpl : public QQmlEngineControlService { public: - static const QString s_key; - enum MessageType { EngineAboutToBeAdded, EngineAdded, @@ -67,22 +65,24 @@ public: StopWaitingEngine }; - QQmlEngineControlService(QObject *parent = 0); + QQmlEngineControlServiceImpl(QObject *parent = 0); protected: + friend class QQmlProfilerServiceFactory; + QMutex dataMutex; - QList<QQmlEngine *> startingEngines; - QList<QQmlEngine *> stoppingEngines; + QList<QJSEngine *> startingEngines; + QList<QJSEngine *> stoppingEngines; - void messageReceived(const QByteArray &); - void engineAboutToBeAdded(QQmlEngine *); - void engineAboutToBeRemoved(QQmlEngine *); - void engineAdded(QQmlEngine *); - void engineRemoved(QQmlEngine *); + void messageReceived(const QByteArray &) Q_DECL_OVERRIDE; + void engineAboutToBeAdded(QJSEngine *) Q_DECL_OVERRIDE; + void engineAboutToBeRemoved(QJSEngine *) Q_DECL_OVERRIDE; + void engineAdded(QJSEngine *) Q_DECL_OVERRIDE; + void engineRemoved(QJSEngine *) Q_DECL_OVERRIDE; - void sendMessage(MessageType type, QQmlEngine *engine); + void sendMessage(MessageType type, QJSEngine *engine); - void stateChanged(State); + void stateChanged(State) Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp index 245900abae..faa1726637 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp @@ -32,13 +32,16 @@ ****************************************************************************/ #include "qqmlprofileradapter.h" +#include "qqmldebugpacket.h" + #include <private/qqmldebugserviceinterfaces_p.h> QT_BEGIN_NAMESPACE QQmlProfilerAdapter::QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEnginePrivate *engine) : - QQmlAbstractProfilerAdapter(service), next(0) + next(0) { + setService(service); engine->enableProfiler(); connect(this, SIGNAL(profilingEnabled(quint64)), engine->profiler, SLOT(startProfiling(quint64))); connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)), @@ -72,13 +75,12 @@ static void qQmlProfilerDataToByteArrays(const QQmlProfilerData *d, QList<QByteA continue; //### using QDataStream is relatively expensive - QQmlDebugStream ds(&data, QIODevice::WriteOnly); + QQmlDebugPacket ds; ds << d->time << decodedMessageType << decodedDetailType; switch (decodedMessageType) { case QQmlProfilerDefinitions::RangeStart: - if (decodedDetailType == (int)QQmlProfilerDefinitions::Binding) - ds << QQmlProfilerDefinitions::QmlBinding; + case QQmlProfilerDefinitions::RangeEnd: break; case QQmlProfilerDefinitions::RangeData: ds << (d->detailString.isEmpty() ? d->detailUrl.toString() : d->detailString); @@ -87,13 +89,11 @@ static void qQmlProfilerDataToByteArrays(const QQmlProfilerData *d, QList<QByteA ds << (d->detailUrl.isEmpty() ? d->detailString : d->detailUrl.toString()) << d->x << d->y; break; - case QQmlProfilerDefinitions::RangeEnd: break; default: Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type."); break; } - messages << data; - data.clear(); + messages << ds.data(); } } } diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h index eceb58ce3a..b15c2febda 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h @@ -54,7 +54,7 @@ class QQmlProfilerAdapter : public QQmlAbstractProfilerAdapter { Q_OBJECT public: QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEnginePrivate *engine); - qint64 sendMessages(qint64 until, QList<QByteArray> &messages); + qint64 sendMessages(qint64 until, QList<QByteArray> &messages) Q_DECL_OVERRIDE; public slots: void receiveData(const QVector<QQmlProfilerData> &new_data); diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp index 65b99ef7ca..462bd5e394 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp @@ -35,9 +35,11 @@ #include "qv4profileradapter.h" #include "qqmlprofileradapter.h" #include "qqmlprofilerservicefactory.h" -#include <private/qqmlengine_p.h> +#include "qqmldebugpacket.h" + +#include <private/qjsengine_p.h> +#include <private/qqmldebugpluginmanager_p.h> -#include <QtCore/qdatastream.h> #include <QtCore/qurl.h> #include <QtCore/qtimer.h> #include <QtCore/qthread.h> @@ -45,18 +47,27 @@ QT_BEGIN_NAMESPACE +Q_QML_DEBUG_PLUGIN_LOADER(QQmlAbstractProfilerAdapter) +Q_QML_IMPORT_DEBUG_PLUGIN(QQuickProfilerAdapterFactory) + QQmlProfilerServiceImpl::QQmlProfilerServiceImpl(QObject *parent) : QQmlConfigurableDebugService<QQmlProfilerService>(1, parent), m_waitingForStop(false) { m_timer.start(); + QQmlAbstractProfilerAdapter *quickAdapter = + loadQQmlAbstractProfilerAdapter(QLatin1String("QQuickProfilerAdapter")); + if (quickAdapter) { + addGlobalProfiler(quickAdapter); + quickAdapter->setService(this); + } } QQmlProfilerServiceImpl::~QQmlProfilerServiceImpl() { // No need to lock here. If any engine or global profiler is still trying to register at this // point we have a nasty bug anyway. - qDeleteAll(m_engineProfilers.values()); + qDeleteAll(m_engineProfilers); qDeleteAll(m_globalProfilers); } @@ -75,8 +86,8 @@ void QQmlProfilerServiceImpl::dataReady(QQmlAbstractProfilerAdapter *profiler) } m_startTimes.insert(0, profiler); if (dataComplete) { - QList<QQmlEngine *> enginesToRelease; - foreach (QQmlEngine *engine, m_stoppingEngines) { + QList<QJSEngine *> enginesToRelease; + foreach (QJSEngine *engine, m_stoppingEngines) { foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers.values(engine)) { if (m_startTimes.values().contains(engineProfiler)) { enginesToRelease.append(engine); @@ -85,27 +96,30 @@ void QQmlProfilerServiceImpl::dataReady(QQmlAbstractProfilerAdapter *profiler) } } sendMessages(); - foreach (QQmlEngine *engine, enginesToRelease) { + foreach (QJSEngine *engine, enginesToRelease) { m_stoppingEngines.removeOne(engine); emit detachedFromEngine(engine); } } } -void QQmlProfilerServiceImpl::engineAboutToBeAdded(QQmlEngine *engine) +void QQmlProfilerServiceImpl::engineAboutToBeAdded(QJSEngine *engine) { Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO, "QML profilers have to be added from the engine thread"); QMutexLocker lock(&m_configMutex); - QQmlProfilerAdapter *qmlAdapter = new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(engine)); + if (QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine)) { + QQmlProfilerAdapter *qmlAdapter = + new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(qmlEngine)); + addEngineProfiler(qmlAdapter, engine); + } QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, QV8Engine::getV4(engine->handle())); - addEngineProfiler(qmlAdapter, engine); addEngineProfiler(v4Adapter, engine); QQmlConfigurableDebugService<QQmlProfilerService>::engineAboutToBeAdded(engine); } -void QQmlProfilerServiceImpl::engineAdded(QQmlEngine *engine) +void QQmlProfilerServiceImpl::engineAdded(QJSEngine *engine) { Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO, "QML profilers have to be added from the engine thread"); @@ -115,7 +129,7 @@ void QQmlProfilerServiceImpl::engineAdded(QQmlEngine *engine) profiler->stopWaiting(); } -void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine) +void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QJSEngine *engine) { Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO, "QML profilers have to be removed from the engine thread"); @@ -135,7 +149,7 @@ void QQmlProfilerServiceImpl::engineAboutToBeRemoved(QQmlEngine *engine) } } -void QQmlProfilerServiceImpl::engineRemoved(QQmlEngine *engine) +void QQmlProfilerServiceImpl::engineRemoved(QJSEngine *engine) { Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO, "QML profilers have to be removed from the engine thread"); @@ -148,7 +162,7 @@ void QQmlProfilerServiceImpl::engineRemoved(QQmlEngine *engine) m_engineProfilers.remove(engine); } -void QQmlProfilerServiceImpl::addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QQmlEngine *engine) +void QQmlProfilerServiceImpl::addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QJSEngine *engine) { profiler->moveToThread(thread()); profiler->synchronize(m_timer); @@ -176,7 +190,6 @@ void QQmlProfilerServiceImpl::removeGlobalProfiler(QQmlAbstractProfilerAdapter * QMutexLocker lock(&m_configMutex); removeProfilerFromStartTimes(profiler); m_globalProfilers.removeOne(profiler); - delete profiler; } void QQmlProfilerServiceImpl::removeProfilerFromStartTimes(const QQmlAbstractProfilerAdapter *profiler) @@ -198,12 +211,17 @@ void QQmlProfilerServiceImpl::removeProfilerFromStartTimes(const QQmlAbstractPro * * If any engine profiler is started like that also start all global profilers. */ -void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 features) +void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features) { QMutexLocker lock(&m_configMutex); - QByteArray message; - QQmlDebugStream d(&message, QIODevice::WriteOnly); + if (features & static_cast<quint64>(1) << ProfileDebugMessages) { + if (QDebugMessageService *messageService = + QQmlDebugConnector::instance()->service<QDebugMessageService>()) + messageService->synchronizeTime(m_timer); + } + + QQmlDebugPacket d; d << m_timer.nsecsElapsed() << (int)Event << (int)StartTrace; bool startedAny = false; @@ -217,8 +235,8 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature if (startedAny) d << idForObject(engine); } else { - QSet<QQmlEngine *> engines; - for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); + QSet<QJSEngine *> engines; + for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { if (!i.value()->isRunning()) { engines << i.key(); @@ -226,7 +244,7 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature startedAny = true; } } - foreach (QQmlEngine *profiledEngine, engines) + foreach (QJSEngine *profiledEngine, engines) d << idForObject(profiledEngine); } @@ -239,7 +257,7 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature emit startFlushTimer(); } - emit messageToClient(name(), message); + emit messageToClient(name(), d.data()); } /*! @@ -249,14 +267,14 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature * If afterwards no more engine profilers are running, also stop all global profilers. Otherwise * only make them report their data. */ -void QQmlProfilerServiceImpl::stopProfiling(QQmlEngine *engine) +void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine) { QMutexLocker lock(&m_configMutex); QList<QQmlAbstractProfilerAdapter *> stopping; QList<QQmlAbstractProfilerAdapter *> reporting; bool stillRunning = false; - for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); + for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { if (i.value()->isRunning()) { if (engine == 0 || i.key() == engine) { @@ -299,15 +317,13 @@ void QQmlProfilerServiceImpl::sendMessages() { QList<QByteArray> messages; - QByteArray data; - + QQmlDebugPacket traceEnd; if (m_waitingForStop) { - QQmlDebugStream traceEnd(&data, QIODevice::WriteOnly); traceEnd << m_timer.nsecsElapsed() << (int)Event << (int)EndTrace; - QSet<QQmlEngine *> seen; + QSet<QJSEngine *> seen; foreach (QQmlAbstractProfilerAdapter *profiler, m_startTimes) { - for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); + for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { if (i.value() == profiler && !seen.contains(i.key())) { seen << i.key(); @@ -331,12 +347,11 @@ void QQmlProfilerServiceImpl::sendMessages() if (m_waitingForStop) { //indicate completion - messages << data; - data.clear(); + messages << traceEnd.data(); - QQmlDebugStream ds(&data, QIODevice::WriteOnly); + QQmlDebugPacket ds; ds << (qint64)-1 << (int)Complete; - messages << data; + messages << ds.data(); m_waitingForStop = false; } @@ -360,7 +375,7 @@ void QQmlProfilerServiceImpl::stateAboutToBeChanged(QQmlDebugService::State newS // Stop all profiling and send the data before we get disabled. if (newState != Enabled) { - foreach (QQmlEngine *engine, m_engineProfilers.keys()) + foreach (QJSEngine *engine, m_engineProfilers.keys()) stopProfiling(engine); } } @@ -369,8 +384,7 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message) { QMutexLocker lock(&m_configMutex); - QByteArray rwData = message; - QQmlDebugStream stream(&rwData, QIODevice::ReadOnly); + QQmlDebugPacket stream(message); int engineId = -1; quint64 features = std::numeric_limits<quint64>::max(); @@ -397,9 +411,9 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message) // If engineId == -1 objectForId() and then the cast will return 0. if (enabled) - startProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId)), features); + startProfiling(qobject_cast<QJSEngine *>(objectForId(engineId)), features); else - stopProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId))); + stopProfiling(qobject_cast<QJSEngine *>(objectForId(engineId))); stopWaiting(); } diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h index 9b139ffabb..299d170339 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h @@ -64,8 +64,6 @@ QT_BEGIN_NAMESPACE class QUrl; -class QQmlEngine; - class QQmlProfilerServiceImpl : public QQmlConfigurableDebugService<QQmlProfilerService>, @@ -74,21 +72,22 @@ class QQmlProfilerServiceImpl : Q_OBJECT public: - void engineAboutToBeAdded(QQmlEngine *engine); - void engineAboutToBeRemoved(QQmlEngine *engine); - void engineAdded(QQmlEngine *engine); - void engineRemoved(QQmlEngine *engine); + void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE; + void engineAboutToBeRemoved(QJSEngine *engine) Q_DECL_OVERRIDE; + void engineAdded(QJSEngine *engine) Q_DECL_OVERRIDE; + void engineRemoved(QJSEngine *engine) Q_DECL_OVERRIDE; - void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler); - void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler); + void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE; + void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE; - void startProfiling(QQmlEngine *engine, quint64 features = std::numeric_limits<quint64>::max()); - void stopProfiling(QQmlEngine *engine); + void startProfiling(QJSEngine *engine, + quint64 features = std::numeric_limits<quint64>::max()) Q_DECL_OVERRIDE; + void stopProfiling(QJSEngine *engine) Q_DECL_OVERRIDE; QQmlProfilerServiceImpl(QObject *parent = 0); - ~QQmlProfilerServiceImpl(); + ~QQmlProfilerServiceImpl() Q_DECL_OVERRIDE; - void dataReady(QQmlAbstractProfilerAdapter *profiler); + void dataReady(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE; signals: void startFlushTimer(); @@ -98,14 +97,14 @@ private slots: void flush(); protected: - virtual void stateAboutToBeChanged(State state); - virtual void messageReceived(const QByteArray &); + virtual void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE; + virtual void messageReceived(const QByteArray &) Q_DECL_OVERRIDE; private: friend class QQmlProfilerServiceFactory; void sendMessages(); - void addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QQmlEngine *engine); + void addEngineProfiler(QQmlAbstractProfilerAdapter *profiler, QJSEngine *engine); void removeProfilerFromStartTimes(const QQmlAbstractProfilerAdapter *profiler); QElapsedTimer m_timer; @@ -113,8 +112,8 @@ private: bool m_waitingForStop; QList<QQmlAbstractProfilerAdapter *> m_globalProfilers; - QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *> m_engineProfilers; - QList<QQmlEngine *> m_stoppingEngines; + QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *> m_engineProfilers; + QList<QJSEngine *> m_stoppingEngines; QMultiMap<qint64, QQmlAbstractProfilerAdapter *> m_startTimes; }; diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp index 83c2075246..c1b8e6a817 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp @@ -42,8 +42,8 @@ QQmlDebugService *QQmlProfilerServiceFactory::create(const QString &key) if (key == QQmlProfilerServiceImpl::s_key) return new QQmlProfilerServiceImpl(this); - if (key == QQmlEngineControlService::s_key) - return new QQmlEngineControlService(this); + if (key == QQmlEngineControlServiceImpl::s_key) + return new QQmlEngineControlServiceImpl(this); return 0; } diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp index 24e01f4c68..2e7051b912 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp @@ -33,16 +33,22 @@ #include "qv4profileradapter.h" #include "qqmlprofilerservice.h" +#include "qqmldebugpacket.h" QT_BEGIN_NAMESPACE QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::ExecutionEngine *engine) : - QQmlAbstractProfilerAdapter(service), dataPos(0), memoryPos(0) + m_functionCallPos(0), m_memoryPos(0) { + setService(service); engine->enableProfiler(); connect(this, SIGNAL(profilingEnabled(quint64)), - engine->profiler, SLOT(startProfiling(quint64))); + this, SLOT(forwardEnabled(quint64))); connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)), + this, SLOT(forwardEnabledWhileWaiting(quint64)), Qt::DirectConnection); + connect(this, SIGNAL(v4ProfilingEnabled(quint64)), + engine->profiler, SLOT(startProfiling(quint64))); + connect(this, SIGNAL(v4ProfilingEnabledWhileWaiting(quint64)), engine->profiler, SLOT(startProfiling(quint64)), Qt::DirectConnection); connect(this, SIGNAL(profilingDisabled()), engine->profiler, SLOT(stopProfiling())); connect(this, SIGNAL(profilingDisabledWhileWaiting()), engine->profiler, SLOT(stopProfiling()), @@ -58,30 +64,29 @@ QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::Execut qint64 QV4ProfilerAdapter::appendMemoryEvents(qint64 until, QList<QByteArray> &messages) { - QByteArray message; - while (memory_data.length() > memoryPos && memory_data[memoryPos].timestamp <= until) { - QQmlDebugStream d(&message, QIODevice::WriteOnly); - QV4::Profiling::MemoryAllocationProperties &props = memory_data[memoryPos]; + while (m_memoryData.length() > m_memoryPos && m_memoryData[m_memoryPos].timestamp <= until) { + QQmlDebugPacket d; + QV4::Profiling::MemoryAllocationProperties &props = m_memoryData[m_memoryPos]; d << props.timestamp << MemoryAllocation << props.type << props.size; - ++memoryPos; - messages.append(message); + ++m_memoryPos; + messages.append(d.data()); } - return memory_data.length() == memoryPos ? -1 : memory_data[memoryPos].timestamp; + return m_memoryData.length() == m_memoryPos ? -1 : m_memoryData[m_memoryPos].timestamp; } qint64 QV4ProfilerAdapter::finalizeMessages(qint64 until, QList<QByteArray> &messages, qint64 callNext) { if (callNext == -1) { - data.clear(); - dataPos = 0; + m_functionCallData.clear(); + m_functionCallPos = 0; } qint64 memoryNext = appendMemoryEvents(until, messages); if (memoryNext == -1) { - memory_data.clear(); - memoryPos = 0; + m_memoryData.clear(); + m_memoryPos = 0; return callNext; } @@ -90,64 +95,84 @@ qint64 QV4ProfilerAdapter::finalizeMessages(qint64 until, QList<QByteArray> &mes qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages) { - QByteArray message; while (true) { - while (!stack.isEmpty() && (dataPos == data.length() || - stack.top() <= data[dataPos].start)) { - if (stack.top() > until) - return finalizeMessages(until, messages, stack.top()); - - appendMemoryEvents(stack.top(), messages); - QQmlDebugStream d(&message, QIODevice::WriteOnly); - d << stack.pop() << RangeEnd << Javascript; - messages.append(message); + while (!m_stack.isEmpty() && + (m_functionCallPos == m_functionCallData.length() || + m_stack.top() <= m_functionCallData[m_functionCallPos].start)) { + if (m_stack.top() > until) + return finalizeMessages(until, messages, m_stack.top()); + + appendMemoryEvents(m_stack.top(), messages); + QQmlDebugPacket d; + d << m_stack.pop() << RangeEnd << Javascript; + messages.append(d.data()); } - while (dataPos != data.length() && (stack.empty() || data[dataPos].start < stack.top())) { - const QV4::Profiling::FunctionCallProperties &props = data[dataPos]; + while (m_functionCallPos != m_functionCallData.length() && + (m_stack.empty() || m_functionCallData[m_functionCallPos].start < m_stack.top())) { + const QV4::Profiling::FunctionCallProperties &props = + m_functionCallData[m_functionCallPos]; if (props.start > until) return finalizeMessages(until, messages, props.start); appendMemoryEvents(props.start, messages); - QQmlDebugStream d_start(&message, QIODevice::WriteOnly); + QQmlDebugPacket d_start; d_start << props.start << RangeStart << Javascript; - messages.push_back(message); - message.clear(); - QQmlDebugStream d_location(&message, QIODevice::WriteOnly); + messages.push_back(d_start.data()); + QQmlDebugPacket d_location; d_location << props.start << RangeLocation << Javascript << props.file << props.line << props.column; - messages.push_back(message); - message.clear(); - QQmlDebugStream d_data(&message, QIODevice::WriteOnly); + messages.push_back(d_location.data()); + QQmlDebugPacket d_data; d_data << props.start << RangeData << Javascript << props.name; - messages.push_back(message); - message.clear(); - stack.push(props.end); - ++dataPos; + messages.push_back(d_data.data()); + m_stack.push(props.end); + ++m_functionCallPos; } - if (stack.empty() && dataPos == data.length()) + if (m_stack.empty() && m_functionCallPos == m_functionCallData.length()) return finalizeMessages(until, messages, -1); } } void QV4ProfilerAdapter::receiveData( - const QVector<QV4::Profiling::FunctionCallProperties> &new_data, - const QVector<QV4::Profiling::MemoryAllocationProperties> &new_memory_data) + const QVector<QV4::Profiling::FunctionCallProperties> &functionCallData, + const QVector<QV4::Profiling::MemoryAllocationProperties> &memoryData) { // In rare cases it could be that another flush or stop event is processed while data from // the previous one is still pending. In that case we just append the data. - if (data.isEmpty()) - data = new_data; + if (m_functionCallData.isEmpty()) + m_functionCallData = functionCallData; else - data.append(new_data); + m_functionCallData.append(functionCallData); - if (memory_data.isEmpty()) - memory_data = new_memory_data; + if (m_memoryData.isEmpty()) + m_memoryData = memoryData; else - memory_data.append(new_memory_data); + m_memoryData.append(memoryData); service->dataReady(this); } +quint64 QV4ProfilerAdapter::translateFeatures(quint64 qmlFeatures) +{ + quint64 v4Features = 0; + const quint64 one = 1; + if (qmlFeatures & (one << ProfileJavaScript)) + v4Features |= (one << QV4::Profiling::FeatureFunctionCall); + if (qmlFeatures & (one << ProfileMemory)) + v4Features |= (one << QV4::Profiling::FeatureMemoryAllocation); + return v4Features; +} + +void QV4ProfilerAdapter::forwardEnabled(quint64 features) +{ + emit v4ProfilingEnabled(translateFeatures(features)); +} + +void QV4ProfilerAdapter::forwardEnabledWhileWaiting(quint64 features) +{ + emit v4ProfilingEnabledWhileWaiting(translateFeatures(features)); +} + QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h index cea3da72e3..c07fc4dc96 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h +++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h @@ -62,18 +62,28 @@ public: virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages); +signals: + void v4ProfilingEnabled(quint64 v4Features); + void v4ProfilingEnabledWhileWaiting(quint64 v4Features); + public slots: void receiveData(const QVector<QV4::Profiling::FunctionCallProperties> &, const QVector<QV4::Profiling::MemoryAllocationProperties> &); +private slots: + void forwardEnabled(quint64 features); + void forwardEnabledWhileWaiting(quint64 features); + private: - QVector<QV4::Profiling::FunctionCallProperties> data; - QVector<QV4::Profiling::MemoryAllocationProperties> memory_data; - int dataPos; - int memoryPos; - QStack<qint64> stack; + QVector<QV4::Profiling::FunctionCallProperties> m_functionCallData; + QVector<QV4::Profiling::MemoryAllocationProperties> m_memoryData; + int m_functionCallPos; + int m_memoryPos; + QStack<qint64> m_stack; qint64 appendMemoryEvents(qint64 until, QList<QByteArray> &messages); qint64 finalizeMessages(qint64 until, QList<QByteArray> &messages, qint64 callNext); + + static quint64 translateFeatures(quint64 qmlFeatures); }; QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro b/src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro new file mode 100644 index 0000000000..6ca0a184ca --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro @@ -0,0 +1,20 @@ +TARGET = qmldbg_quickprofiler +QT += qml-private quick-private core-private packetprotocol-private + +PLUGIN_TYPE = qmltooling +PLUGIN_CLASS_NAME = QQuickProfilerAdapterFactory +load(qt_plugin) + +INCLUDEPATH += $$PWD/../shared + +SOURCES += \ + $$PWD/qquickprofileradapter.cpp \ + $$PWD/qquickprofileradapterfactory.cpp + +HEADERS += \ + $$PWD/qquickprofileradapter.h \ + $$PWD/qquickprofileradapterfactory.h \ + $$PWD/../shared/qqmldebugpacket.h + +OTHER_FILES += \ + qquickprofileradapter.json diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp new file mode 100644 index 0000000000..8438a6fb3a --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickprofileradapter.h" +#include "qqmldebugpacket.h" +#include <QCoreApplication> +#include <private/qqmldebugserviceinterfaces_p.h> +#include <private/qquickprofiler_p.h> + +QT_BEGIN_NAMESPACE + +QQuickProfilerAdapter::QQuickProfilerAdapter(QObject *parent) : + QQmlAbstractProfilerAdapter(parent), next(0) +{ + QQuickProfiler::initialize(this); + + // We can always do DirectConnection here as all methods are protected by mutexes + connect(this, SIGNAL(profilingEnabled(quint64)), + QQuickProfiler::s_instance, SLOT(startProfilingImpl(quint64)), Qt::DirectConnection); + connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)), + QQuickProfiler::s_instance, SLOT(startProfilingImpl(quint64)), Qt::DirectConnection); + connect(this, SIGNAL(referenceTimeKnown(QElapsedTimer)), + QQuickProfiler::s_instance, SLOT(setTimer(QElapsedTimer)), Qt::DirectConnection); + connect(this, SIGNAL(profilingDisabled()), + QQuickProfiler::s_instance, SLOT(stopProfilingImpl()), Qt::DirectConnection); + connect(this, SIGNAL(profilingDisabledWhileWaiting()), + QQuickProfiler::s_instance, SLOT(stopProfilingImpl()), Qt::DirectConnection); + connect(this, SIGNAL(dataRequested()), + QQuickProfiler::s_instance, SLOT(reportDataImpl()), Qt::DirectConnection); + connect(QQuickProfiler::s_instance, SIGNAL(dataReady(QVector<QQuickProfilerData>)), + this, SLOT(receiveData(QVector<QQuickProfilerData>)), Qt::DirectConnection); +} + +QQuickProfilerAdapter::~QQuickProfilerAdapter() +{ + if (service) + service->removeGlobalProfiler(this); +} + +// convert to QByteArrays that can be sent to the debug client +// use of QDataStream can skew results +// (see tst_qqmldebugtrace::trace() benchmark) +static void qQuickProfilerDataToByteArrays(const QQuickProfilerData &data, + QList<QByteArray> &messages) +{ + Q_ASSERT_X(((data.messageType | data.detailType) & (1 << 31)) == 0, Q_FUNC_INFO, + "You can use at most 31 message types and 31 detail types."); + for (uint decodedMessageType = 0; (data.messageType >> decodedMessageType) != 0; + ++decodedMessageType) { + if ((data.messageType & (1 << decodedMessageType)) == 0) + continue; + + for (uint decodedDetailType = 0; (data.detailType >> decodedDetailType) != 0; + ++decodedDetailType) { + if ((data.detailType & (1 << decodedDetailType)) == 0) + continue; + + //### using QDataStream is relatively expensive + QQmlDebugPacket ds; + ds << data.time << decodedMessageType << decodedDetailType; + + switch (decodedMessageType) { + case QQuickProfiler::Event: + switch (decodedDetailType) { + case QQuickProfiler::AnimationFrame: + ds << data.framerate << data.count << data.threadId; + break; + case QQuickProfiler::Key: + case QQuickProfiler::Mouse: + ds << data.inputType << data.inputA << data.inputB; + break; + } + break; + case QQuickProfiler::PixmapCacheEvent: + ds << data.detailUrl.toString(); + switch (decodedDetailType) { + case QQuickProfiler::PixmapSizeKnown: ds << data.x << data.y; break; + case QQuickProfiler::PixmapReferenceCountChanged: ds << data.count; break; + case QQuickProfiler::PixmapCacheCountChanged: ds << data.count; break; + default: break; + } + break; + case QQuickProfiler::SceneGraphFrame: + switch (decodedDetailType) { + // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime + case QQuickProfiler::SceneGraphRendererFrame: ds << data.subtime_1 << data.subtime_2 << data.subtime_3 << data.subtime_4; break; + // AdaptationLayerFrame: glyphCount (which is an integer), glyphRenderTime, glyphStoreTime + case QQuickProfiler::SceneGraphAdaptationLayerFrame: ds << data.subtime_3 << data.subtime_1 << data.subtime_2; break; + // ContextFrame: compiling material time + case QQuickProfiler::SceneGraphContextFrame: ds << data.subtime_1; break; + // RenderLoop: syncTime, renderTime, swapTime + case QQuickProfiler::SceneGraphRenderLoopFrame: ds << data.subtime_1 << data.subtime_2 << data.subtime_3; break; + // TexturePrepare: bind, convert, swizzle, upload, mipmap + case QQuickProfiler::SceneGraphTexturePrepare: ds << data.subtime_1 << data.subtime_2 << data.subtime_3 << data.subtime_4 << data.subtime_5; break; + // TextureDeletion: deletionTime + case QQuickProfiler::SceneGraphTextureDeletion: ds << data.subtime_1; break; + // PolishAndSync: polishTime, waitTime, syncTime, animationsTime, + case QQuickProfiler::SceneGraphPolishAndSync: ds << data.subtime_1 << data.subtime_2 << data.subtime_3 << data.subtime_4; break; + // WindowsRenderLoop: GL time, make current time, SceneGraph time + case QQuickProfiler::SceneGraphWindowsRenderShow: ds << data.subtime_1 << data.subtime_2 << data.subtime_3; break; + // WindowsAnimations: update time + case QQuickProfiler::SceneGraphWindowsAnimations: ds << data.subtime_1; break; + // non-threaded rendering: polish time + case QQuickProfiler::SceneGraphPolishFrame: ds << data.subtime_1; break; + default:break; + } + break; + default: + Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type."); + break; + } + messages << ds.data(); + } + } +} + +qint64 QQuickProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages) +{ + while (next < m_data.size()) { + if (m_data[next].time <= until) + qQuickProfilerDataToByteArrays(m_data[next++], messages); + else + return m_data[next].time; + } + m_data.clear(); + next = 0; + return -1; +} + +void QQuickProfilerAdapter::receiveData(const QVector<QQuickProfilerData> &new_data) +{ + if (m_data.isEmpty()) + m_data = new_data; + else + m_data.append(new_data); + service->dataReady(this); +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.h b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.h new file mode 100644 index 0000000000..7a3a25f049 --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPROFILERADAPTER_H +#define QQUICKPROFILERADAPTER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/private/qqmlabstractprofileradapter_p.h> +#include <QtQuick/private/qquickprofiler_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickProfilerAdapter : public QQmlAbstractProfilerAdapter { + Q_OBJECT +public: + QQuickProfilerAdapter(QObject *parent = 0); + ~QQuickProfilerAdapter(); + qint64 sendMessages(qint64 until, QList<QByteArray> &messages); + +public slots: + void receiveData(const QVector<QQuickProfilerData> &new_data); + +private: + int next; + QVector<QQuickProfilerData> m_data; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPROFILERADAPTER_H diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.json b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.json new file mode 100644 index 0000000000..76b08fbcab --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "QQuickProfilerAdapter" ] +} diff --git a/tools/qmlprofiler/qmlprofilereventlocation.h b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.cpp index ebf9f2eed6..9fae5e3a4d 100644 --- a/tools/qmlprofiler/qmlprofilereventlocation.h +++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.cpp @@ -31,23 +31,18 @@ ** ****************************************************************************/ -#ifndef QMLPROFILEREVENTLOCATION_H -#define QMLPROFILEREVENTLOCATION_H +#include "qquickprofileradapterfactory.h" +#include "qquickprofileradapter.h" +#include <private/qqmldebugconnector_p.h> +#include <private/qqmldebugserviceinterfaces_p.h> -#include <QString> +QT_BEGIN_NAMESPACE -struct QmlEventLocation +QQmlAbstractProfilerAdapter *QQuickProfilerAdapterFactory::create(const QString &key) { - QmlEventLocation() : line(-1), column(-1) {} - QmlEventLocation(const QString &file, int lineNumber, int columnNumber) - : filename(file), line(lineNumber), column(columnNumber) {} - QString filename; - int line; - int column; -}; + if (key != QLatin1String("QQuickProfilerAdapter")) + return 0; + return new QQuickProfilerAdapter(this); +} -QT_BEGIN_NAMESPACE -Q_DECLARE_TYPEINFO(QmlEventLocation, Q_MOVABLE_TYPE); QT_END_NAMESPACE - -#endif // QMLPROFILEREVENTLOCATION_H diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h new file mode 100644 index 0000000000..dee77747ef --- /dev/null +++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPROFILERADAPTERFACTORY_H +#define QQUICKPROFILERADAPTERFACTORY_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/private/qqmlabstractprofileradapter_p.h> +#include <QtQuick/private/qquickprofiler_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickProfilerAdapterFactory : public QQmlAbstractProfilerAdapterFactory +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlAbstractProfilerAdapterFactory_iid FILE "qquickprofileradapter.json") +public: + QQmlAbstractProfilerAdapter *create(const QString &key); +}; + +QT_END_NAMESPACE + +#endif // QQUICKPROFILERADAPTERFACTORY_H diff --git a/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro b/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro index 5e2d0874df..923faa01f3 100644 --- a/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro +++ b/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro @@ -1,19 +1,18 @@ TARGET = qmldbg_server -QT = qml-private core-private +QT = qml-private packetprotocol-private PLUGIN_TYPE = qmltooling PLUGIN_CLASS_NAME = QQmlDebugServerFactory load(qt_plugin) SOURCES += \ - $$PWD/qqmldebugserver.cpp \ - $$PWD/../shared/qpacketprotocol.cpp + $$PWD/qqmldebugserver.cpp HEADERS += \ $$PWD/qqmldebugserverfactory.h \ $$PWD/../shared/qqmldebugserver.h \ - $$PWD/../shared/qpacketprotocol.h \ - $$PWD/../shared/qqmldebugserverconnection.h + $$PWD/../shared/qqmldebugserverconnection.h \ + $$PWD/../shared/qqmldebugpacket.h INCLUDEPATH += $$PWD \ $$PWD/../shared diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp index 69d36beaca..50c7ef3771 100644 --- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp +++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp @@ -33,13 +33,15 @@ #include "qqmldebugserver.h" #include "qqmldebugserverfactory.h" -#include "qpacketprotocol.h" #include "qqmldebugserverconnection.h" +#include "qqmldebugpacket.h" #include <private/qqmldebugservice_p.h> -#include <private/qqmlengine_p.h> +#include <private/qjsengine_p.h> #include <private/qqmlglobal_p.h> #include <private/qqmldebugpluginmanager_p.h> +#include <private/qqmldebugserviceinterfaces_p.h> +#include <private/qpacketprotocol_p.h> #include <QtCore/QAtomicInt> #include <QtCore/QDir> @@ -47,9 +49,6 @@ #include <QtCore/QStringList> #include <QtCore/qwaitcondition.h> -#include <private/qobject_p.h> -#include <private/qcoreapplication_p.h> - QT_BEGIN_NAMESPACE /* @@ -105,6 +104,11 @@ public: m_fileName = fileName; } + const QString &pluginName() const + { + return m_pluginName; + } + void run(); private: @@ -122,25 +126,25 @@ class QQmlDebugServerImpl : public QQmlDebugServer public: QQmlDebugServerImpl(); - bool blockingMode() const; + bool blockingMode() const Q_DECL_OVERRIDE; - QQmlDebugService *service(const QString &name) const; + QQmlDebugService *service(const QString &name) const Q_DECL_OVERRIDE; - void addEngine(QQmlEngine *engine); - void removeEngine(QQmlEngine *engine); + void addEngine(QJSEngine *engine) Q_DECL_OVERRIDE; + void removeEngine(QJSEngine *engine) Q_DECL_OVERRIDE; - bool addService(const QString &name, QQmlDebugService *service); - bool removeService(const QString &name); + bool addService(const QString &name, QQmlDebugService *service) Q_DECL_OVERRIDE; + bool removeService(const QString &name) Q_DECL_OVERRIDE; - bool open(const QVariantHash &configuration); - void setDevice(QIODevice *socket); + bool open(const QVariantHash &configuration) Q_DECL_OVERRIDE; + void setDevice(QIODevice *socket) Q_DECL_OVERRIDE; void parseArguments(); static void cleanup(); private slots: - void wakeEngine(QQmlEngine *engine); + void wakeEngine(QJSEngine *engine); void sendMessage(const QString &name, const QByteArray &message); void sendMessages(const QString &name, const QList<QByteArray> &messages); void changeServiceState(const QString &serviceName, QQmlDebugService::State state); @@ -175,7 +179,7 @@ private: bool m_gotHello; bool m_blockingMode; - QHash<QQmlEngine *, EngineCondition> m_engineConditions; + QHash<QJSEngine *, EngineCondition> m_engineConditions; QMutex m_helloMutex; QWaitCondition m_helloCondition; @@ -304,6 +308,9 @@ bool QQmlDebugServerImpl::open(const QVariantHash &configuration = QVariantHash( } } + if (m_thread.pluginName().isEmpty()) + return false; + QMutexLocker locker(&m_helloMutex); m_thread.start(); m_helloCondition.wait(&m_helloMutex); // wait for connection @@ -312,6 +319,7 @@ bool QQmlDebugServerImpl::open(const QVariantHash &configuration = QVariantHash( return true; } +#define qUsage qWarning().noquote().nospace void QQmlDebugServerImpl::parseArguments() { // format: qmljsdebugger=port:<port_from>[,port_to],host:<ip address>][,block] @@ -334,7 +342,7 @@ void QQmlDebugServerImpl::parseArguments() for (; argsIt != argsItEnd; ++argsIt) { const QString strArgument = *argsIt; if (strArgument.startsWith(QLatin1String("port:"))) { - portFrom = strArgument.mid(5).toInt(&ok); + portFrom = strArgument.midRef(5).toInt(&ok); portTo = portFrom; QStringList::const_iterator argsNext = argsIt + 1; if (argsNext == argsItEnd) @@ -360,9 +368,8 @@ void QQmlDebugServerImpl::parseArguments() } else if (!services.isEmpty()) { services.append(strArgument); } else { - qWarning() << QString::fromLatin1("QML Debugger: Invalid argument '%1' " - "detected. Ignoring the same.") - .arg(strArgument); + qUsage() << tr("QML Debugger: Invalid argument \"%1\" detected. Ignoring the same.") + .arg(strArgument); } } @@ -374,11 +381,43 @@ void QQmlDebugServerImpl::parseArguments() else m_thread.setPortRange(portFrom, portTo, hostAddress); } else { - qWarning() << QString::fromLatin1("QML Debugger: Ignoring \"-qmljsdebugger=%1\". " - "Format is qmljsdebugger=port:<port_from>[,port_to],host:" - "<ip address>][,block]").arg(args); + qUsage() << tr("QML Debugger: Ignoring \"-qmljsdebugger=%1\".").arg(args); + qUsage() << tr("The format is \"-qmljsdebugger=[file:<file>|port:<port_from>][,<port_to>]" + "[,host:<ip address>][,block][,services:<service>][,<service>]*\"\n"); + qUsage() << tr("\"file:\" can be used to specify the name of a file the debugger will try " + "to connect to using a QLocalSocket. If \"file:\" is given any \"host:\" and" + "\"port:\" arguments will be ignored.\n"); + qUsage() << tr("\"host:\" and \"port:\" can be used to specify an address and a single " + "port or a range of ports the debugger will try to bind to with a " + "QTcpServer.\n"); + qUsage() << tr("\"block\" makes the debugger and some services wait for clients to be " + "connected and ready before the first QML engine starts.\n"); + qUsage() << tr("\"services:\" can be used to specify which debug services the debugger " + "should load. Some debug services interact badly with others. The V4 " + "debugger should not be loaded when using the QML profiler as it will force " + "any V4 engines to use the JavaScript interpreter rather than the JIT. The " + "following debug services are available by default:"); + qUsage() << QQmlEngineDebugService::s_key << tr("\t- The QML debugger"); + qUsage() << QV4DebugService::s_key << tr("\t- The V4 debugger"); + qUsage() << QQmlInspectorService::s_key << tr("\t- The QML inspector"); + qUsage() << QQmlProfilerService::s_key << tr("\t- The QML profiler"); + qUsage() << QQmlEngineControlService::s_key + << tr("\t- Allows the client to delay the starting and stopping of\n" + "\t\t QML engines until other services are ready. QtCreator\n" + "\t\t uses this service with the QML profiler in order to\n" + "\t\t profile multiple QML engines at the same time."); + qUsage() << QDebugMessageService::s_key + << tr("\t- Sends qDebug() and similar messages over the QML debug\n" + "\t\t connection. QtCreator uses this for showing debug\n" + "\t\t messages in the JavaScript console."); + qUsage() << tr("Other services offered by qmltooling plugins that implement " + "QQmlDebugServiceFactory and which can be found in the standard plugin " + "paths will also be available and can be specified. If no \"services\" " + "argument is given, all services found this way, including the default " + "ones, are loaded."); } } +#undef qUsage void QQmlDebugServerImpl::receiveMessage() { @@ -390,7 +429,7 @@ void QQmlDebugServerImpl::receiveMessage() if (!m_protocol) return; - QQmlDebugStream in(m_protocol->read().data()); + QQmlDebugPacket in(m_protocol->read()); QString name; @@ -404,16 +443,15 @@ void QQmlDebugServerImpl::receiveMessage() //Get the supported QDataStream version if (!in.atEnd()) { - in >> QQmlDebugStream::s_dataStreamVersion; - if (QQmlDebugStream::s_dataStreamVersion > QDataStream().version()) - QQmlDebugStream::s_dataStreamVersion = QDataStream().version(); + in >> s_dataStreamVersion; + if (s_dataStreamVersion > QDataStream::Qt_DefaultCompiledVersion) + s_dataStreamVersion = QDataStream::Qt_DefaultCompiledVersion; } // Send the hello answer immediately, since it needs to arrive before // the plugins below start sending messages. - QByteArray helloAnswer; - QQmlDebugStream out(&helloAnswer, QIODevice::WriteOnly); + QQmlDebugPacket out; QStringList pluginNames; QList<float> pluginVersions; const int count = m_plugins.count(); @@ -426,11 +464,9 @@ void QQmlDebugServerImpl::receiveMessage() } out << QString(QStringLiteral("QDeclarativeDebugClient")) << 0 << protocolVersion - << pluginNames << pluginVersions << QQmlDebugStream::s_dataStreamVersion; + << pluginNames << pluginVersions << dataStreamVersion(); - QPacket pack; - pack.writeRawData(helloAnswer.data(), helloAnswer.length()); - m_protocol->send(pack); + m_protocol->send(out.data()); m_connection->flush(); QMutexLocker helloLock(&m_helloMutex); @@ -523,7 +559,7 @@ QQmlDebugService *QQmlDebugServerImpl::service(const QString &name) const return m_plugins.value(name); } -void QQmlDebugServerImpl::addEngine(QQmlEngine *engine) +void QQmlDebugServerImpl::addEngine(QJSEngine *engine) { // to be executed outside of debugger thread Q_ASSERT(QThread::currentThread() != &m_thread); @@ -538,7 +574,7 @@ void QQmlDebugServerImpl::addEngine(QQmlEngine *engine) service->engineAdded(engine); } -void QQmlDebugServerImpl::removeEngine(QQmlEngine *engine) +void QQmlDebugServerImpl::removeEngine(QJSEngine *engine) { // to be executed outside of debugger thread Q_ASSERT(QThread::currentThread() != &m_thread); @@ -566,10 +602,10 @@ bool QQmlDebugServerImpl::addService(const QString &name, QQmlDebugService *serv connect(service, SIGNAL(messagesToClient(QString,QList<QByteArray>)), this, SLOT(sendMessages(QString,QList<QByteArray>))); - connect(service, SIGNAL(attachedToEngine(QQmlEngine*)), - this, SLOT(wakeEngine(QQmlEngine*)), Qt::QueuedConnection); - connect(service, SIGNAL(detachedFromEngine(QQmlEngine*)), - this, SLOT(wakeEngine(QQmlEngine*)), Qt::QueuedConnection); + connect(service, SIGNAL(attachedToEngine(QJSEngine*)), + this, SLOT(wakeEngine(QJSEngine*)), Qt::QueuedConnection); + connect(service, SIGNAL(detachedFromEngine(QJSEngine*)), + this, SLOT(wakeEngine(QJSEngine*)), Qt::QueuedConnection); service->setState(QQmlDebugService::Unavailable); m_plugins.insert(name, service); @@ -589,18 +625,16 @@ bool QQmlDebugServerImpl::removeService(const QString &name) m_plugins.remove(name); service->setState(QQmlDebugService::NotConnected); - disconnect(service, SIGNAL(detachedFromEngine(QQmlEngine*)), - this, SLOT(wakeEngine(QQmlEngine*))); - disconnect(service, SIGNAL(attachedToEngine(QQmlEngine*)), - this, SLOT(wakeEngine(QQmlEngine*))); + disconnect(service, SIGNAL(detachedFromEngine(QJSEngine*)), + this, SLOT(wakeEngine(QJSEngine*))); + disconnect(service, SIGNAL(attachedToEngine(QJSEngine*)), + this, SLOT(wakeEngine(QJSEngine*))); disconnect(service, SIGNAL(messagesToClient(QString,QList<QByteArray>)), this, SLOT(sendMessages(QString,QList<QByteArray>))); disconnect(service, SIGNAL(messageToClient(QString,QByteArray)), this, SLOT(sendMessage(QString,QByteArray))); - m_plugins.remove(service->name()); - return true; } @@ -614,13 +648,9 @@ bool QQmlDebugServerImpl::canSendMessage(const QString &name) void QQmlDebugServerImpl::doSendMessage(const QString &name, const QByteArray &message) { - QByteArray prefixed; - QQmlDebugStream out(&prefixed, QIODevice::WriteOnly); + QQmlDebugPacket out; out << name << message; - - QPacket pack; - pack.writeRawData(prefixed.data(), prefixed.length()); - m_protocol->send(pack); + m_protocol->send(out.data()); } void QQmlDebugServerImpl::sendMessage(const QString &name, const QByteArray &message) @@ -640,7 +670,7 @@ void QQmlDebugServerImpl::sendMessages(const QString &name, const QList<QByteArr } } -void QQmlDebugServerImpl::wakeEngine(QQmlEngine *engine) +void QQmlDebugServerImpl::wakeEngine(QJSEngine *engine) { // to be executed in debugger thread Q_ASSERT(QThread::currentThread() == thread()); diff --git a/src/plugins/qmltooling/qmltooling.pro b/src/plugins/qmltooling/qmltooling.pro index 263e76e016..3728126dd9 100644 --- a/src/plugins/qmltooling/qmltooling.pro +++ b/src/plugins/qmltooling/qmltooling.pro @@ -1,5 +1,9 @@ TEMPLATE = subdirs +# Utilities +SUBDIRS += \ + packetprotocol + # Connectors SUBDIRS += \ qmldbg_native \ @@ -12,4 +16,15 @@ SUBDIRS += \ qmldbg_debugger \ qmldbg_profiler -qtHaveModule(quick): SUBDIRS += qmldbg_inspector +qmldbg_server.depends = packetprotocol +qmldbg_native.depends = packetprotocol +qmldbg_debugger.depends = packetprotocol +qmldbg_profiler.depends = packetprotocol + +qtHaveModule(quick) { + SUBDIRS += \ + qmldbg_inspector \ + qmldbg_quickprofiler + qmldbg_inspector.depends = packetprotocol + qmldbg_quickprofiler.depends = packetprotocol +} diff --git a/src/plugins/qmltooling/shared/qpacketprotocol.cpp b/src/plugins/qmltooling/shared/qpacketprotocol.cpp deleted file mode 100644 index 9a58f803c1..0000000000 --- a/src/plugins/qmltooling/shared/qpacketprotocol.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpacketprotocol.h" - -#include <QtCore/QBuffer> -#include <QtCore/QElapsedTimer> -#include <private/qiodevice_p.h> - -QT_BEGIN_NAMESPACE - -static const unsigned int MAX_PACKET_SIZE = 0x7FFFFFFF; - -/*! - \class QPacketProtocol - \internal - - \brief The QPacketProtocol class encapsulates communicating discrete packets - across fragmented IO channels, such as TCP sockets. - - QPacketProtocol makes it simple to send arbitrary sized data "packets" across - fragmented transports such as TCP and UDP. - - As transmission boundaries are not respected, sending packets over protocols - like TCP frequently involves "stitching" them back together at the receiver. - QPacketProtocol makes this easier by performing this task for you. Packet - data sent using QPacketProtocol is prepended with a 4-byte size header - allowing the receiving QPacketProtocol to buffer the packet internally until - it has all been received. QPacketProtocol does not perform any sanity - checking on the size or on the data, so this class should only be used in - prototyping or trusted situations where DOS attacks are unlikely. - - QPacketProtocol does not perform any communications itself. Instead it can - operate on any QIODevice that supports the QIODevice::readyRead() signal. A - logical "packet" is encapsulated by the companion QPacket class. The - following example shows two ways to send data using QPacketProtocol. The - transmitted data is equivalent in both. - - \code - QTcpSocket socket; - // ... connect socket ... - - QPacketProtocol protocol(&socket); - - // Send packet the quick way - protocol.send() << "Hello world" << 123; - - // Send packet the longer way - QPacket packet; - packet << "Hello world" << 123; - protocol.send(packet); - \endcode - - Likewise, the following shows how to read data from QPacketProtocol, assuming - that the QPacketProtocol::readyRead() signal has been emitted. - - \code - // ... QPacketProtocol::readyRead() is emitted ... - - int a; - QByteArray b; - - // Receive packet the quick way - protocol.read() >> a >> b; - - // Receive packet the longer way - QPacket packet = protocol.read(); - p >> a >> b; - \endcode - - \ingroup io - \sa QPacket -*/ - -class QPacketProtocolPrivate : public QObject -{ - Q_OBJECT -public: - QPacketProtocolPrivate(QPacketProtocol *parent, QIODevice *_dev) - : QObject(parent), inProgressSize(-1), maxPacketSize(MAX_PACKET_SIZE), - waitingForPacket(false), dev(_dev) - { - Q_ASSERT(4 == sizeof(qint32)); - - QObject::connect(this, SIGNAL(readyRead()), - parent, SIGNAL(readyRead())); - QObject::connect(this, SIGNAL(packetWritten()), - parent, SIGNAL(packetWritten())); - QObject::connect(this, SIGNAL(invalidPacket()), - parent, SIGNAL(invalidPacket())); - QObject::connect(dev, SIGNAL(readyRead()), - this, SLOT(readyToRead())); - QObject::connect(dev, SIGNAL(aboutToClose()), - this, SLOT(aboutToClose())); - QObject::connect(dev, SIGNAL(bytesWritten(qint64)), - this, SLOT(bytesWritten(qint64))); - } - -Q_SIGNALS: - void readyRead(); - void packetWritten(); - void invalidPacket(); - -public Q_SLOTS: - void aboutToClose() - { - inProgress.clear(); - sendingPackets.clear(); - inProgressSize = -1; - } - - void bytesWritten(qint64 bytes) - { - Q_ASSERT(!sendingPackets.isEmpty()); - - while (bytes) { - if (sendingPackets.at(0) > bytes) { - sendingPackets[0] -= bytes; - bytes = 0; - } else { - bytes -= sendingPackets.at(0); - sendingPackets.removeFirst(); - emit packetWritten(); - } - } - } - - void readyToRead() - { - while (true) { - // Need to get trailing data - if (-1 == inProgressSize) { - // We need a size header of sizeof(qint32) - if (sizeof(qint32) > (uint)dev->bytesAvailable()) - return; - - // Read size header - int read = dev->read((char *)&inProgressSize, sizeof(qint32)); - Q_ASSERT(read == sizeof(qint32)); - Q_UNUSED(read); - - // Check sizing constraints - if (inProgressSize > maxPacketSize) { - QObject::disconnect(dev, SIGNAL(readyRead()), - this, SLOT(readyToRead())); - QObject::disconnect(dev, SIGNAL(aboutToClose()), - this, SLOT(aboutToClose())); - QObject::disconnect(dev, SIGNAL(bytesWritten(qint64)), - this, SLOT(bytesWritten(qint64))); - dev = 0; - emit invalidPacket(); - return; - } - - inProgressSize -= sizeof(qint32); - } else { - inProgress.append(dev->read(inProgressSize - inProgress.size())); - - if (inProgressSize == inProgress.size()) { - // Packet has arrived! - packets.append(inProgress); - inProgressSize = -1; - inProgress.clear(); - - waitingForPacket = false; - emit readyRead(); - } else - return; - } - } - } - -public: - QList<qint64> sendingPackets; - QList<QByteArray> packets; - QByteArray inProgress; - qint32 inProgressSize; - qint32 maxPacketSize; - bool waitingForPacket; - QIODevice *dev; -}; - -/*! - Construct a QPacketProtocol instance that works on \a dev with the - specified \a parent. - */ -QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent) - : QObject(parent), d(new QPacketProtocolPrivate(this, dev)) -{ - Q_ASSERT(dev); -} - -/*! - Destroys the QPacketProtocol instance. - */ -QPacketProtocol::~QPacketProtocol() -{ -} - -/*! - Returns the maximum packet size allowed. By default this is - 2,147,483,647 bytes. - - If a packet claiming to be larger than the maximum packet size is received, - the QPacketProtocol::invalidPacket() signal is emitted. - - \sa QPacketProtocol::setMaximumPacketSize() - */ -qint32 QPacketProtocol::maximumPacketSize() const -{ - return d->maxPacketSize; -} - -/*! - Sets the maximum allowable packet size to \a max. - - \sa QPacketProtocol::maximumPacketSize() - */ -qint32 QPacketProtocol::setMaximumPacketSize(qint32 max) -{ - if (max > (signed)sizeof(qint32)) - d->maxPacketSize = max; - return d->maxPacketSize; -} - -/*! - Returns a streamable object that is transmitted on destruction. For example - - \code - protocol.send() << "Hello world" << 123; - \endcode - - will send a packet containing "Hello world" and 123. To construct more - complex packets, explicitly construct a QPacket instance. - */ -QPacketAutoSend QPacketProtocol::send() -{ - return QPacketAutoSend(this); -} - -/*! - \fn void QPacketProtocol::send(const QPacket & packet) - - Transmit the \a packet. - */ -void QPacketProtocol::send(const QPacket & p) -{ - if (p.b.isEmpty()) - return; // We don't send empty packets - - qint64 sendSize = p.b.size() + sizeof(qint32); - - d->sendingPackets.append(sendSize); - qint32 sendSize32 = sendSize; - qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32)); - Q_UNUSED(writeBytes); - Q_ASSERT(writeBytes == sizeof(qint32)); - writeBytes = d->dev->write(p.b); - Q_ASSERT(writeBytes == p.b.size()); -} - -/*! - Returns the number of received packets yet to be read. - */ -qint64 QPacketProtocol::packetsAvailable() const -{ - return d->packets.count(); -} - -/*! - Discard any unread packets. - */ -void QPacketProtocol::clear() -{ - d->packets.clear(); -} - -/*! - Return the next unread packet, or an invalid QPacket instance if no packets - are available. This method does NOT block. - */ -QPacket QPacketProtocol::read() -{ - if (0 == d->packets.count()) - return QPacket(); - - QPacket rv(d->packets.at(0)); - d->packets.removeFirst(); - return rv; -} - -/*! - This function locks until a new packet is available for reading and the - \l{QIODevice::}{readyRead()} signal has been emitted. The function - will timeout after \a msecs milliseconds; the default timeout is - 30000 milliseconds. - - The function returns true if the readyRead() signal is emitted and - there is new data available for reading; otherwise it returns false - (if an error occurred or the operation timed out). - */ - -bool QPacketProtocol::waitForReadyRead(int msecs) -{ - if (!d->packets.isEmpty()) - return true; - - QElapsedTimer stopWatch; - stopWatch.start(); - - d->waitingForPacket = true; - do { - if (!d->dev->waitForReadyRead(msecs)) - return false; - if (!d->waitingForPacket) - return true; - msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed()); - } while (true); -} - -/*! - Return the QIODevice passed to the QPacketProtocol constructor. -*/ -QIODevice *QPacketProtocol::device() -{ - return d->dev; -} - -/*! - \fn void QPacketProtocol::readyRead() - - Emitted whenever a new packet is received. Applications may use - QPacketProtocol::read() to retrieve this packet. - */ - -/*! - \fn void QPacketProtocol::invalidPacket() - - A packet larger than the maximum allowable packet size was received. The - packet will be discarded and, as it indicates corruption in the protocol, no - further packets will be received. - */ - -/*! - \fn void QPacketProtocol::packetWritten() - - Emitted each time a packet is completing written to the device. This signal - may be used for communications flow control. - */ - -/*! - \class QPacket - \internal - - \brief The QPacket class encapsulates an unfragmentable packet of data to be - transmitted by QPacketProtocol. - - The QPacket class works together with QPacketProtocol to make it simple to - send arbitrary sized data "packets" across fragmented transports such as TCP - and UDP. - - QPacket provides a QDataStream interface to an unfragmentable packet. - Applications should construct a QPacket, propagate it with data and then - transmit it over a QPacketProtocol instance. For example: - \code - QPacketProtocol protocol(...); - - QPacket myPacket; - myPacket << "Hello world!" << 123; - protocol.send(myPacket); - \endcode - - As long as both ends of the connection are using the QPacketProtocol class, - the data within this packet will be delivered unfragmented at the other end, - ready for extraction. - - \code - QByteArray greeting; - int count; - - QPacket myPacket = protocol.read(); - - myPacket >> greeting >> count; - \endcode - - Only packets returned from QPacketProtocol::read() may be read from. QPacket - instances constructed by directly by applications are for transmission only - and are considered "write only". Attempting to read data from them will - result in undefined behavior. - - \ingroup io - \sa QPacketProtocol - */ - -/*! - Constructs an empty write-only packet. - */ -QPacket::QPacket() - : QDataStream(), buf(0) -{ - buf = new QBuffer(&b); - buf->open(QIODevice::WriteOnly); - setDevice(buf); - setVersion(QDataStream::Qt_4_7); -} - -/*! - Destroys the QPacket instance. - */ -QPacket::~QPacket() -{ - if (buf) { - delete buf; - buf = 0; - } -} - -/*! - Creates a copy of \a other. The initial stream positions are shared, but the - two packets are otherwise independent. - */ -QPacket::QPacket(const QPacket & other) - : QDataStream(), b(other.b), buf(0) -{ - buf = new QBuffer(&b); - buf->open(other.buf->openMode()); - setDevice(buf); -} - -/*! - \internal - */ -QPacket::QPacket(const QByteArray & ba) - : QDataStream(), b(ba), buf(0) -{ - buf = new QBuffer(&b); - buf->open(QIODevice::ReadOnly); - setDevice(buf); -} - -/*! - Returns true if this packet is empty - that is, contains no data. - */ -bool QPacket::isEmpty() const -{ - return b.isEmpty(); -} - -/*! - Returns raw packet data. - */ -QByteArray QPacket::data() const -{ - return b; -} - -/*! - Clears data in the packet. This is useful for reusing one writable packet. - For example - \code - QPacketProtocol protocol(...); - - QPacket packet; - - packet << "Hello world!" << 123; - protocol.send(packet); - - packet.clear(); - packet << "Goodbyte world!" << 789; - protocol.send(packet); - \endcode - */ -void QPacket::clear() -{ - QBuffer::OpenMode oldMode = buf->openMode(); - buf->close(); - b.clear(); - buf->setBuffer(&b); // reset QBuffer internals with new size of b. - buf->open(oldMode); -} - -/*! - \class QPacketAutoSend - \internal - - \internal - */ -QPacketAutoSend::QPacketAutoSend(QPacketProtocol *_p) - : QPacket(), p(_p) -{ -} - -QPacketAutoSend::~QPacketAutoSend() -{ - if (!b.isEmpty()) - p->send(*this); -} - -QT_END_NAMESPACE - -#include <qpacketprotocol.moc> diff --git a/src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h b/src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h index 9aa4531428..52021379bc 100644 --- a/src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h +++ b/src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h @@ -66,7 +66,7 @@ protected: { QMutexLocker lock(&m_configMutex); m_waitingForConfiguration = false; - foreach (QQmlEngine *engine, m_waitingEngines) + foreach (QJSEngine *engine, m_waitingEngines) emit Base::attachedToEngine(engine); m_waitingEngines.clear(); } @@ -79,7 +79,7 @@ protected: QQmlDebugConnector::instance()->blockingMode()); } - void stateChanged(QQmlDebugService::State newState) + void stateChanged(QQmlDebugService::State newState) Q_DECL_OVERRIDE { if (newState != QQmlDebugService::Enabled) stopWaiting(); @@ -87,7 +87,7 @@ protected: init(); } - void engineAboutToBeAdded(QQmlEngine *engine) + void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE { QMutexLocker lock(&m_configMutex); if (m_waitingForConfiguration) @@ -97,7 +97,7 @@ protected: } QMutex m_configMutex; - QList<QQmlEngine *> m_waitingEngines; + QList<QJSEngine *> m_waitingEngines; bool m_waitingForConfiguration; }; diff --git a/src/plugins/qmltooling/shared/qqmldebugpacket.h b/src/plugins/qmltooling/shared/qqmldebugpacket.h new file mode 100644 index 0000000000..459937f411 --- /dev/null +++ b/src/plugins/qmltooling/shared/qqmldebugpacket.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLDEBUGPACKET_P_H +#define QQMLDEBUGPACKET_P_H + +#include <QtCore/qbuffer.h> +#include <QtQml/private/qqmldebugconnector_p.h> +#include <QtPacketProtocol/private/qpacket_p.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +// QPacket with a fixed data stream version, centrally set by QQmlDebugServer +class QQmlDebugPacket : public QPacket +{ +public: + QQmlDebugPacket() : QPacket(QQmlDebugConnector::dataStreamVersion()) {} + QQmlDebugPacket(const QByteArray &ba) : QPacket(QQmlDebugConnector::dataStreamVersion(), ba) {} +}; + +QT_END_NAMESPACE + +#endif // QQMLDEBUGPACKET_P_H diff --git a/src/plugins/qmltooling/shared/qqmldebugserver.h b/src/plugins/qmltooling/shared/qqmldebugserver.h index a7c17075d9..3807f12214 100644 --- a/src/plugins/qmltooling/shared/qqmldebugserver.h +++ b/src/plugins/qmltooling/shared/qqmldebugserver.h @@ -37,6 +37,8 @@ #include <private/qqmldebugconnector_p.h> #include <private/qtqmlglobal_p.h> +#include <QtCore/QIODevice> + // // W A R N I N G // ------------- diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h index bfd1561d3d..c723224985 100644 --- a/src/qml/debugger/qqmlabstractprofileradapter_p.h +++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h @@ -58,9 +58,10 @@ class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapter : public QObject, public Q_OBJECT public: - QQmlAbstractProfilerAdapter(QQmlProfilerService *service) : - service(service), waiting(true), featuresEnabled(0) {} + QQmlAbstractProfilerAdapter(QObject *parent = 0) : + QObject(parent), service(0), waiting(true), featuresEnabled(0) {} virtual ~QQmlAbstractProfilerAdapter() {} + void setService(QQmlProfilerService *new_service) { service = new_service; } virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages) = 0; @@ -96,6 +97,15 @@ private: quint64 featuresEnabled; }; +class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapterFactory : public QObject +{ + Q_OBJECT +public: + virtual QQmlAbstractProfilerAdapter *create(const QString &key) = 0; +}; + +#define QQmlAbstractProfilerAdapterFactory_iid "org.qt-project.Qt.QQmlAbstractProfilerAdapterFactory" + QT_END_NAMESPACE #endif // QQMLABSTRACTPROFILERADAPTER_P_H diff --git a/src/qml/debugger/qqmldebug.cpp b/src/qml/debugger/qqmldebug.cpp index 35dc110e9a..b308f5aa29 100644 --- a/src/qml/debugger/qqmldebug.cpp +++ b/src/qml/debugger/qqmldebug.cpp @@ -33,6 +33,7 @@ #include "qqmldebug.h" #include "qqmldebugconnector_p.h" +#include "qqmldebugserviceinterfaces_p.h" #include <private/qqmlengine_p.h> @@ -52,10 +53,64 @@ QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning) } /*! + * Retrieves the plugin keys of the debugger services provided by default. The debugger services + * enable a debug client to use a Qml/JavaScript debugger, in order to set breakpoints, pause + * execution, evaluate expressions and similar debugging tasks. + * \return List of plugin keys of default debugger services. + */ +QStringList QQmlDebuggingEnabler::debuggerServices() +{ + return QStringList() << QV4DebugService::s_key << QQmlEngineDebugService::s_key + << QDebugMessageService::s_key; +} + +/*! + * Retrieves the plugin keys of the inspector services provided by default. The inspector services + * enable a debug client to use a visual inspector tool for Qt Quick. + * \return List of plugin keys of default inspector services. + */ +QStringList QQmlDebuggingEnabler::inspectorServices() +{ + return QStringList() << QQmlInspectorService::s_key; +} + +/*! + * Retrieves the names of the profiler services provided by default. The profiler services enable a + * debug client to use a profiler and track the time taken by various QML and JavaScript constructs, + * as well as the QtQuick SceneGraph. + * \return List of plugin keys of default profiler services. + */ +QStringList QQmlDebuggingEnabler::profilerServices() +{ + return QStringList() << QQmlProfilerService::s_key << QQmlEngineControlService::s_key; +} + +/*! + * Restricts the services available from the debug connector. The connector will scan plugins in the + * "qmltooling" subdirectory of the default plugin path. If this function is not called before the + * debug connector is enabled, all services found that way will be available to any client. If this + * function is called, only the services with plugin keys given in \a services will be available. + * + * Use this method to disable debugger and inspector services when profiling to get better + * performance and more realistic profiles. The debugger service will put any JavaScript engine it + * connects to into interpreted mode, disabling the JIT compiler. + * + * \sa debuggerServices(), profilerServices(), inspectorServices() + */ +void QQmlDebuggingEnabler::setServices(const QStringList &services) +{ +#ifndef QQML_NO_DEBUG_PROTOCOL + QQmlDebugConnector::setServices(services); +#else + Q_UNUSED(services); +#endif +} + +/*! * \enum QQmlDebuggingEnabler::StartMode * - * Defines the debug server's start behavior. You can interrupt QML engines starting while a debug - * client is connecting, in order to set breakpoints in or profile startup code. + * Defines the debug connector's start behavior. You can interrupt QML engines starting while a + * debug client is connecting, in order to set breakpoints in or profile startup code. * * \value DoNotWaitForClient Run any QML engines as usual while the debug services are connecting. * \value WaitForClient If a QML engine starts while the debug services are connecting, @@ -63,13 +118,13 @@ QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning) */ /*! - * Enables debugging for QML engines created after calling this function. The debug server will + * Enables debugging for QML engines created after calling this function. The debug connector will * listen on \a port at \a hostName and block the QML engine until it receives a connection if * \a mode is \c WaitForClient. If \a mode is not specified it won't block and if \a hostName is not - * specified it will listen on all available interfaces. You can only start one debug server at a - * time. A debug server may have already been started if the -qmljsdebugger= command line argument - * was given. This method returns \c true if a new debug server was successfully started, or - * \c false otherwise. + * specified it will listen on all available interfaces. You can only start one debug connector at a + * time. A debug connector may have already been started if the -qmljsdebugger= command line + * argument was given. This method returns \c true if a new debug connector was successfully + * started, or \c false otherwise. */ bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const QString &hostName) { @@ -85,7 +140,7 @@ bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const Q } #else Q_UNUSED(port); - Q_UNUSED(block); + Q_UNUSED(mode); Q_UNUSED(hostName); #endif return false; @@ -94,12 +149,12 @@ bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const Q /*! * \since 5.6 * - * Enables debugging for QML engines created after calling this function. The debug server will + * Enables debugging for QML engines created after calling this function. The debug connector will * connect to a debugger waiting on a local socket at the given \a socketFileName and block the QML * engine until the connection is established if \a mode is \c WaitForClient. If \a mode is not - * specified it will not block. You can only start one debug server at a time. A debug server may - * have already been started if the -qmljsdebugger= command line argument was given. This method - * returns \c true if a new debug server was successfully started, or \c false otherwise. + * specified it will not block. You can only start one debug connector at a time. A debug connector + * may have already been started if the -qmljsdebugger= command line argument was given. This method + * returns \c true if a new debug connector was successfully started, or \c false otherwise. */ bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName, StartMode mode) { @@ -114,7 +169,7 @@ bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName, } #else Q_UNUSED(fileName); - Q_UNUSED(block); + Q_UNUSED(mode); #endif return false; } diff --git a/src/qml/debugger/qqmldebug.h b/src/qml/debugger/qqmldebug.h index 5d65982a49..6316ebd195 100644 --- a/src/qml/debugger/qqmldebug.h +++ b/src/qml/debugger/qqmldebug.h @@ -48,6 +48,13 @@ struct Q_QML_EXPORT QQmlDebuggingEnabler }; QQmlDebuggingEnabler(bool printWarning = true); + + static QStringList debuggerServices(); + static QStringList inspectorServices(); + static QStringList profilerServices(); + + static void setServices(const QStringList &services); + static bool startTcpDebugServer(int port, StartMode mode = DoNotWaitForClient, const QString &hostName = QString()); static bool connectToLocalDebugger(const QString &socketFileName, diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp index 64a8a49bb9..7d9f462fe2 100644 --- a/src/qml/debugger/qqmldebugconnector.cpp +++ b/src/qml/debugger/qqmldebugconnector.cpp @@ -39,6 +39,7 @@ #include <QtCore/QDir> #include <QtCore/QDebug> #include <QtCore/QJsonArray> +#include <QtCore/QDataStream> #include <private/qcoreapplication_p.h> #include <private/qqmlengine_p.h> @@ -56,6 +57,8 @@ Q_QML_IMPORT_DEBUG_PLUGIN(QQmlInspectorServiceFactory) Q_QML_IMPORT_DEBUG_PLUGIN(QQmlProfilerServiceFactory) Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebuggerServiceFactory) +int QQmlDebugConnector::s_dataStreamVersion = QDataStream::Qt_4_7; + struct QQmlDebugConnectorParams { QString pluginKey; QStringList services; diff --git a/src/qml/debugger/qqmldebugconnector_p.h b/src/qml/debugger/qqmldebugconnector_p.h index f5f5a87b56..1e7d01e431 100644 --- a/src/qml/debugger/qqmldebugconnector_p.h +++ b/src/qml/debugger/qqmldebugconnector_p.h @@ -35,6 +35,7 @@ #define QQMLDEBUGCONNECTOR_H #include <QtQml/qtqmlglobal.h> +#include <QtQml/qjsengine.h> #include <QtCore/QVariantList> #include <private/qqmldebugservice_p.h> @@ -60,13 +61,17 @@ public: static void setPluginKey(const QString &key); static void setServices(const QStringList &services); static QQmlDebugConnector *instance(); + static int dataStreamVersion() + { + return s_dataStreamVersion; + } virtual bool blockingMode() const = 0; virtual QQmlDebugService *service(const QString &name) const = 0; - virtual void addEngine(QQmlEngine *engine) = 0; - virtual void removeEngine(QQmlEngine *engine) = 0; + virtual void addEngine(QJSEngine *engine) = 0; + virtual void removeEngine(QJSEngine *engine) = 0; virtual bool addService(const QString &name, QQmlDebugService *service) = 0; virtual bool removeService(const QString &name) = 0; @@ -82,6 +87,7 @@ public: protected: static QString commandLineArguments(); + static int s_dataStreamVersion; }; class Q_QML_PRIVATE_EXPORT QQmlDebugConnectorFactory : public QObject { diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp index 0b07f320ec..f46a924d5e 100644 --- a/src/qml/debugger/qqmldebugservice.cpp +++ b/src/qml/debugger/qqmldebugservice.cpp @@ -182,50 +182,24 @@ void QQmlDebugService::messageReceived(const QByteArray &) { } -void QQmlDebugService::engineAboutToBeAdded(QQmlEngine *engine) +void QQmlDebugService::engineAboutToBeAdded(QJSEngine *engine) { emit attachedToEngine(engine); } -void QQmlDebugService::engineAboutToBeRemoved(QQmlEngine *engine) +void QQmlDebugService::engineAboutToBeRemoved(QJSEngine *engine) { emit detachedFromEngine(engine); } -void QQmlDebugService::engineAdded(QQmlEngine *) +void QQmlDebugService::engineAdded(QJSEngine *) { } -void QQmlDebugService::engineRemoved(QQmlEngine *) +void QQmlDebugService::engineRemoved(QJSEngine *) { } -int QQmlDebugStream::s_dataStreamVersion = QDataStream::Qt_4_7; - -QQmlDebugStream::QQmlDebugStream() - : QDataStream() -{ - setVersion(s_dataStreamVersion); -} - -QQmlDebugStream::QQmlDebugStream(QIODevice *d) - : QDataStream(d) -{ - setVersion(s_dataStreamVersion); -} - -QQmlDebugStream::QQmlDebugStream(QByteArray *ba, QIODevice::OpenMode flags) - : QDataStream(ba, flags) -{ - setVersion(s_dataStreamVersion); -} - -QQmlDebugStream::QQmlDebugStream(const QByteArray &ba) - : QDataStream(ba) -{ - setVersion(s_dataStreamVersion); -} - QT_END_NAMESPACE #include "qqmldebugservice.moc" diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h index 3d692133cc..0fcf5459ef 100644 --- a/src/qml/debugger/qqmldebugservice_p.h +++ b/src/qml/debugger/qqmldebugservice_p.h @@ -35,7 +35,6 @@ #define QQMLDEBUGSERVICE_H #include <QtCore/qobject.h> -#include <QtCore/qdatastream.h> #include <QtCore/qhash.h> #include <private/qtqmlglobal_p.h> @@ -53,7 +52,7 @@ QT_BEGIN_NAMESPACE -class QQmlEngine; +class QJSEngine; class QQmlDebugServicePrivate; class Q_QML_PRIVATE_EXPORT QQmlDebugService : public QObject @@ -76,10 +75,10 @@ public: virtual void stateChanged(State); virtual void messageReceived(const QByteArray &); - virtual void engineAboutToBeAdded(QQmlEngine *); - virtual void engineAboutToBeRemoved(QQmlEngine *); - virtual void engineAdded(QQmlEngine *); - virtual void engineRemoved(QQmlEngine *); + virtual void engineAboutToBeAdded(QJSEngine *); + virtual void engineAboutToBeRemoved(QJSEngine *); + virtual void engineAdded(QJSEngine *); + virtual void engineRemoved(QJSEngine *); static const QHash<int, QObject *> &objectsForIds(); static int idForObject(QObject *); @@ -89,24 +88,13 @@ protected: explicit QQmlDebugService(const QString &, float version, QObject *parent = 0); signals: - void attachedToEngine(QQmlEngine *); - void detachedFromEngine(QQmlEngine *); + void attachedToEngine(QJSEngine *); + void detachedFromEngine(QJSEngine *); void messageToClient(const QString &name, const QByteArray &message); void messagesToClient(const QString &name, const QList<QByteArray> &messages); }; -class Q_QML_PRIVATE_EXPORT QQmlDebugStream : public QDataStream -{ -public: - static int s_dataStreamVersion; - - QQmlDebugStream(); - explicit QQmlDebugStream(QIODevice *d); - QQmlDebugStream(QByteArray *ba, QIODevice::OpenMode flags); - QQmlDebugStream(const QByteArray &ba); -}; - QT_END_NAMESPACE #endif // QQMLDEBUGSERVICE_H diff --git a/src/qml/debugger/qqmldebugserviceinterfaces.cpp b/src/qml/debugger/qqmldebugserviceinterfaces.cpp index 199c682748..e0968b2656 100644 --- a/src/qml/debugger/qqmldebugserviceinterfaces.cpp +++ b/src/qml/debugger/qqmldebugserviceinterfaces.cpp @@ -39,6 +39,8 @@ const QString QV4DebugService::s_key = QStringLiteral("V8Debugger"); const QString QQmlEngineDebugService::s_key = QStringLiteral("QmlDebugger"); const QString QQmlInspectorService::s_key = QStringLiteral("QmlInspector"); const QString QQmlProfilerService::s_key = QStringLiteral("CanvasFrameRate"); +const QString QDebugMessageService::s_key = QStringLiteral("DebugMessages"); +const QString QQmlEngineControlService::s_key = QStringLiteral("EngineControl"); const QString QQmlNativeDebugService::s_key = QStringLiteral("NativeQmlDebugger"); QT_END_NAMESPACE diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h index 6391bc6218..1b45392680 100644 --- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h +++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h @@ -60,6 +60,8 @@ class Q_QML_PRIVATE_EXPORT QV4DebugService : protected QQmlDebugService { Q_OBJECT public: + static const QString s_key; + virtual void signalEmitted(const QString &signal) = 0; protected: @@ -67,20 +69,20 @@ protected: QV4DebugService(float version, QObject *parent = 0) : QQmlDebugService(s_key, version, parent) {} - - static const QString s_key; }; class Q_QML_PRIVATE_EXPORT QQmlProfilerService : protected QQmlDebugService { Q_OBJECT public: + static const QString s_key; + virtual void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) = 0; virtual void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) = 0; - virtual void startProfiling(QQmlEngine *engine, + virtual void startProfiling(QJSEngine *engine, quint64 features = std::numeric_limits<quint64>::max()) = 0; - virtual void stopProfiling(QQmlEngine *engine) = 0; + virtual void stopProfiling(QJSEngine *engine) = 0; virtual void dataReady(QQmlAbstractProfilerAdapter *profiler) = 0; @@ -89,15 +91,15 @@ protected: QQmlProfilerService(float version, QObject *parent = 0) : QQmlDebugService(s_key, version, parent) {} - - static const QString s_key; }; class Q_QML_PRIVATE_EXPORT QQmlEngineDebugService : protected QQmlDebugService { Q_OBJECT public: - virtual void objectCreated(QQmlEngine *engine, QObject *object) = 0; + static const QString s_key; + + virtual void objectCreated(QJSEngine *engine, QObject *object) = 0; virtual void setStatesDelegate(QQmlDebugStatesDelegate *) = 0; protected: @@ -107,14 +109,14 @@ protected: QQmlDebugService(s_key, version, parent) {} QQmlBoundSignal *nextSignal(QQmlBoundSignal *prev) { return prev->m_nextSignal; } - - static const QString s_key; }; class Q_QML_PRIVATE_EXPORT QQmlInspectorService : protected QQmlDebugService { Q_OBJECT public: + static const QString s_key; + virtual void addView(QObject *) = 0; virtual void removeView(QObject *) = 0; @@ -123,8 +125,35 @@ protected: QQmlInspectorService(float version, QObject *parent = 0) : QQmlDebugService(s_key, version, parent) {} +}; + +class Q_QML_PRIVATE_EXPORT QDebugMessageService : protected QQmlDebugService +{ + Q_OBJECT +public: + static const QString s_key; + + virtual void synchronizeTime(const QElapsedTimer &otherTimer) = 0; + +protected: + friend class QQmlDebugConnector; + + QDebugMessageService(float version, QObject *parent = 0) : + QQmlDebugService(s_key, version, parent) {} +}; +class Q_QML_PRIVATE_EXPORT QQmlEngineControlService : protected QQmlDebugService +{ + Q_OBJECT +public: static const QString s_key; + +protected: + friend class QQmlDebugConnector; + + QQmlEngineControlService(float version, QObject *parent = 0) : + QQmlDebugService(s_key, version, parent) {} + }; class Q_QML_PRIVATE_EXPORT QQmlNativeDebugService : protected QQmlDebugService diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h index 1213b67b3c..ce708132f8 100644 --- a/src/qml/debugger/qqmlprofilerdefinitions_p.h +++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h @@ -89,9 +89,6 @@ struct QQmlProfilerDefinitions { enum BindingType { QmlBinding, - V8Binding, - V4Binding, - MaximumBindingType }; @@ -126,8 +123,8 @@ struct QQmlProfilerDefinitions { typedef QV4::Profiling::MemoryType MemoryType; enum ProfileFeature { - ProfileJavaScript = QV4::Profiling::FeatureFunctionCall, - ProfileMemory = QV4::Profiling::FeatureMemoryAllocation, + ProfileJavaScript, + ProfileMemory, ProfilePixmapCache, ProfileSceneGraph, ProfileAnimations, @@ -137,9 +134,25 @@ struct QQmlProfilerDefinitions { ProfileBinding, ProfileHandlingSignal, ProfileInputEvents, + ProfileDebugMessages, MaximumProfileFeature }; + + enum InputEventType { + InputKeyPress, + InputKeyRelease, + InputKeyUnknown, + + InputMousePress, + InputMouseRelease, + InputMouseMove, + InputMouseDoubleClick, + InputMouseWheel, + InputMouseUnknown, + + MaximumInputEventType + }; }; QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index 7706a40da6..b04bcd33e7 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -51,290 +51,4 @@ QT_BEGIN_NAMESPACE -using namespace QV4; -using namespace QV4::Debugging; - -V4Debugger::JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, - const QString &script) - : engine(engine) - , frameNr(frameNr) - , script(script) - , resultIsException(false) -{} - -void V4Debugger::JavaScriptJob::run() -{ - Scope scope(engine); - - ExecutionContextSaver saver(scope); - - ExecutionContext *ctx = engine->currentContext; - if (frameNr > 0) { - for (int i = 0; i < frameNr; ++i) { - ctx = engine->parentContext(ctx); - } - engine->pushContext(ctx); - } - - QV4::Script script(ctx, this->script); - script.strictMode = ctx->d()->strictMode; - // In order for property lookups in QML to work, we need to disable fast v4 lookups. That - // is a side-effect of inheritContext. - script.inheritContext = true; - script.parse(); - QV4::ScopedValue result(scope); - if (!scope.engine->hasException) - result = script.run(); - if (scope.engine->hasException) { - result = scope.engine->catchException(); - resultIsException = true; - } - handleResult(result); -} - -bool V4Debugger::JavaScriptJob::hasExeption() const -{ - return resultIsException; -} - -class EvalJob: public V4Debugger::JavaScriptJob -{ - bool result; - -public: - EvalJob(QV4::ExecutionEngine *engine, const QString &script) - : V4Debugger::JavaScriptJob(engine, /*frameNr*/-1, script) - , result(false) - {} - - virtual void handleResult(QV4::ScopedValue &result) - { - this->result = result->toBoolean(); - } - - bool resultAsBoolean() const - { - return result; - } -}; - -V4Debugger::V4Debugger(QV4::ExecutionEngine *engine) - : m_engine(engine) - , m_state(Running) - , m_stepping(NotStepping) - , m_pauseRequested(false) - , m_haveBreakPoints(false) - , m_breakOnThrow(false) - , m_returnedValue(engine, Primitive::undefinedValue()) - , m_gatherSources(0) - , m_runningJob(0) -{ - qMetaTypeId<V4Debugger*>(); - qMetaTypeId<PauseReason>(); -} - -void V4Debugger::pause() -{ - QMutexLocker locker(&m_lock); - if (m_state == Paused) - return; - m_pauseRequested = true; -} - -void V4Debugger::resume(Speed speed) -{ - QMutexLocker locker(&m_lock); - if (m_state != Paused) - return; - - if (!m_returnedValue.isUndefined()) - m_returnedValue.set(m_engine, Encode::undefined()); - - m_currentContext.set(m_engine, *m_engine->currentContext); - m_stepping = speed; - m_runningCondition.wakeAll(); -} - -void V4Debugger::addBreakPoint(const QString &fileName, int lineNumber, const QString &condition) -{ - QMutexLocker locker(&m_lock); - m_breakPoints.insert(DebuggerBreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), lineNumber), condition); - m_haveBreakPoints = true; -} - -void V4Debugger::removeBreakPoint(const QString &fileName, int lineNumber) -{ - QMutexLocker locker(&m_lock); - m_breakPoints.remove(DebuggerBreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), lineNumber)); - m_haveBreakPoints = !m_breakPoints.isEmpty(); -} - -void V4Debugger::setBreakOnThrow(bool onoff) -{ - QMutexLocker locker(&m_lock); - - m_breakOnThrow = onoff; -} - -V4Debugger::ExecutionState V4Debugger::currentExecutionState() const -{ - ExecutionState state; - state.fileName = getFunction()->sourceFile(); - state.lineNumber = engine()->current->lineNumber; - - return state; -} - -QVector<StackFrame> V4Debugger::stackTrace(int frameLimit) const -{ - return m_engine->stackTrace(frameLimit); -} - -void V4Debugger::maybeBreakAtInstruction() -{ - if (m_runningJob) // do not re-enter when we're doing a job for the debugger. - return; - - QMutexLocker locker(&m_lock); - - if (m_gatherSources) { - m_gatherSources->run(); - delete m_gatherSources; - m_gatherSources = 0; - } - - switch (m_stepping) { - case StepOver: - if (m_currentContext.asManaged()->d() != m_engine->current) - break; - // fall through - case StepIn: - pauseAndWait(Step); - return; - case StepOut: - case NotStepping: - break; - } - - if (m_pauseRequested) { // Serve debugging requests from the agent - m_pauseRequested = false; - pauseAndWait(PauseRequest); - } else if (m_haveBreakPoints) { - if (Function *f = getFunction()) { - const int lineNumber = engine()->current->lineNumber; - if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber)) - pauseAndWait(BreakPoint); - } - } -} - -void V4Debugger::enteringFunction() -{ - if (m_runningJob) - return; - QMutexLocker locker(&m_lock); - - if (m_stepping == StepIn) { - m_currentContext.set(m_engine, *m_engine->currentContext); - } -} - -void V4Debugger::leavingFunction(const ReturnedValue &retVal) -{ - if (m_runningJob) - return; - Q_UNUSED(retVal); // TODO - - QMutexLocker locker(&m_lock); - - if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->current) { - m_currentContext.set(m_engine, *m_engine->parentContext(m_engine->currentContext)); - m_stepping = StepOver; - m_returnedValue.set(m_engine, retVal); - } -} - -void V4Debugger::aboutToThrow() -{ - if (!m_breakOnThrow) - return; - - if (m_runningJob) // do not re-enter when we're doing a job for the debugger. - return; - - QMutexLocker locker(&m_lock); - pauseAndWait(Throwing); -} - -Function *V4Debugger::getFunction() const -{ - Scope scope(m_engine); - ExecutionContext *context = m_engine->currentContext; - ScopedFunctionObject function(scope, context->getFunctionObject()); - if (function) - return function->function(); - else - return context->d()->engine->globalCode; -} - -void V4Debugger::pauseAndWait(PauseReason reason) -{ - if (m_runningJob) - return; - - m_state = Paused; - emit debuggerPaused(this, reason); - - while (true) { - m_runningCondition.wait(&m_lock); - if (m_runningJob) { - m_runningJob->run(); - m_jobIsRunning.wakeAll(); - } else { - break; - } - } - - m_state = Running; -} - -bool V4Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr) -{ - BreakPoints::iterator it = m_breakPoints.find(DebuggerBreakPoint(filename.mid(filename.lastIndexOf('/') + 1), linenr)); - if (it == m_breakPoints.end()) - return false; - QString condition = it.value(); - if (condition.isEmpty()) - return true; - - Q_ASSERT(m_runningJob == 0); - EvalJob evilJob(m_engine, condition); - m_runningJob = &evilJob; - m_runningJob->run(); - m_runningJob = 0; - - return evilJob.resultAsBoolean(); -} - -void V4Debugger::runInEngine(V4Debugger::Job *job) -{ - QMutexLocker locker(&m_lock); - runInEngine_havingLock(job); -} - -void V4Debugger::runInEngine_havingLock(V4Debugger::Job *job) -{ - Q_ASSERT(job); - Q_ASSERT(m_runningJob == 0); - - m_runningJob = job; - m_runningCondition.wakeAll(); - m_jobIsRunning.wait(&m_lock); - m_runningJob = 0; -} - -V4Debugger::Job::~Job() -{ -} - QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h index fdc9cac24f..3a3ecef918 100644 --- a/src/qml/jsruntime/qv4debugging_p.h +++ b/src/qml/jsruntime/qv4debugging_p.h @@ -31,8 +31,8 @@ ** ****************************************************************************/ -#ifndef DEBUGGING_H -#define DEBUGGING_H +#ifndef QV4DEBUGGING_H +#define QV4DEBUGGING_H // // W A R N I N G @@ -46,50 +46,13 @@ // #include "qv4global_p.h" -#include "qv4engine_p.h" -#include "qv4context_p.h" -#include "qv4scopedvalue_p.h" - -#include <QHash> -#include <QThread> -#include <QMutex> -#include <QWaitCondition> - -#include <QtCore/QJsonObject> +#include <QtCore/qobject.h> QT_BEGIN_NAMESPACE namespace QV4 { - -struct Function; - namespace Debugging { -enum PauseReason { - PauseRequest, - BreakPoint, - Throwing, - Step -}; - -struct DebuggerBreakPoint { - DebuggerBreakPoint(const QString &fileName, int line) - : fileName(fileName), lineNumber(line) - {} - QString fileName; - int lineNumber; -}; -inline uint qHash(const DebuggerBreakPoint &b, uint seed = 0) Q_DECL_NOTHROW -{ - return qHash(b.fileName, seed) ^ b.lineNumber; -} -inline bool operator==(const DebuggerBreakPoint &a, const DebuggerBreakPoint &b) -{ - return a.lineNumber == b.lineNumber && a.fileName == b.fileName; -} - -typedef QHash<DebuggerBreakPoint, QString> BreakPoints; - class Q_QML_EXPORT Debugger : public QObject { Q_OBJECT @@ -103,123 +66,9 @@ public: virtual void aboutToThrow() = 0; }; -class Q_QML_EXPORT V4Debugger : public Debugger -{ - Q_OBJECT -public: - class Q_QML_EXPORT Job - { - public: - virtual ~Job() = 0; - virtual void run() = 0; - }; - - class Q_QML_EXPORT JavaScriptJob: public Job - { - QV4::ExecutionEngine *engine; - int frameNr; - const QString &script; - bool resultIsException; - - public: - JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, const QString &script); - void run(); - bool hasExeption() const; - - protected: - virtual void handleResult(QV4::ScopedValue &result) = 0; - }; - - enum State { - Running, - Paused - }; - - enum Speed { - FullThrottle = 0, - StepOut, - StepOver, - StepIn, - - NotStepping = FullThrottle - }; - - V4Debugger(ExecutionEngine *engine); - - ExecutionEngine *engine() const - { return m_engine; } - - void pause(); - void resume(Speed speed); - - State state() const { return m_state; } - - void addBreakPoint(const QString &fileName, int lineNumber, const QString &condition = QString()); - void removeBreakPoint(const QString &fileName, int lineNumber); - - void setBreakOnThrow(bool onoff); - - // used for testing - struct ExecutionState - { - QString fileName; - int lineNumber; - }; - ExecutionState currentExecutionState() const; - - bool pauseAtNextOpportunity() const { - return m_pauseRequested || m_haveBreakPoints || m_gatherSources || m_stepping >= StepOver; - } - - QVector<StackFrame> stackTrace(int frameLimit = -1) const; - QVector<Heap::ExecutionContext::ContextType> getScopeTypes(int frame = 0) const; - - Function *getFunction() const; - void runInEngine(Job *job); - -public: // compile-time interface - void maybeBreakAtInstruction(); - -public: // execution hooks - void enteringFunction(); - void leavingFunction(const ReturnedValue &retVal); - void aboutToThrow(); - -signals: - void sourcesCollected(QV4::Debugging::V4Debugger *self, const QStringList &sources, int seq); - void debuggerPaused(QV4::Debugging::V4Debugger *self, QV4::Debugging::PauseReason reason); - -private: - // requires lock to be held - void pauseAndWait(PauseReason reason); - bool reallyHitTheBreakPoint(const QString &filename, int linenr); - void runInEngine_havingLock(V4Debugger::Job *job); - -private: - QV4::ExecutionEngine *m_engine; - QV4::PersistentValue m_currentContext; - QMutex m_lock; - QWaitCondition m_runningCondition; - State m_state; - Speed m_stepping; - bool m_pauseRequested; - bool m_haveBreakPoints; - bool m_breakOnThrow; - - BreakPoints m_breakPoints; - QV4::PersistentValue m_returnedValue; - - Job *m_gatherSources; - Job *m_runningJob; - QWaitCondition m_jobIsRunning; -}; - } // namespace Debugging } // namespace QV4 QT_END_NAMESPACE -Q_DECLARE_METATYPE(QV4::Debugging::Debugger*) -Q_DECLARE_METATYPE(QV4::Debugging::PauseReason) - -#endif // DEBUGGING_H +#endif // QV4DEBUGGING_H diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index 110a2c9089..b4733356ac 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -302,7 +302,7 @@ static QString decode(const QString &input, DecodeMode decodeMode, bool *ok) ++r; } if (*r) - output.append(input.mid(start, i - start + 1)); + output.append(input.midRef(start, i - start + 1)); else output.append(QChar(b)); } else { diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 8f471132b7..ee294b3678 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -1447,7 +1447,8 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const const QQmlPropertyData *candidate = &data; while (candidate) { error += QLatin1String("\n ") + - QString::fromUtf8(object.metaObject()->method(candidate->coreIndex).methodSignature().constData()); + QString::fromUtf8(object.metaObject()->method(candidate->coreIndex) + .methodSignature()); candidate = RelatedMethod(object, candidate, dummy, propertyCache); } diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 477a517e32..decffaf2fa 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -250,7 +250,7 @@ QQmlBoundSignal::QQmlBoundSignal(QObject *target, int signal, QObject *owner, QQmlEngine *engine) : QQmlNotifierEndpoint(QQmlNotifierEndpoint::QQmlBoundSignal), m_prevSignal(0), m_nextSignal(0), - m_expression(0) + m_enabled(true), m_expression(0) { addToObject(owner); @@ -313,18 +313,33 @@ void QQmlBoundSignal::takeExpression(QQmlBoundSignalExpression *e) m_expression->setNotifyOnValueChanged(false); } +/*! + This property holds whether the item will emit signals. + + The QQmlBoundSignal callback will only emit a signal if this property is set to true. + + By default, this property is true. + */ +void QQmlBoundSignal::setEnabled(bool enabled) +{ + if (m_enabled == enabled) + return; + + m_enabled = enabled; +} + void QQmlBoundSignal_callback(QQmlNotifierEndpoint *e, void **a) { QQmlBoundSignal *s = static_cast<QQmlBoundSignal*>(e); - if (!s->m_expression) + if (!s->m_expression || !s->m_enabled) return; QV4DebugService *service = QQmlDebugConnector::service<QV4DebugService>(); if (service) - service->signalEmitted(QString::fromLatin1(QMetaObjectPrivate::signal( - s->m_expression->target()->metaObject(), - s->signalIndex()).methodSignature())); + service->signalEmitted(QString::fromUtf8(QMetaObjectPrivate::signal( + s->m_expression->target()->metaObject(), + s->signalIndex()).methodSignature())); QQmlEngine *engine; if (s->m_expression && (engine = s->m_expression->engine())) { diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h index 3742317484..ef8fdd4a1a 100644 --- a/src/qml/qml/qqmlboundsignal_p.h +++ b/src/qml/qml/qqmlboundsignal_p.h @@ -108,6 +108,8 @@ public: QQmlBoundSignalExpression *expression() const; void takeExpression(QQmlBoundSignalExpression *); + void setEnabled(bool enabled); + private: friend void QQmlBoundSignal_callback(QQmlNotifierEndpoint *, void **); friend class QQmlPropertyPrivate; @@ -119,6 +121,8 @@ private: QQmlBoundSignal **m_prevSignal; QQmlBoundSignal *m_nextSignal; + bool m_enabled; + QQmlBoundSignalExpressionPointer m_expression; }; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 93e66a1b12..4da19a5a5c 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -176,6 +176,7 @@ void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int qmlRegisterType<QQmlComponent>(uri,versionMajor,versionMinor,"Component"); qmlRegisterType<QObject>(uri,versionMajor,versionMinor,"QtObject"); qmlRegisterType<QQmlBind>(uri, versionMajor, versionMinor,"Binding"); + qmlRegisterType<QQmlConnections,1>(uri, versionMajor, (versionMinor < 3 ? 3 : versionMinor), "Connections"); //Only available in >=2.3 qmlRegisterType<QQmlConnections>(uri, versionMajor, versionMinor,"Connections"); qmlRegisterType<QQmlTimer>(uri, versionMajor, versionMinor,"Timer"); qmlRegisterType<QQmlInstantiator>(uri, versionMajor, (versionMinor < 1 ? 1 : versionMinor), "Instantiator"); //Only available in >=2.1 diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index f6f8c6e51e..c5b5947c11 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -1000,13 +1000,21 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, } #else - Q_UNUSED(qmldirFilePath); - Q_UNUSED(uri); Q_UNUSED(vmaj); Q_UNUSED(vmin); Q_UNUSED(database); Q_UNUSED(qmldir); - Q_UNUSED(errors); + + if (errors) { + QQmlError error; + error.setDescription( + QQmlImportDatabase::tr( + "plugin cannot be loaded for module \"%1\": library loading is disabled") + .arg(uri)); + error.setUrl(QUrl::fromLocalFile(qmldirFilePath)); + errors->prepend(error); + } + return false; #endif // QT_NO_LIBRARY return true; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index c03a463c83..f096dfeea9 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -884,9 +884,10 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con QMetaMethod signalMethod = _qobject->metaObject()->method(property->coreIndex); if (!QMetaObject::checkConnectArgs(signalMethod, method)) { - recordError(binding->valueLocation, tr("Cannot connect mismatched signal/slot %1 %vs. %2") - .arg(QString::fromLatin1(method.methodSignature().constData())) - .arg(QString::fromLatin1(signalMethod.methodSignature().constData()))); + recordError(binding->valueLocation, + tr("Cannot connect mismatched signal/slot %1 %vs. %2") + .arg(QString::fromUtf8(method.methodSignature())) + .arg(QString::fromUtf8(signalMethod.methodSignature()))); return false; } diff --git a/src/qml/qml/qqmlstringconverters.cpp b/src/qml/qml/qqmlstringconverters.cpp index eb0afda927..6a5c0736cf 100644 --- a/src/qml/qml/qqmlstringconverters.cpp +++ b/src/qml/qml/qqmlstringconverters.cpp @@ -137,8 +137,8 @@ QPointF QQmlStringConverters::pointFFromString(const QString &s, bool *ok) bool xGood, yGood; int index = s.indexOf(QLatin1Char(',')); - qreal xCoord = s.left(index).toDouble(&xGood); - qreal yCoord = s.mid(index+1).toDouble(&yGood); + qreal xCoord = s.leftRef(index).toDouble(&xGood); + qreal yCoord = s.midRef(index+1).toDouble(&yGood); if (!xGood || !yGood) { if (ok) *ok = false; @@ -161,8 +161,8 @@ QSizeF QQmlStringConverters::sizeFFromString(const QString &s, bool *ok) bool wGood, hGood; int index = s.indexOf(QLatin1Char('x')); - qreal width = s.left(index).toDouble(&wGood); - qreal height = s.mid(index+1).toDouble(&hGood); + qreal width = s.leftRef(index).toDouble(&wGood); + qreal height = s.midRef(index+1).toDouble(&hGood); if (!wGood || !hGood) { if (ok) *ok = false; @@ -185,12 +185,12 @@ QRectF QQmlStringConverters::rectFFromString(const QString &s, bool *ok) bool xGood, yGood, wGood, hGood; int index = s.indexOf(QLatin1Char(',')); - qreal x = s.left(index).toDouble(&xGood); + qreal x = s.leftRef(index).toDouble(&xGood); int index2 = s.indexOf(QLatin1Char(','), index+1); - qreal y = s.mid(index+1, index2-index-1).toDouble(&yGood); + qreal y = s.midRef(index+1, index2-index-1).toDouble(&yGood); index = s.indexOf(QLatin1Char('x'), index2+1); - qreal width = s.mid(index2+1, index-index2-1).toDouble(&wGood); - qreal height = s.mid(index+1).toDouble(&hGood); + qreal width = s.midRef(index2+1, index-index2-1).toDouble(&wGood); + qreal height = s.midRef(index+1).toDouble(&hGood); if (!xGood || !yGood || !wGood || !hGood) { if (ok) *ok = false; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 67c4295d95..b1f2549035 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -793,8 +793,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * // are not rewritten correctly but this bug is deemed out-of-scope to fix for // performance reasons; see QTBUG-24064) and thus compilation will have failed. QQmlError e; - e.setDescription(QString(QLatin1String("Exception occurred during compilation of function: %1")). - arg(QLatin1String(QMetaObject::method(_id).methodSignature().constData()))); + e.setDescription(QString::fromLatin1("Exception occurred during compilation of " + "function: %1") + .arg(QString::fromUtf8(QMetaObject::method(_id) + .methodSignature()))); ep->warning(e); return -1; // The dynamic method with that id is not available. } diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index f4e980eefb..e859224aea 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -904,7 +904,7 @@ ReturnedValue QtObject::method_btoa(CallContext *ctx) /*! \qmlmethod string Qt::atob(data) -ASCII to binary - this function returns a base64 decoding of \c data. +ASCII to binary - this function decodes the base64 encoded \a data string and returns it. */ ReturnedValue QtObject::method_atob(CallContext *ctx) { @@ -1468,9 +1468,6 @@ QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx) { QV4::ExecutionEngine *v4 = ctx->d()->engine; - if (!v4->qmlEngine()) - return QV4::Encode::undefined(); // Not yet implemented for JavaScript. - QV4::StackFrame frame = v4->currentStackFrame(); const QByteArray baSource = frame.source.toUtf8(); const QByteArray baFunction = frame.function.toUtf8(); @@ -1479,7 +1476,7 @@ QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx) if (!service) { logger.warning("Cannot start profiling because debug service is disabled. Start with -qmljsdebugger=port:XXXXX."); } else { - service->startProfiling(v4->qmlEngine()); + service->startProfiling(v4->jsEngine()); logger.debug("Profiling started."); } @@ -1490,9 +1487,6 @@ QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx) { QV4::ExecutionEngine *v4 = ctx->d()->engine; - if (!v4->qmlEngine()) - return QV4::Encode::undefined(); // Not yet implemented for JavaScript. - QV4::StackFrame frame = v4->currentStackFrame(); const QByteArray baSource = frame.source.toUtf8(); const QByteArray baFunction = frame.function.toUtf8(); @@ -1502,7 +1496,7 @@ QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx) if (!service) { logger.warning("Ignoring console.profileEnd(): the debug service is disabled."); } else { - service->stopProfiling(v4->qmlEngine()); + service->stopProfiling(v4->jsEngine()); logger.debug("Profiling ended."); } diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp index 6a93410ecb..5f69bf5f94 100644 --- a/src/qml/types/qqmlconnections.cpp +++ b/src/qml/types/qqmlconnections.cpp @@ -51,11 +51,12 @@ QT_BEGIN_NAMESPACE class QQmlConnectionsPrivate : public QObjectPrivate { public: - QQmlConnectionsPrivate() : target(0), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {} + QQmlConnectionsPrivate() : target(0), enabled(true), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {} QList<QQmlBoundSignal*> boundsignals; QObject *target; + bool enabled; bool targetSet; bool ignoreUnknownSignals; bool componentcomplete; @@ -177,6 +178,34 @@ void QQmlConnections::setTarget(QObject *obj) } /*! + \qmlproperty bool QtQml::Connections::enabled + \since 5.7 + + This property holds whether the item accepts change events. + + By default, this property is \c true. +*/ +bool QQmlConnections::isEnabled() const +{ + Q_D(const QQmlConnections); + return d->enabled; +} + +void QQmlConnections::setEnabled(bool enabled) +{ + Q_D(QQmlConnections); + if (d->enabled == enabled) + return; + + d->enabled = enabled; + + foreach (QQmlBoundSignal *s, d->boundsignals) + s->setEnabled(d->enabled); + + emit enabledChanged(); +} + +/*! \qmlproperty bool QtQml::Connections::ignoreUnknownSignals Normally, a connection to a non-existent signal produces runtime errors. diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h index 234c5061a7..d330b772cc 100644 --- a/src/qml/types/qqmlconnections_p.h +++ b/src/qml/types/qqmlconnections_p.h @@ -63,6 +63,7 @@ class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatu Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) + Q_REVISION(1) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals) public: @@ -72,11 +73,15 @@ public: QObject *target() const; void setTarget(QObject *); + bool isEnabled() const; + void setEnabled(bool enabled); + bool ignoreUnknownSignals() const; void setIgnoreUnknownSignals(bool ignore); Q_SIGNALS: void targetChanged(); + Q_REVISION(1) void enabledChanged(); private: void connectSignals(); diff --git a/src/qmldebug/qmldebug.pro b/src/qmldebug/qmldebug.pro new file mode 100644 index 0000000000..e5f6de3314 --- /dev/null +++ b/src/qmldebug/qmldebug.pro @@ -0,0 +1,21 @@ +TARGET = QtQmlDebug +QT = core-private network packetprotocol-private qml-private +CONFIG += static internal_module + +load(qt_module) + +SOURCES += \ + qqmldebugclient.cpp \ + qqmldebugconnection.cpp \ + qqmlenginecontrolclient.cpp \ + qqmlprofilerclient.cpp + +HEADERS += \ + qqmldebugclient_p.h \ + qqmldebugclient_p_p.h \ + qqmldebugconnection_p.h \ + qqmlenginecontrolclient_p.h \ + qqmlenginecontrolclient_p_p.h \ + qqmleventlocation_p.h \ + qqmlprofilerclient_p.h \ + qqmlprofilerclient_p_p.h diff --git a/src/qmldebug/qqmldebugclient.cpp b/src/qmldebug/qqmldebugclient.cpp new file mode 100644 index 0000000000..dfa14d6667 --- /dev/null +++ b/src/qmldebug/qqmldebugclient.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqmldebugclient_p_p.h" +#include "qqmldebugconnection_p.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qpointer.h> + +QT_BEGIN_NAMESPACE + +QQmlDebugClient::QQmlDebugClient(const QString &name, QQmlDebugConnection *parent) : + QObject(*(new QQmlDebugClientPrivate(name, parent)), parent) +{ + Q_D(QQmlDebugClient); + d->addToConnection(); +} + +QQmlDebugClient::QQmlDebugClient(QQmlDebugClientPrivate &dd) : + QObject(dd, dd.connection.data()) +{ + Q_D(QQmlDebugClient); + d->addToConnection(); +} + +QQmlDebugClient::~QQmlDebugClient() +{ + Q_D(QQmlDebugClient); + if (d->connection && !d->connection->removeClient(d->name)) + qWarning() << "QQmlDebugClient: Plugin not registered" << d->name; +} + +QQmlDebugClientPrivate::QQmlDebugClientPrivate(const QString &name, + QQmlDebugConnection *connection) : + name(name), connection(connection) +{ +} + +void QQmlDebugClientPrivate::addToConnection() +{ + Q_Q(QQmlDebugClient); + if (connection && !connection->addClient(name, q)) { + qWarning() << "QQmlDebugClient: Conflicting plugin name" << name; + connection = 0; + } +} + +QString QQmlDebugClient::name() const +{ + Q_D(const QQmlDebugClient); + return d->name; +} + +float QQmlDebugClient::serviceVersion() const +{ + Q_D(const QQmlDebugClient); + return d->connection->serviceVersion(d->name); +} + +QQmlDebugClient::State QQmlDebugClient::state() const +{ + Q_D(const QQmlDebugClient); + if (!d->connection || !d->connection->isConnected()) + return NotConnected; + + if (d->connection->serviceVersion(d->name) != -1) + return Enabled; + + return Unavailable; +} + +void QQmlDebugClient::sendMessage(const QByteArray &message) +{ + Q_D(QQmlDebugClient); + d->connection->sendMessage(d->name, message); +} + +QQmlDebugConnection *QQmlDebugClient::connection() const +{ + Q_D(const QQmlDebugClient); + return d->connection; +} + +void QQmlDebugClient::stateChanged(QQmlDebugClient::State state) +{ + Q_UNUSED(state); +} + +void QQmlDebugClient::messageReceived(const QByteArray &message) +{ + Q_UNUSED(message); +} + +QT_END_NAMESPACE diff --git a/tools/qmlprofiler/qqmldebugclient.h b/src/qmldebug/qqmldebugclient_p.h index 522f6bca2f..6d391617a9 100644 --- a/tools/qmlprofiler/qqmldebugclient.h +++ b/src/qmldebug/qqmldebugclient_p.h @@ -31,71 +31,55 @@ ** ****************************************************************************/ -#ifndef QQMLDEBUGCLIENT_H -#define QQMLDEBUGCLIENT_H +#ifndef QQMLDEBUGCLIENT_P_H +#define QQMLDEBUGCLIENT_P_H -#include <QtNetwork/qtcpsocket.h> +#include <QtCore/qobject.h> -class QQmlDebugConnectionPrivate; -class QQmlDebugConnection : public QIODevice -{ - Q_OBJECT - Q_DISABLE_COPY(QQmlDebugConnection) -public: - QQmlDebugConnection(QObject * = 0); - ~QQmlDebugConnection(); - - void connectToHost(const QString &hostName, quint16 port); - - qint64 bytesAvailable() const; - bool isConnected() const; - QAbstractSocket::SocketState state() const; - void flush(); - bool isSequential() const; - void close(); - bool waitForConnected(int msecs = 30000); - -signals: - void connected(); - void stateChanged(QAbstractSocket::SocketState socketState); - void error(QAbstractSocket::SocketError socketError); +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// -protected: - qint64 readData(char *data, qint64 maxSize); - qint64 writeData(const char *data, qint64 maxSize); - -private: - QQmlDebugConnectionPrivate *d; - friend class QQmlDebugClient; - friend class QQmlDebugClientPrivate; -}; +QT_BEGIN_NAMESPACE +class QQmlDebugConnection; class QQmlDebugClientPrivate; class QQmlDebugClient : public QObject { Q_OBJECT Q_DISABLE_COPY(QQmlDebugClient) + Q_DECLARE_PRIVATE(QQmlDebugClient) public: enum State { NotConnected, Unavailable, Enabled }; - QQmlDebugClient(const QString &, QQmlDebugConnection *parent); + QQmlDebugClient(const QString &name, QQmlDebugConnection *parent); ~QQmlDebugClient(); QString name() const; float serviceVersion() const; State state() const; + void sendMessage(const QByteArray &message); - virtual void sendMessage(const QByteArray &); + QQmlDebugConnection *connection() const; protected: - virtual void stateChanged(State); - virtual void messageReceived(const QByteArray &); + QQmlDebugClient(QQmlDebugClientPrivate &dd); private: - QQmlDebugClientPrivate *d; friend class QQmlDebugConnection; - friend class QQmlDebugConnectionPrivate; + + virtual void stateChanged(State state); + virtual void messageReceived(const QByteArray &message); }; -#endif // QQMLDEBUGCLIENT_H +QT_END_NAMESPACE + +#endif // QQMLDEBUGCLIENT_P_H diff --git a/src/qmldebug/qqmldebugclient_p_p.h b/src/qmldebug/qqmldebugclient_p_p.h new file mode 100644 index 0000000000..66a4f4e0c3 --- /dev/null +++ b/src/qmldebug/qqmldebugclient_p_p.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLDEBUGCLIENT_P_P_H +#define QQMLDEBUGCLIENT_P_P_H + +#include "qqmldebugclient_p.h" +#include <private/qobject_p.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QQmlDebugClientPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQmlDebugClient) +public: + QQmlDebugClientPrivate(const QString &name, QQmlDebugConnection *connection); + void addToConnection(); + + QString name; + QPointer<QQmlDebugConnection> connection; +}; + +QT_END_NAMESPACE + +#endif // QQMLDEBUGCLIENT_P_P_H diff --git a/src/qmldebug/qqmldebugconnection.cpp b/src/qmldebug/qqmldebugconnection.cpp new file mode 100644 index 0000000000..3c207b7cc8 --- /dev/null +++ b/src/qmldebug/qqmldebugconnection.cpp @@ -0,0 +1,458 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqmldebugconnection_p.h" +#include "qqmldebugclient_p.h" + +#include <private/qpacketprotocol_p.h> +#include <private/qpacket_p.h> +#include <private/qobject_p.h> + +#include <QtCore/qeventloop.h> +#include <QtCore/qtimer.h> +#include <QtCore/qdatastream.h> +#include <QtNetwork/qlocalserver.h> +#include <QtNetwork/qlocalsocket.h> +#include <QtNetwork/qtcpsocket.h> + +QT_BEGIN_NAMESPACE + +static const int protocolVersion = 1; +static const QString serverId = QLatin1String("QDeclarativeDebugServer"); +static const QString clientId = QLatin1String("QDeclarativeDebugClient"); + +class QQmlDebugConnectionPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQmlDebugConnection) + +public: + QQmlDebugConnectionPrivate(); + QPacketProtocol *protocol; + QIODevice *device; + QLocalServer *server; + QEventLoop handshakeEventLoop; + QTimer handshakeTimer; + + bool gotHello; + int currentDataStreamVersion; + int maximumDataStreamVersion; + QHash <QString, float> serverPlugins; + QHash<QString, QQmlDebugClient *> plugins; + QStringList removedPlugins; + + void advertisePlugins(); + void connectDeviceSignals(); + void flush(); +}; + +QQmlDebugConnectionPrivate::QQmlDebugConnectionPrivate() : + protocol(0), device(0), server(0), gotHello(false), + currentDataStreamVersion(QDataStream::Qt_4_7), + maximumDataStreamVersion(QDataStream::Qt_DefaultCompiledVersion) +{ + handshakeTimer.setSingleShot(true); + handshakeTimer.setInterval(3000); +} + +void QQmlDebugConnectionPrivate::advertisePlugins() +{ + Q_Q(QQmlDebugConnection); + if (!q->isConnected()) + return; + + QPacket pack(currentDataStreamVersion); + pack << serverId << 1 << plugins.keys(); + protocol->send(pack.data()); + flush(); +} + +void QQmlDebugConnection::socketConnected() +{ + Q_D(QQmlDebugConnection); + QPacket pack(d->currentDataStreamVersion); + pack << serverId << 0 << protocolVersion << d->plugins.keys() << d->maximumDataStreamVersion; + d->protocol->send(pack.data()); + d->flush(); +} + +void QQmlDebugConnection::socketDisconnected() +{ + Q_D(QQmlDebugConnection); + d->gotHello = false; + emit disconnected(); +} + +void QQmlDebugConnection::protocolReadyRead() +{ + Q_D(QQmlDebugConnection); + if (!d->gotHello) { + QPacket pack(d->currentDataStreamVersion, d->protocol->read()); + QString name; + + pack >> name; + + bool validHello = false; + if (name == clientId) { + int op = -1; + pack >> op; + if (op == 0) { + int version = -1; + pack >> version; + if (version == protocolVersion) { + QStringList pluginNames; + QList<float> pluginVersions; + pack >> pluginNames; + if (!pack.atEnd()) + pack >> pluginVersions; + + const int pluginNamesSize = pluginNames.size(); + const int pluginVersionsSize = pluginVersions.size(); + for (int i = 0; i < pluginNamesSize; ++i) { + float pluginVersion = 1.0; + if (i < pluginVersionsSize) + pluginVersion = pluginVersions.at(i); + d->serverPlugins.insert(pluginNames.at(i), pluginVersion); + } + + pack >> d->currentDataStreamVersion; + validHello = true; + } + } + } + + if (!validHello) { + qWarning("QQmlDebugConnection: Invalid hello message"); + QObject::disconnect(d->protocol, SIGNAL(protocolReadyRead()), this, SLOT(protocolReadyRead())); + return; + } + d->gotHello = true; + emit connected(); + + QHash<QString, QQmlDebugClient *>::Iterator iter = d->plugins.begin(); + for (; iter != d->plugins.end(); ++iter) { + QQmlDebugClient::State newState = QQmlDebugClient::Unavailable; + if (d->serverPlugins.contains(iter.key())) + newState = QQmlDebugClient::Enabled; + iter.value()->stateChanged(newState); + } + + d->handshakeTimer.stop(); + d->handshakeEventLoop.quit(); + } + + while (d->protocol->packetsAvailable()) { + QPacket pack(d->currentDataStreamVersion, d->protocol->read()); + QString name; + pack >> name; + + if (name == clientId) { + int op = -1; + pack >> op; + + if (op == 1) { + // Service Discovery + QHash<QString, float> oldServerPlugins = d->serverPlugins; + d->serverPlugins.clear(); + + QStringList pluginNames; + QList<float> pluginVersions; + pack >> pluginNames; + if (!pack.atEnd()) + pack >> pluginVersions; + + const int pluginNamesSize = pluginNames.size(); + const int pluginVersionsSize = pluginVersions.size(); + for (int i = 0; i < pluginNamesSize; ++i) { + float pluginVersion = 1.0; + if (i < pluginVersionsSize) + pluginVersion = pluginVersions.at(i); + d->serverPlugins.insert(pluginNames.at(i), pluginVersion); + } + + QHash<QString, QQmlDebugClient *>::Iterator iter = d->plugins.begin(); + for (; iter != d->plugins.end(); ++iter) { + const QString pluginName = iter.key(); + QQmlDebugClient::State newSate = QQmlDebugClient::Unavailable; + if (d->serverPlugins.contains(pluginName)) + newSate = QQmlDebugClient::Enabled; + + if (oldServerPlugins.contains(pluginName) + != d->serverPlugins.contains(pluginName)) { + iter.value()->stateChanged(newSate); + } + } + } else { + qWarning() << "QQmlDebugConnection: Unknown control message id" << op; + } + } else { + QByteArray message; + pack >> message; + + QHash<QString, QQmlDebugClient *>::Iterator iter = d->plugins.find(name); + if (iter == d->plugins.end()) { + // We can get more messages for plugins we have removed because it takes time to + // send the advertisement message but the removal is instant locally. + if (!d->removedPlugins.contains(name)) + qWarning() << "QQmlDebugConnection: Message received for missing plugin" + << name; + } else { + (*iter)->messageReceived(message); + } + } + } +} + +void QQmlDebugConnection::handshakeTimeout() +{ + Q_D(QQmlDebugConnection); + if (!d->gotHello) { + qWarning() << "QQmlDebugConnection: Did not get handshake answer in time"; + d->handshakeEventLoop.quit(); + } +} + +QQmlDebugConnection::QQmlDebugConnection(QObject *parent) : + QObject(*(new QQmlDebugConnectionPrivate), parent) +{ + Q_D(QQmlDebugConnection); + connect(&d->handshakeTimer, SIGNAL(timeout()), this, SLOT(handshakeTimeout())); +} + +QQmlDebugConnection::~QQmlDebugConnection() +{ + Q_D(QQmlDebugConnection); + QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin(); + for (; iter != d->plugins.end(); ++iter) + iter.value()->stateChanged(QQmlDebugClient::NotConnected); +} + +int QQmlDebugConnection::currentDataStreamVersion() const +{ + Q_D(const QQmlDebugConnection); + return d->currentDataStreamVersion; +} + +void QQmlDebugConnection::setMaximumDataStreamVersion(int maximumVersion) +{ + Q_D(QQmlDebugConnection); + d->maximumDataStreamVersion = maximumVersion; +} + +bool QQmlDebugConnection::isConnected() const +{ + Q_D(const QQmlDebugConnection); + return d->gotHello; +} + +bool QQmlDebugConnection::isConnecting() const +{ + Q_D(const QQmlDebugConnection); + return !d->gotHello && d->device; +} + +void QQmlDebugConnection::close() +{ + Q_D(QQmlDebugConnection); + if (d->gotHello) { + d->gotHello = false; + d->device->close(); + + QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin(); + for (; iter != d->plugins.end(); ++iter) + iter.value()->stateChanged(QQmlDebugClient::NotConnected); + } + + if (d->device) { + d->device->deleteLater(); + d->device = 0; + } +} + +bool QQmlDebugConnection::waitForConnected(int msecs) +{ + Q_D(QQmlDebugConnection); + QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); + if (!socket) { + if (!d->server || (!d->server->hasPendingConnections() && + !d->server->waitForNewConnection(msecs))) + return false; + } else if (!socket->waitForConnected(msecs)) { + return false; + } + // wait for handshake + d->handshakeTimer.start(); + d->handshakeEventLoop.exec(); + return d->gotHello; +} + +QQmlDebugClient *QQmlDebugConnection::client(const QString &name) const +{ + Q_D(const QQmlDebugConnection); + return d->plugins.value(name, 0); +} + +bool QQmlDebugConnection::addClient(const QString &name, QQmlDebugClient *client) +{ + Q_D(QQmlDebugConnection); + if (d->plugins.contains(name)) + return false; + d->removedPlugins.removeAll(name); + d->plugins.insert(name, client); + d->advertisePlugins(); + return true; +} + +bool QQmlDebugConnection::removeClient(const QString &name) +{ + Q_D(QQmlDebugConnection); + if (!d->plugins.contains(name)) + return false; + d->plugins.remove(name); + d->removedPlugins.append(name); + d->advertisePlugins(); + return true; +} + +float QQmlDebugConnection::serviceVersion(const QString &serviceName) const +{ + Q_D(const QQmlDebugConnection); + return d->serverPlugins.value(serviceName, -1); +} + +bool QQmlDebugConnection::sendMessage(const QString &name, const QByteArray &message) +{ + Q_D(QQmlDebugConnection); + if (!isConnected() || !d->serverPlugins.contains(name)) + return false; + + QPacket pack(d->currentDataStreamVersion); + pack << name << message; + d->protocol->send(pack.data()); + d->flush(); + + return true; +} + +void QQmlDebugConnectionPrivate::flush() +{ + QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(device); + if (socket) + socket->flush(); +} + +void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port) +{ + Q_D(QQmlDebugConnection); + if (d->gotHello) + close(); + QTcpSocket *socket = new QTcpSocket(this); + d->device = socket; + d->connectDeviceSignals(); + connect(socket, SIGNAL(connected()), this, SLOT(socketConnected())); + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SIGNAL(socketError(QAbstractSocket::SocketError))); + connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SIGNAL(socketStateChanged(QAbstractSocket::SocketState))); + socket->connectToHost(hostName, port); +} + +void QQmlDebugConnection::startLocalServer(const QString &fileName) +{ + Q_D(QQmlDebugConnection); + if (d->gotHello) + close(); + if (d->server) + d->server->deleteLater(); + d->server = new QLocalServer(this); + // QueuedConnection so that waitForNewConnection() returns true. + connect(d->server, SIGNAL(newConnection()), this, SLOT(newConnection()), Qt::QueuedConnection); + d->server->listen(fileName); +} + +class LocalSocketSignalTranslator : public QObject +{ + Q_OBJECT +public: + LocalSocketSignalTranslator(QLocalSocket *parent) : QObject(parent) + { + connect(parent, SIGNAL(stateChanged(QLocalSocket::LocalSocketState)), + this, SLOT(onStateChanged(QLocalSocket::LocalSocketState))); + connect(parent, SIGNAL(error(QLocalSocket::LocalSocketError)), + this, SLOT(onError(QLocalSocket::LocalSocketError))); + } + +signals: + void socketError(QAbstractSocket::SocketError error); + void socketStateChanged(QAbstractSocket::SocketState state); + +public slots: + void onError(QLocalSocket::LocalSocketError error) + { + emit socketError(static_cast<QAbstractSocket::SocketError>(error)); + } + + void onStateChanged(QLocalSocket::LocalSocketState state) + { + emit socketStateChanged(static_cast<QAbstractSocket::SocketState>(state)); + } +}; + +void QQmlDebugConnection::newConnection() +{ + Q_D(QQmlDebugConnection); + delete d->device; + QLocalSocket *socket = d->server->nextPendingConnection(); + d->server->close(); + d->device = socket; + d->connectDeviceSignals(); + LocalSocketSignalTranslator *translator = new LocalSocketSignalTranslator(socket); + + QObject::connect(translator, SIGNAL(socketError(QAbstractSocket::SocketError)), + this, SIGNAL(socketError(QAbstractSocket::SocketError))); + QObject::connect(translator, SIGNAL(socketStateChanged(QAbstractSocket::SocketState)), + this, SIGNAL(socketStateChanged(QAbstractSocket::SocketState))); + socketConnected(); +} + +void QQmlDebugConnectionPrivate::connectDeviceSignals() +{ + Q_Q(QQmlDebugConnection); + delete protocol; + protocol = new QPacketProtocol(device, q); + QObject::connect(protocol, SIGNAL(readyRead()), q, SLOT(protocolReadyRead())); + QObject::connect(device, SIGNAL(disconnected()), q, SLOT(socketDisconnected())); +} + +QT_END_NAMESPACE + +#include <qqmldebugconnection.moc> diff --git a/tests/auto/qml/debugger/shared/qqmldebugclient.h b/src/qmldebug/qqmldebugconnection_p.h index fe9da693c8..190ca25db2 100644 --- a/tests/auto/qml/debugger/shared/qqmldebugclient.h +++ b/src/qmldebug/qqmldebugconnection_p.h @@ -31,80 +31,69 @@ ** ****************************************************************************/ -#ifndef QQMLDEBUGCLIENT_H -#define QQMLDEBUGCLIENT_H - -#include <QtNetwork/qtcpsocket.h> - +#ifndef QQMLDEBUGCONNECTION_P_H +#define QQMLDEBUGCONNECTION_P_H + +#include <QtCore/qobject.h> +#include <QtNetwork/qabstractsocket.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QQmlDebugClient; class QQmlDebugConnectionPrivate; -class QQmlDebugConnection : public QIODevice +class QQmlDebugConnection : public QObject { Q_OBJECT Q_DISABLE_COPY(QQmlDebugConnection) + Q_DECLARE_PRIVATE(QQmlDebugConnection) public: - QQmlDebugConnection(QObject * = 0); + QQmlDebugConnection(QObject *parent = 0); ~QQmlDebugConnection(); void connectToHost(const QString &hostName, quint16 port); void startLocalServer(const QString &fileName); - void setDataStreamVersion(int dataStreamVersion); - int dataStreamVersion(); + int currentDataStreamVersion() const; + void setMaximumDataStreamVersion(int maximumVersion); - qint64 bytesAvailable() const; bool isConnected() const; - QAbstractSocket::SocketState state() const; - void flush(); - bool isSequential() const; + bool isConnecting() const; + void close(); bool waitForConnected(int msecs = 30000); - QString stateString() const; + QQmlDebugClient *client(const QString &name) const; + bool addClient(const QString &name, QQmlDebugClient *client); + bool removeClient(const QString &name); + + float serviceVersion(const QString &serviceName) const; + bool sendMessage(const QString &name, const QByteArray &message); signals: void connected(); - void stateChanged(QAbstractSocket::SocketState socketState); - void error(QAbstractSocket::SocketError socketError); - -protected: - qint64 readData(char *data, qint64 maxSize); - qint64 writeData(const char *data, qint64 maxSize); - -private: - QQmlDebugConnectionPrivate *d; - int m_dataStreamVersion; - friend class QQmlDebugClient; - friend class QQmlDebugClientPrivate; - friend class QQmlDebugConnectionPrivate; + void disconnected(); + void socketError(QAbstractSocket::SocketError socketError); + void socketStateChanged(QAbstractSocket::SocketState socketState); + +private Q_SLOTS: + void newConnection(); + void socketConnected(); + void socketDisconnected(); + void protocolReadyRead(); + void handshakeTimeout(); }; -class QQmlDebugClientPrivate; -class QQmlDebugClient : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(QQmlDebugClient) - -public: - enum State { NotConnected, Unavailable, Enabled }; - - QQmlDebugClient(const QString &, QQmlDebugConnection *parent); - ~QQmlDebugClient(); - - QString name() const; - float serviceVersion() const; - State state() const; - QString stateString() const; - - virtual void sendMessage(const QByteArray &); - -protected: - virtual void stateChanged(State); - virtual void messageReceived(const QByteArray &); - -private: - QQmlDebugClientPrivate *d; - friend class QQmlDebugConnection; - friend class QQmlDebugConnectionPrivate; -}; +QT_END_NAMESPACE -#endif // QQMLDEBUGCLIENT_H +#endif // QQMLDEBUGCONNECTION_P_H diff --git a/src/qmldebug/qqmlenginecontrolclient.cpp b/src/qmldebug/qqmlenginecontrolclient.cpp new file mode 100644 index 0000000000..b45e4e1f14 --- /dev/null +++ b/src/qmldebug/qqmlenginecontrolclient.cpp @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqmlenginecontrolclient_p.h" +#include "qqmlenginecontrolclient_p_p.h" +#include "qqmldebugconnection_p.h" + +#include <private/qqmldebugserviceinterfaces_p.h> +#include <private/qpacket_p.h> + +QT_BEGIN_NAMESPACE + +QQmlEngineControlClient::QQmlEngineControlClient(QQmlDebugConnection *connection) : + QQmlDebugClient(*(new QQmlEngineControlClientPrivate(connection))) +{ +} + +QQmlEngineControlClient::QQmlEngineControlClient(QQmlEngineControlClientPrivate &dd) : + QQmlDebugClient(dd) +{ +} + +/*! + * Block the starting or stopping of the engine with id \a engineId for now. By calling + * releaseEngine later the block can be lifted again. In the debugged application the engine control + * server waits until a message is received before continuing. So by not sending a message here we + * delay the process. Blocks add up. You have to call releaseEngine() as often as you've called + * blockEngine before. The intention of that is to allow different debug clients to use the same + * engine control and communicate with their respective counterparts before the QML engine starts or + * shuts down. + */ +void QQmlEngineControlClient::blockEngine(int engineId) +{ + Q_D(QQmlEngineControlClient); + Q_ASSERT(d->blockedEngines.contains(engineId)); + d->blockedEngines[engineId].blockers++; +} + +/*! + * Release the engine with id \a engineId. If no other blocks are present, depending on what the + * engine is waiting for, the start or stop command is sent to the process being debugged. + */ +void QQmlEngineControlClient::releaseEngine(int engineId) +{ + Q_D(QQmlEngineControlClient); + Q_ASSERT(d->blockedEngines.contains(engineId)); + + QQmlEngineControlClientPrivate::EngineState &state = d->blockedEngines[engineId]; + if (--state.blockers == 0) { + Q_ASSERT(state.releaseCommand != QQmlEngineControlClientPrivate::InvalidCommand); + d->sendCommand(state.releaseCommand, engineId); + d->blockedEngines.remove(engineId); + } +} + +QList<int> QQmlEngineControlClient::blockedEngines() const +{ + Q_D(const QQmlEngineControlClient); + return d->blockedEngines.keys(); +} + +void QQmlEngineControlClient::messageReceived(const QByteArray &data) +{ + Q_D(QQmlEngineControlClient); + QPacket stream(d->connection->currentDataStreamVersion(), data); + int message; + int id; + QString name; + + stream >> message >> id; + + if (!stream.atEnd()) + stream >> name; + + QQmlEngineControlClientPrivate::EngineState &state = d->blockedEngines[id]; + Q_ASSERT(state.blockers == 0); + Q_ASSERT(state.releaseCommand == QQmlEngineControlClientPrivate::InvalidCommand); + + switch (message) { + case QQmlEngineControlClientPrivate::EngineAboutToBeAdded: + state.releaseCommand = QQmlEngineControlClientPrivate::StartWaitingEngine; + emit engineAboutToBeAdded(id, name); + break; + case QQmlEngineControlClientPrivate::EngineAdded: + emit engineAdded(id, name); + break; + case QQmlEngineControlClientPrivate::EngineAboutToBeRemoved: + state.releaseCommand = QQmlEngineControlClientPrivate::StopWaitingEngine; + emit engineAboutToBeRemoved(id, name); + break; + case QQmlEngineControlClientPrivate::EngineRemoved: + emit engineRemoved(id, name); + break; + } + + if (state.blockers == 0 && + state.releaseCommand != QQmlEngineControlClientPrivate::InvalidCommand) { + d->sendCommand(state.releaseCommand, id); + d->blockedEngines.remove(id); + } +} + +QQmlEngineControlClientPrivate::QQmlEngineControlClientPrivate(QQmlDebugConnection *connection) : + QQmlDebugClientPrivate(QQmlEngineControlService::s_key, connection) +{ +} + +void QQmlEngineControlClientPrivate::sendCommand( + QQmlEngineControlClientPrivate::CommandType command, int engineId) +{ + Q_Q(QQmlEngineControlClient); + QPacket stream(connection->currentDataStreamVersion()); + stream << int(command) << engineId; + q->sendMessage(stream.data()); +} + +QT_END_NAMESPACE diff --git a/src/qmldebug/qqmlenginecontrolclient_p.h b/src/qmldebug/qqmlenginecontrolclient_p.h new file mode 100644 index 0000000000..601f8a871d --- /dev/null +++ b/src/qmldebug/qqmlenginecontrolclient_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLENGINECONTROLCLIENT_P_H +#define QQMLENGINECONTROLCLIENT_P_H + +#include "qqmldebugclient_p.h" + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QQmlEngineControlClientPrivate; +class QQmlEngineControlClient : public QQmlDebugClient +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QQmlEngineControlClient) +public: + QQmlEngineControlClient(QQmlDebugConnection *connection); + + void blockEngine(int engineId); + void releaseEngine(int engineId); + + QList<int> blockedEngines() const; + +signals: + void engineAboutToBeAdded(int engineId, const QString &name); + void engineAdded(int engineId, const QString &name); + void engineAboutToBeRemoved(int engineId, const QString &name); + void engineRemoved(int engineId, const QString &name); + +protected: + QQmlEngineControlClient(QQmlEngineControlClientPrivate &dd); + +private: + void messageReceived(const QByteArray &); +}; + +QT_END_NAMESPACE + +#endif // QQMLENGINECONTROLCLIENT_P_H diff --git a/src/qmldebug/qqmlenginecontrolclient_p_p.h b/src/qmldebug/qqmlenginecontrolclient_p_p.h new file mode 100644 index 0000000000..7e99c35948 --- /dev/null +++ b/src/qmldebug/qqmlenginecontrolclient_p_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLENGINECONTROLCLIENT_P_P_H +#define QQMLENGINECONTROLCLIENT_P_P_H + +#include "qqmlenginecontrolclient_p.h" +#include "qqmldebugclient_p_p.h" + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QQmlEngineControlClientPrivate : public QQmlDebugClientPrivate +{ + Q_DECLARE_PUBLIC(QQmlEngineControlClient) +public: + enum MessageType { + EngineAboutToBeAdded, + EngineAdded, + EngineAboutToBeRemoved, + EngineRemoved + }; + + enum CommandType { + StartWaitingEngine, + StopWaitingEngine, + InvalidCommand + }; + + QQmlEngineControlClientPrivate(QQmlDebugConnection *connection); + + void sendCommand(CommandType command, int engineId); + + struct EngineState { + EngineState(CommandType command = InvalidCommand) : releaseCommand(command), blockers(0) {} + CommandType releaseCommand; + int blockers; + }; + + QHash<int, EngineState> blockedEngines; +}; + +QT_END_NAMESPACE + +#endif // QQMLENGINECONTROLCLIENT_P_P_H diff --git a/src/qmldebug/qqmleventlocation_p.h b/src/qmldebug/qqmleventlocation_p.h new file mode 100644 index 0000000000..25d81a5989 --- /dev/null +++ b/src/qmldebug/qqmleventlocation_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLEVENTLOCATION_P_H +#define QQMLEVENTLOCATION_P_H + +#include <QtCore/qstring.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +struct QQmlEventLocation +{ + QQmlEventLocation() : line(-1), column(-1) {} + QQmlEventLocation(const QString &file, int lineNumber, int columnNumber) : + filename(file), line(lineNumber), column(columnNumber) {} + + QString filename; + int line; + int column; +}; + +Q_DECLARE_TYPEINFO(QQmlEventLocation, Q_MOVABLE_TYPE); + +QT_END_NAMESPACE + +#endif // QQMLEVENTLOCATION_P_H diff --git a/src/qmldebug/qqmlprofilerclient.cpp b/src/qmldebug/qqmlprofilerclient.cpp new file mode 100644 index 0000000000..c7ad6dae53 --- /dev/null +++ b/src/qmldebug/qqmlprofilerclient.cpp @@ -0,0 +1,354 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqmlprofilerclient_p_p.h" +#include "qqmldebugconnection_p.h" +#include <private/qqmldebugserviceinterfaces_p.h> + +QT_BEGIN_NAMESPACE + +QQmlProfilerClient::QQmlProfilerClient(QQmlDebugConnection *connection) : + QQmlDebugClient(*(new QQmlProfilerClientPrivate(connection))) +{ +} + +QQmlProfilerClient::QQmlProfilerClient(QQmlProfilerClientPrivate &dd) : + QQmlDebugClient(dd) +{ +} + +QQmlProfilerClientPrivate::QQmlProfilerClientPrivate(QQmlDebugConnection *connection) : + QQmlDebugClientPrivate(QQmlProfilerService::s_key, connection), + features(std::numeric_limits<quint64>::max()) +{ +} + +void QQmlProfilerClient::setFeatures(quint64 features) +{ + Q_D(QQmlProfilerClient); + d->features = features; +} + +void QQmlProfilerClient::sendRecordingStatus(bool record, int engineId, quint32 flushInterval) +{ + Q_D(const QQmlProfilerClient); + + QPacket stream(d->connection->currentDataStreamVersion()); + stream << record << engineId << d->features << flushInterval; + sendMessage(stream.data()); +} + +void QQmlProfilerClient::traceStarted(qint64 time, int engineId) +{ + Q_UNUSED(time); + Q_UNUSED(engineId); +} + +void QQmlProfilerClient::traceFinished(qint64 time, int engineId) +{ + Q_UNUSED(time); + Q_UNUSED(engineId); +} + +void QQmlProfilerClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime) +{ + Q_UNUSED(type); + Q_UNUSED(startTime); +} + +void QQmlProfilerClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, + const QString &data) +{ + Q_UNUSED(type); + Q_UNUSED(time); + Q_UNUSED(data); +} + +void QQmlProfilerClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time, + const QQmlEventLocation &location) +{ + Q_UNUSED(type); + Q_UNUSED(time); + Q_UNUSED(location); +} + +void QQmlProfilerClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime) +{ + Q_UNUSED(type); + Q_UNUSED(endTime); +} + +void QQmlProfilerClient::animationFrame(qint64 time, int frameRate, int animationCount, + int threadId) +{ + Q_UNUSED(time); + Q_UNUSED(frameRate); + Q_UNUSED(animationCount); + Q_UNUSED(threadId); +} + +void QQmlProfilerClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, + qint64 time, qint64 numericData1, qint64 numericData2, + qint64 numericData3, qint64 numericData4, + qint64 numericData5) +{ + Q_UNUSED(type); + Q_UNUSED(time); + Q_UNUSED(numericData1); + Q_UNUSED(numericData2); + Q_UNUSED(numericData3); + Q_UNUSED(numericData4); + Q_UNUSED(numericData5); +} + +void QQmlProfilerClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, + qint64 time, const QString &url, int numericData1, + int numericData2) +{ + Q_UNUSED(type); + Q_UNUSED(time); + Q_UNUSED(url); + Q_UNUSED(numericData1); + Q_UNUSED(numericData2); +} + +void QQmlProfilerClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, + qint64 amount) +{ + Q_UNUSED(type); + Q_UNUSED(time); + Q_UNUSED(amount); +} + +void QQmlProfilerClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, + int a, int b) +{ + Q_UNUSED(type); + Q_UNUSED(time); + Q_UNUSED(a); + Q_UNUSED(b); +} + +void QQmlProfilerClient::complete() +{ +} + +void QQmlProfilerClient::unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time, + int detailType) +{ + Q_UNUSED(messageType); + Q_UNUSED(time); + Q_UNUSED(detailType); +} + +void QQmlProfilerClient::unknownData(QPacket &stream) +{ + Q_UNUSED(stream); +} + +inline QQmlProfilerDefinitions::ProfileFeature featureFromRangeType( + QQmlProfilerDefinitions::RangeType range) +{ + switch (range) { + case QQmlProfilerDefinitions::Painting: + return QQmlProfilerDefinitions::ProfilePainting; + case QQmlProfilerDefinitions::Compiling: + return QQmlProfilerDefinitions::ProfileCompiling; + case QQmlProfilerDefinitions::Creating: + return QQmlProfilerDefinitions::ProfileCreating; + case QQmlProfilerDefinitions::Binding: + return QQmlProfilerDefinitions::ProfileBinding; + case QQmlProfilerDefinitions::HandlingSignal: + return QQmlProfilerDefinitions::ProfileHandlingSignal; + case QQmlProfilerDefinitions::Javascript: + return QQmlProfilerDefinitions::ProfileJavaScript; + default: + return QQmlProfilerDefinitions::MaximumProfileFeature; + } +} + +void QQmlProfilerClient::messageReceived(const QByteArray &data) +{ + Q_D(const QQmlProfilerClient); + + QPacket stream(d->connection->currentDataStreamVersion(), data); + + // Force all the 1 << <FLAG> expressions to be done in 64 bit, to silence some warnings + const quint64 one = static_cast<quint64>(1); + + qint64 time; + int messageType; + + stream >> time >> messageType; + + if (messageType >= QQmlProfilerDefinitions::MaximumMessage) { + unknownEvent(static_cast<QQmlProfilerDefinitions::Message>(messageType), time, -1); + return; + } + + if (messageType == QQmlProfilerDefinitions::Event) { + int type; + stream >> type; + + QQmlProfilerDefinitions::EventType eventType = + static_cast<QQmlProfilerDefinitions::EventType>(type); + + if (eventType == QQmlProfilerDefinitions::EndTrace) { + int engineId = -1; + if (!stream.atEnd()) + stream >> engineId; + traceFinished(time, engineId); + } else if (eventType == QQmlProfilerDefinitions::AnimationFrame) { + if (!(d->features & one << QQmlProfilerDefinitions::ProfileAnimations)) + return; + + int frameRate, animationCount; + int threadId = 0; + stream >> frameRate >> animationCount; + if (!stream.atEnd()) + stream >> threadId; + + animationFrame(time, frameRate, animationCount, threadId); + } else if (type == QQmlProfilerDefinitions::StartTrace) { + int engineId = -1; + if (!stream.atEnd()) + stream >> engineId; + traceStarted(time, engineId); + } else if (eventType == QQmlProfilerDefinitions::Key || + eventType == QQmlProfilerDefinitions::Mouse) { + + if (!(d->features & one << QQmlProfilerDefinitions::ProfileInputEvents)) + return; + + int type; + if (!stream.atEnd()) { + stream >> type; + } else { + type = (eventType == QQmlProfilerDefinitions::Key) ? + QQmlProfilerDefinitions::InputKeyUnknown : + QQmlProfilerDefinitions::InputMouseUnknown; + } + + int a = 0; + if (!stream.atEnd()) + stream >> a; + + int b = 0; + if (!stream.atEnd()) + stream >> b; + + inputEvent(static_cast<QQmlProfilerDefinitions::InputEventType>(type), time, a, b); + } else { + unknownEvent(QQmlProfilerDefinitions::Event, time, type); + } + } else if (messageType == QQmlProfilerDefinitions::Complete) { + complete(); + } else if (messageType == QQmlProfilerDefinitions::SceneGraphFrame) { + if (!(d->features & one << QQmlProfilerDefinitions::ProfileSceneGraph)) + return; + + int type; + int count = 0; + qint64 params[5]; + + stream >> type; + while (!stream.atEnd()) + stream >> params[count++]; + + while (count < 5) + params[count++] = 0; + + sceneGraphEvent(static_cast<QQmlProfilerDefinitions::SceneGraphFrameType>(type), time, + params[0], params[1], params[2], params[3], params[4]); + } else if (messageType == QQmlProfilerDefinitions::PixmapCacheEvent) { + if (!(d->features & one << QQmlProfilerDefinitions::ProfilePixmapCache)) + return; + + int type, param1 = 0, param2 = 0; + QString pixUrl; + stream >> type >> pixUrl; + + QQmlProfilerDefinitions::PixmapEventType pixmapEventType = + static_cast<QQmlProfilerDefinitions::PixmapEventType>(type); + + if (pixmapEventType == QQmlProfilerDefinitions::PixmapReferenceCountChanged || + pixmapEventType == QQmlProfilerDefinitions::PixmapCacheCountChanged) { + stream >> param1; + } else if (pixmapEventType == QQmlProfilerDefinitions::PixmapSizeKnown) { + stream >> param1 >> param2; + } + + pixmapCacheEvent(pixmapEventType, time, pixUrl, param1, param2); + } else if (messageType == QQmlProfilerDefinitions::MemoryAllocation) { + if (!(d->features & one << QQmlProfilerDefinitions::ProfileMemory)) + return; + int type; + qint64 delta; + stream >> type >> delta; + memoryAllocation((QQmlProfilerDefinitions::MemoryType)type, time, delta); + } else { + int range; + stream >> range; + + QQmlProfilerDefinitions::RangeType rangeType = + static_cast<QQmlProfilerDefinitions::RangeType>(range); + + if (range >= QQmlProfilerDefinitions::MaximumRangeType || + !(d->features & one << featureFromRangeType(rangeType))) + return; + + if (messageType == QQmlProfilerDefinitions::RangeStart) { + rangeStart(rangeType, time); + } else if (messageType == QQmlProfilerDefinitions::RangeData) { + QString data; + stream >> data; + rangeData(rangeType, time, data); + } else if (messageType == QQmlProfilerDefinitions::RangeLocation) { + QQmlEventLocation location; + stream >> location.filename >> location.line; + + if (!stream.atEnd()) + stream >> location.column; + + rangeLocation(rangeType, time, location); + } else if (messageType == QQmlProfilerDefinitions::RangeEnd) { + rangeEnd(rangeType, time); + } else { + unknownEvent(static_cast<QQmlProfilerDefinitions::Message>(messageType), time, range); + } + } + + if (!stream.atEnd()) + unknownData(stream); +} +QT_END_NAMESPACE diff --git a/src/qmldebug/qqmlprofilerclient_p.h b/src/qmldebug/qqmlprofilerclient_p.h new file mode 100644 index 0000000000..0513bef608 --- /dev/null +++ b/src/qmldebug/qqmlprofilerclient_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLPROFILERCLIENT_P_H +#define QQMLPROFILERCLIENT_P_H + +#include "qqmldebugclient_p.h" +#include "qqmleventlocation_p.h" +#include <private/qqmlprofilerdefinitions_p.h> +#include <private/qpacket_p.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QQmlProfilerClientPrivate; +class QQmlProfilerClient : public QQmlDebugClient +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QQmlProfilerClient) + +public: + QQmlProfilerClient(QQmlDebugConnection *connection); + void setFeatures(quint64 features); + +public slots: + void sendRecordingStatus(bool record, int engineId = -1, quint32 flushInterval = 0); + +protected: + QQmlProfilerClient(QQmlProfilerClientPrivate &dd); + +private: + virtual void messageReceived(const QByteArray &message); + + virtual void traceStarted(qint64 time, int engineId); + virtual void traceFinished(qint64 time, int engineId); + + virtual void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime); + virtual void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, + const QString &data); + virtual void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time, + const QQmlEventLocation &location); + virtual void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime); + + virtual void animationFrame(qint64 time, int frameRate, int animationCount, int threadId); + + virtual void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time, + qint64 numericData1, qint64 numericData2, qint64 numericData3, + qint64 numericData4, qint64 numericData5); + + virtual void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time, + const QString &url, int numericData1, int numericData2); + + virtual void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, + qint64 amount); + + virtual void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, + int b); + + virtual void complete(); + + virtual void unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time, + int detailType); + virtual void unknownData(QPacket &stream); +}; + +QT_END_NAMESPACE + +#endif // QQMLPROFILERCLIENT_P_H diff --git a/src/qmldebug/qqmlprofilerclient_p_p.h b/src/qmldebug/qqmlprofilerclient_p_p.h new file mode 100644 index 0000000000..c522eb7f52 --- /dev/null +++ b/src/qmldebug/qqmlprofilerclient_p_p.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLPROFILERCLIENT_P_P_H +#define QQMLPROFILERCLIENT_P_P_H + +#include "qqmlprofilerclient_p.h" +#include "qqmldebugclient_p_p.h" + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QQmlProfilerClientPrivate : public QQmlDebugClientPrivate +{ + Q_DECLARE_PUBLIC(QQmlProfilerClient) +public: + QQmlProfilerClientPrivate(QQmlDebugConnection *connection); + quint64 features; +}; + +QT_END_NAMESPACE + +#endif // QQMLPROFILERCLIENT_P_P_H + diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index fd1b74d32d..23d13c2fd4 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2323,7 +2323,7 @@ QQuickItem::~QQuickItem() // XXX todo - optimize while (!d->childItems.isEmpty()) - d->childItems.first()->setParentItem(0); + d->childItems.constFirst()->setParentItem(0); for (int ii = 0; ii < d->changeListeners.count(); ++ii) { QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate(); @@ -2485,7 +2485,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo from = item->parentItem(); } else { if (!item->childItems().isEmpty()) - from = item->childItems().first(); + from = item->d_func()->childItems.constFirst(); else from = item->parentItem(); } diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 0211e9f285..955e1f1e00 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -1319,10 +1319,10 @@ void QQuickListViewPrivate::updateFooter() } FxListItemSG *listItem = static_cast<FxListItemSG*>(footer); - if (visibleItems.count()) { - if (footerPositioning == QQuickListView::OverlayFooter) { - listItem->setPosition(isContentFlowReversed() ? -position() - footerSize() : position() + size() - footerSize()); - } else if (footerPositioning == QQuickListView::PullBackFooter) { + if (footerPositioning == QQuickListView::OverlayFooter) { + listItem->setPosition(isContentFlowReversed() ? -position() - footerSize() : position() + size() - footerSize()); + } else if (visibleItems.count()) { + if (footerPositioning == QQuickListView::PullBackFooter) { qreal viewPos = isContentFlowReversed() ? -position() : position() + size(); qreal clampedPos = qBound(originPosition() - footerSize() + size(), listItem->position(), lastPosition()); listItem->setPosition(qBound(viewPos - footerSize(), clampedPos, viewPos)); @@ -1358,26 +1358,24 @@ void QQuickListViewPrivate::updateHeader() } FxListItemSG *listItem = static_cast<FxListItemSG*>(header); - if (listItem) { - if (visibleItems.count()) { - if (headerPositioning == QQuickListView::OverlayHeader) { - listItem->setPosition(isContentFlowReversed() ? -position() - size() : position()); - } else if (headerPositioning == QQuickListView::PullBackHeader) { - qreal viewPos = isContentFlowReversed() ? -position() - size() : position(); - qreal clampedPos = qBound(originPosition() - headerSize(), listItem->position(), lastPosition() - headerSize() - size()); - listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos)); + if (headerPositioning == QQuickListView::OverlayHeader) { + listItem->setPosition(isContentFlowReversed() ? -position() - size() : position()); + } else if (visibleItems.count()) { + if (headerPositioning == QQuickListView::PullBackHeader) { + qreal viewPos = isContentFlowReversed() ? -position() - size() : position(); + qreal clampedPos = qBound(originPosition() - headerSize(), listItem->position(), lastPosition() - headerSize() - size()); + listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos)); + } else { + qreal startPos = originPosition(); + if (visibleIndex == 0) { + listItem->setPosition(startPos - headerSize()); } else { - qreal startPos = originPosition(); - if (visibleIndex == 0) { + if (position() <= startPos || listItem->position() > startPos - headerSize()) listItem->setPosition(startPos - headerSize()); - } else { - if (position() <= startPos || listItem->position() > startPos - headerSize()) - listItem->setPosition(startPos - headerSize()); - } } - } else { - listItem->setPosition(-headerSize()); } + } else { + listItem->setPosition(-headerSize()); } if (created) @@ -2840,8 +2838,15 @@ void QQuickListView::viewportMoved(Qt::Orientations orient) { Q_D(QQuickListView); QQuickItemView::viewportMoved(orient); - if (!d->itemCount) + + if (!d->itemCount) { + if (d->hasStickyHeader()) + d->updateHeader(); + if (d->hasStickyFooter()) + d->updateFooter(); return; + } + // Recursion can occur due to refill changing the content size. if (d->inViewportMoved) return; diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 456eedd0be..0040843929 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -852,6 +852,11 @@ likelihood of glitches in animation. When loading asynchronously the status will change to Loader.Loading. Once the entire component has been created, the \l item will be available and the status will change to Loader.Ready. +Changing the value of this property to \c false while an asynchronous load is in +progress will force immediate, synchronous completion. This allows beginning an +asynchronous load and then forcing completion if the Loader content must be +accessed before the asynchronous load has completed. + To avoid seeing the items loading progressively set \c visible appropriately, e.g. \code @@ -878,6 +883,19 @@ void QQuickLoader::setAsynchronous(bool a) return; d->asynchronous = a; + + if (!d->asynchronous && isComponentComplete() && d->active) { + if (d->loadingFromSource && d->component && d->component->isLoading()) { + // Force a synchronous component load + QUrl currentSource = d->source; + d->clear(); + d->source = currentSource; + loadFromSource(); + } else if (d->incubator && d->incubator->isLoading()) { + d->incubator->forceCompletion(); + } + } + emit asynchronousChanged(); } diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 223219a3f9..d32b194803 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -73,7 +73,11 @@ QQuickTextPrivate::QQuickTextPrivate() , elideMode(QQuickText::ElideNone), hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop) , format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap) , style(QQuickText::Normal) +#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE) + , renderType(QQuickText::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE) +#else , renderType(QQuickText::QtRendering) +#endif , updateType(UpdatePaintNode) , maximumLineCountValid(false), updateOnComponentComplete(true), richText(false) , styledText(false), widthExceeded(false), heightExceeded(false), internalWidthUpdate(false) diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp index 04e43c017e..d0678b4278 100644 --- a/src/quick/items/qquicktextcontrol.cpp +++ b/src/quick/items/qquicktextcontrol.cpp @@ -1419,7 +1419,7 @@ QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVar tmpCursor.movePosition(QTextCursor::NextBlock); --numBlocks; } - result += block.text().mid(0,localPos); + result += block.text().midRef(0,localPos); return QVariant(result); } default: diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h index fed0688fd7..a2b4c1ab99 100644 --- a/src/quick/items/qquicktextedit_p_p.h +++ b/src/quick/items/qquicktextedit_p_p.h @@ -106,7 +106,11 @@ public: , quickDocument(0), lastSelectionStart(0), lastSelectionEnd(0), lineCount(0) , hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop) , format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap) +#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE) + , renderType(QQuickTextEdit::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE) +#else , renderType(QQuickTextEdit::QtRendering) +#endif , contentDirection(Qt::LayoutDirectionAuto) , mouseSelectionMode(QQuickTextEdit::SelectCharacters) #ifndef QT_NO_IM diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 087b8b8135..fe18fc2231 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -3533,7 +3533,7 @@ void QQuickTextInputPrivate::internalInsert(const QString &s) int remaining = m_maxLength - m_text.length(); if (remaining != 0) { m_text.insert(m_cursor, s.left(remaining)); - for (int i = 0; i < (int) s.left(remaining).length(); ++i) + for (int i = 0; i < (int) s.leftRef(remaining).length(); ++i) addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1)); m_textDirty = true; } @@ -3886,14 +3886,14 @@ QString QQuickTextInputPrivate::maskString(uint pos, const QString &str, bool cl int n = findInMask(i, true, true, str[(int)strIndex]); if (n != -1) { if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[(int)strIndex]))) { - s += fill.mid(i, n-i+1); + s += fill.midRef(i, n-i+1); i = n + 1; // update i to find + 1 } } else { // search for valid m_blank if not n = findInMask(i, true, false, str[(int)strIndex]); if (n != -1) { - s += fill.mid(i, n-i); + s += fill.midRef(i, n-i); switch (m_maskData[n].caseMode) { case MaskInputData::Upper: s += str[(int)strIndex].toUpper(); diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h index 00d9b2b0fa..6aaa630839 100644 --- a/src/quick/items/qquicktextinput_p_p.h +++ b/src/quick/items/qquicktextinput_p_p.h @@ -115,7 +115,11 @@ public: , vAlign(QQuickTextInput::AlignTop) , wrapMode(QQuickTextInput::NoWrap) , m_echoMode(QQuickTextInput::Normal) +#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE) + , renderType(QQuickTextInput::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE) +#else , renderType(QQuickTextInput::QtRendering) +#endif , updateType(UpdatePaintNode) , mouseSelectionMode(QQuickTextInput::SelectCharacters) , m_layoutDirection(Qt::LayoutDirectionAuto) diff --git a/src/quick/items/qquicktextnode_p.h b/src/quick/items/qquicktextnode_p.h index c6a1059e8a..01de0dbf2f 100644 --- a/src/quick/items/qquicktextnode_p.h +++ b/src/quick/items/qquicktextnode_p.h @@ -68,7 +68,7 @@ class QSGTexture; class QQuickTextNodeEngine; -class QQuickTextNode : public QSGTransformNode +class Q_QUICK_PRIVATE_EXPORT QQuickTextNode : public QSGTransformNode { public: enum Decoration { diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index 867f7d9d15..96f6b7ddd1 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -601,40 +601,30 @@ void QQuickView::resizeEvent(QResizeEvent *e) /*! \reimp */ void QQuickView::keyPressEvent(QKeyEvent *e) { - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>()); - QQuickWindow::keyPressEvent(e); } /*! \reimp */ void QQuickView::keyReleaseEvent(QKeyEvent *e) { - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>()); - QQuickWindow::keyReleaseEvent(e); } /*! \reimp */ void QQuickView::mouseMoveEvent(QMouseEvent *e) { - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); - QQuickWindow::mouseMoveEvent(e); } /*! \reimp */ void QQuickView::mousePressEvent(QMouseEvent *e) { - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); - QQuickWindow::mousePressEvent(e); } /*! \reimp */ void QQuickView::mouseReleaseEvent(QMouseEvent *e) { - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); - QQuickWindow::mouseReleaseEvent(e); } diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 6542bde4f1..9224c071fd 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -46,6 +46,7 @@ #include <private/qsgrenderloop_p.h> #include <private/qquickrendercontrol_p.h> #include <private/qquickanimatorcontroller_p.h> +#include <private/qquickprofiler_p.h> #include <private/qguiapplication_p.h> #include <QtGui/QInputMethod> @@ -1420,6 +1421,8 @@ bool QQuickWindow::event(QEvent *e) void QQuickWindow::keyPressEvent(QKeyEvent *e) { Q_D(QQuickWindow); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyPress, e->key(), + e->modifiers()); d->deliverKeyEvent(e); } @@ -1427,6 +1430,8 @@ void QQuickWindow::keyPressEvent(QKeyEvent *e) void QQuickWindow::keyReleaseEvent(QKeyEvent *e) { Q_D(QQuickWindow); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyRelease, e->key(), + e->modifiers()); d->deliverKeyEvent(e); } @@ -1524,6 +1529,8 @@ bool QQuickWindowPrivate::deliverMouseEvent(QMouseEvent *event) void QQuickWindow::mousePressEvent(QMouseEvent *event) { Q_D(QQuickWindow); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMousePress, event->button(), + event->buttons()); if (event->source() == Qt::MouseEventSynthesizedBySystem) { event->accept(); @@ -1538,6 +1545,8 @@ void QQuickWindow::mousePressEvent(QMouseEvent *event) void QQuickWindow::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickWindow); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseRelease, event->button(), + event->buttons()); if (event->source() == Qt::MouseEventSynthesizedBySystem) { event->accept(); @@ -1560,6 +1569,8 @@ void QQuickWindow::mouseReleaseEvent(QMouseEvent *event) void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event) { Q_D(QQuickWindow); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseDoubleClick, + event->button(), event->buttons()); if (event->source() == Qt::MouseEventSynthesizedBySystem) { event->accept(); @@ -1604,6 +1615,8 @@ bool QQuickWindowPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item, void QQuickWindow::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickWindow); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseMove, + event->localPos().x(), event->localPos().y()); if (event->source() == Qt::MouseEventSynthesizedBySystem) { event->accept(); @@ -1749,6 +1762,9 @@ bool QQuickWindowPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event void QQuickWindow::wheelEvent(QWheelEvent *event) { Q_D(QQuickWindow); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseWheel, + event->angleDelta().x(), event->angleDelta().y()); + qCDebug(DBG_MOUSE) << "QQuickWindow::wheelEvent()" << event->pixelDelta() << event->angleDelta() << event->phase(); //if the actual wheel event was accepted, accept the compatibility wheel event and return early diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp index ecf6865895..cabf0589e2 100644 --- a/src/quick/qtquick2.cpp +++ b/src/quick/qtquick2.cpp @@ -190,10 +190,6 @@ void QQmlQtQuick2Module::defineModule() QQmlEngineDebugService *debugService = QQmlDebugConnector::service<QQmlEngineDebugService>(); if (debugService) debugService->setStatesDelegate(new QQmlQtQuick2DebugStatesDelegate); - - QQmlProfilerService *profilerService = QQmlDebugConnector::service<QQmlProfilerService>(); - if (profilerService) - QQuickProfiler::initialize(profilerService); } void QQmlQtQuick2Module::undefineModule() diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp index 96b606aa3c..883657da24 100644 --- a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp +++ b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp @@ -71,7 +71,7 @@ QSGDistanceFieldGlyphCacheManager::QSGDistanceFieldGlyphCacheManager() QSGDistanceFieldGlyphCacheManager::~QSGDistanceFieldGlyphCacheManager() { - qDeleteAll(m_caches.values()); + qDeleteAll(m_caches); } QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCacheManager::cache(const QRawFont &font) diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index 0182f8abfb..d0330398e5 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -79,7 +79,8 @@ QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObje QQuickItem *item = qobject_cast<QQuickItem *>(ctx); if (item->window()) setWindow(item->window()); - connect(item, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(windowChanged(QQuickWindow*))); + + qmlobject_connect(item, QQuickItem, SIGNAL(windowChanged(QQuickWindow*)), this, QQuickAnimatorProxyJob, SLOT(windowChanged(QQuickWindow*))); } } diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index 2ea1a062d8..d1ca02d79f 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -231,10 +231,10 @@ public: int index3 = s.indexOf(QLatin1Char(','), index2+1); bool sGood, xGood, yGood, zGood; - qreal sCoord = s.left(index).toDouble(&sGood); - qreal xCoord = s.mid(index+1, index2-index-1).toDouble(&xGood); - qreal yCoord = s.mid(index2+1, index3-index2-1).toDouble(&yGood); - qreal zCoord = s.mid(index3+1).toDouble(&zGood); + qreal sCoord = s.leftRef(index).toDouble(&sGood); + qreal xCoord = s.midRef(index+1, index2-index-1).toDouble(&xGood); + qreal yCoord = s.midRef(index2+1, index3-index2-1).toDouble(&yGood); + qreal zCoord = s.midRef(index3+1).toDouble(&zGood); if (sGood && xGood && yGood && zGood) { if (ok) *ok = true; @@ -254,7 +254,7 @@ public: QString mutableStr = s; for (int i = 0; vOK && i < 16; ++i) { int cidx = mutableStr.indexOf(QLatin1Char(',')); - matValues[i] = mutableStr.left(cidx).toDouble(&vOK); + matValues[i] = mutableStr.leftRef(cidx).toDouble(&vOK); mutableStr = mutableStr.mid(cidx + 1); } diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp index 77ffda474a..cb6212196e 100644 --- a/src/quick/util/qquickprofiler.cpp +++ b/src/quick/util/qquickprofiler.cpp @@ -32,8 +32,11 @@ ****************************************************************************/ #include "qquickprofiler_p.h" -#include <QCoreApplication> -#include <private/qqmldebugserviceinterfaces_p.h> + +#include <QtQml/private/qqmlabstractprofileradapter_p.h> + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qthread.h> QT_BEGIN_NAMESPACE @@ -41,93 +44,10 @@ QT_BEGIN_NAMESPACE QQuickProfiler *QQuickProfiler::s_instance = 0; quint64 QQuickProfiler::featuresEnabled = 0; -// convert to QByteArrays that can be sent to the debug client -// use of QDataStream can skew results -// (see tst_qqmldebugtrace::trace() benchmark) -void QQuickProfilerData::toByteArrays(QList<QByteArray> &messages) const -{ - QByteArray data; - Q_ASSERT_X(((messageType | detailType) & (1 << 31)) == 0, Q_FUNC_INFO, "You can use at most 31 message types and 31 detail types."); - for (uint decodedMessageType = 0; (messageType >> decodedMessageType) != 0; ++decodedMessageType) { - if ((messageType & (1 << decodedMessageType)) == 0) - continue; - - for (uint decodedDetailType = 0; (detailType >> decodedDetailType) != 0; ++decodedDetailType) { - if ((detailType & (1 << decodedDetailType)) == 0) - continue; - - //### using QDataStream is relatively expensive - QQmlDebugStream ds(&data, QIODevice::WriteOnly); - ds << time << decodedMessageType << decodedDetailType; - - switch (decodedMessageType) { - case QQuickProfiler::Event: - if (decodedDetailType == (int)QQuickProfiler::AnimationFrame) - ds << framerate << count << threadId; - break; - case QQuickProfiler::PixmapCacheEvent: - ds << detailUrl.toString(); - switch (decodedDetailType) { - case QQuickProfiler::PixmapSizeKnown: ds << x << y; break; - case QQuickProfiler::PixmapReferenceCountChanged: ds << count; break; - case QQuickProfiler::PixmapCacheCountChanged: ds << count; break; - default: break; - } - break; - case QQuickProfiler::SceneGraphFrame: - switch (decodedDetailType) { - // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime - case QQuickProfiler::SceneGraphRendererFrame: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break; - // AdaptationLayerFrame: glyphCount (which is an integer), glyphRenderTime, glyphStoreTime - case QQuickProfiler::SceneGraphAdaptationLayerFrame: ds << subtime_3 << subtime_1 << subtime_2; break; - // ContextFrame: compiling material time - case QQuickProfiler::SceneGraphContextFrame: ds << subtime_1; break; - // RenderLoop: syncTime, renderTime, swapTime - case QQuickProfiler::SceneGraphRenderLoopFrame: ds << subtime_1 << subtime_2 << subtime_3; break; - // TexturePrepare: bind, convert, swizzle, upload, mipmap - case QQuickProfiler::SceneGraphTexturePrepare: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4 << subtime_5; break; - // TextureDeletion: deletionTime - case QQuickProfiler::SceneGraphTextureDeletion: ds << subtime_1; break; - // PolishAndSync: polishTime, waitTime, syncTime, animationsTime, - case QQuickProfiler::SceneGraphPolishAndSync: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break; - // WindowsRenderLoop: GL time, make current time, SceneGraph time - case QQuickProfiler::SceneGraphWindowsRenderShow: ds << subtime_1 << subtime_2 << subtime_3; break; - // WindowsAnimations: update time - case QQuickProfiler::SceneGraphWindowsAnimations: ds << subtime_1; break; - // non-threaded rendering: polish time - case QQuickProfiler::SceneGraphPolishFrame: ds << subtime_1; break; - default:break; - } - break; - default: - Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type."); - break; - } - messages << data; - data.clear(); - } - } -} - -qint64 QQuickProfiler::sendMessages(qint64 until, QList<QByteArray> &messages) -{ - QMutexLocker lock(&m_dataMutex); - while (next < m_data.size()) { - if (m_data[next].time <= until) - m_data[next++].toByteArrays(messages); - else - return m_data[next].time; - } - m_data.clear(); - next = 0; - return -1; -} - -void QQuickProfiler::initialize(QQmlProfilerService *service) +void QQuickProfiler::initialize(QObject *parent) { Q_ASSERT(s_instance == 0); - s_instance = new QQuickProfiler(service); - service->addGlobalProfiler(s_instance); + s_instance = new QQuickProfiler(parent); } void animationTimerCallback(qint64 delta) @@ -154,26 +74,10 @@ public slots: #include "qquickprofiler.moc" -QQuickProfiler::QQuickProfiler(QQmlProfilerService *service) : - QQmlAbstractProfilerAdapter(service), next(0) +QQuickProfiler::QQuickProfiler(QObject *parent) : QObject(parent) { // This is safe because at this point the m_instance isn't initialized, yet. m_timer.start(); - - // We can always do DirectConnection here as all methods are protected by mutexes - connect(this, SIGNAL(profilingEnabled(quint64)), this, SLOT(startProfilingImpl(quint64)), - Qt::DirectConnection); - connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)), - this, SLOT(startProfilingImpl(quint64)), Qt::DirectConnection); - connect(this, SIGNAL(referenceTimeKnown(QElapsedTimer)), this, SLOT(setTimer(QElapsedTimer)), - Qt::DirectConnection); - connect(this, SIGNAL(profilingDisabled()), this, SLOT(stopProfilingImpl()), - Qt::DirectConnection); - connect(this, SIGNAL(profilingDisabledWhileWaiting()), this, SLOT(stopProfilingImpl()), - Qt::DirectConnection); - connect(this, SIGNAL(dataRequested()), this, SLOT(reportDataImpl()), - Qt::DirectConnection); - CallbackRegistrationHelper *helper = new CallbackRegistrationHelper; // will delete itself helper->moveToThread(QCoreApplication::instance()->thread()); QMetaObject::invokeMethod(helper, "registerAnimationTimerCallback", Qt::QueuedConnection); @@ -189,7 +93,6 @@ QQuickProfiler::~QQuickProfiler() void QQuickProfiler::startProfilingImpl(quint64 features) { QMutexLocker lock(&m_dataMutex); - next = 0; m_data.clear(); featuresEnabled = features; } @@ -200,12 +103,12 @@ void QQuickProfiler::stopProfilingImpl() QMutexLocker lock(&m_dataMutex); featuresEnabled = 0; } - service->dataReady(this); + emit dataReady(m_data); } void QQuickProfiler::reportDataImpl() { - service->dataReady(this); + emit dataReady(m_data); } void QQuickProfiler::setTimer(const QElapsedTimer &t) diff --git a/src/quick/util/qquickprofiler_p.h b/src/quick/util/qquickprofiler_p.h index 6b6e7fa062..4983adf63b 100644 --- a/src/quick/util/qquickprofiler_p.h +++ b/src/quick/util/qquickprofiler_p.h @@ -45,13 +45,14 @@ // We mean it. // -#include <private/qtquickglobal_p.h> #include <QtCore/private/qabstractanimation_p.h> -#include <QtQml/private/qqmlabstractprofileradapter_p.h> -#include <QUrl> -#include <QSize> -#include <QMutex> -#include <QThreadStorage> +#include <QtQml/private/qqmlprofilerdefinitions_p.h> +#include <QtQuick/private/qtquickglobal_p.h> + +#include <QtCore/qurl.h> +#include <QtCore/qsize.h> +#include <QtCore/qmutex.h> +#include <QtCore/qthreadstorage.h> QT_BEGIN_NAMESPACE @@ -97,8 +98,9 @@ QT_BEGIN_NAMESPACE (QQuickProfiler::reportSceneGraphFrame<Type, true>(Payload))) -#define Q_QUICK_INPUT_PROFILE(Method)\ - Q_QUICK_PROFILE(QQuickProfiler::ProfileInputEvents, Method) +#define Q_QUICK_INPUT_PROFILE(Type, DetailType, A, B)\ + Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileInputEvents,\ + (QQuickProfiler::inputEvent<Type, DetailType>(A, B))) // This struct is somewhat dangerous to use: // You can save values either with 32 or 64 bit precision. toByteArrays will @@ -117,10 +119,10 @@ struct Q_AUTOTEST_EXPORT QQuickProfilerData time(time), messageType(messageType), detailType(detailType), detailUrl(url), x(x), y(y), framerate(framerate), count(count) {} - QQuickProfilerData(qint64 time, int messageType, int detailType, int framerate = 0, - int count = 0, int threadId = 0) : - time(time), messageType(messageType), detailType(detailType), framerate(framerate), - count(count), threadId(threadId) {} + QQuickProfilerData(qint64 time, int messageType, int detailType, int framerateOrInputType = 0, + int countOrInputA = 0, int threadIdOrInputB = 0) : + time(time), messageType(messageType), detailType(detailType), + framerate(framerateOrInputType), count(countOrInputA), threadId(threadIdOrInputB) {} // Special ctor for scenegraph frames. Note that it's missing the QString/QUrl params. // This is slightly ugly, but makes it easier to disambiguate between int and qint64 params. @@ -149,19 +151,20 @@ struct Q_AUTOTEST_EXPORT QQuickProfilerData union { qint64 subtime_3; int framerate; //used by animation events + int inputType; }; union { qint64 subtime_4; int count; //used by animation events and for pixmaps + int inputA; //used by input events }; union { qint64 subtime_5; int threadId; + int inputB; //used by input events }; - - void toByteArrays(QList<QByteArray> &messages) const; }; Q_DECLARE_TYPEINFO(QQuickProfilerData, Q_MOVABLE_TYPE); @@ -199,7 +202,7 @@ public: } }; -class Q_QUICK_PRIVATE_EXPORT QQuickProfiler : public QQmlAbstractProfilerAdapter { +class Q_QUICK_PRIVATE_EXPORT QQuickProfiler : public QObject, public QQmlProfilerDefinitions { Q_OBJECT public: @@ -208,11 +211,11 @@ public: RenderThread }; - template<EventType DetailType> - static void addEvent() + template<EventType DetailType, InputEventType InputType> + static void inputEvent(int x, int y = 0) { s_instance->processMessage(QQuickProfilerData(s_instance->timestamp(), 1 << Event, - 1 << DetailType)); + 1 << DetailType, InputType, x, y)); } static void animationFrame(qint64 delta, AnimationThread threadId) @@ -310,7 +313,6 @@ public: qint64 timestamp() { return m_timer.nsecsElapsed(); } - qint64 sendMessages(qint64 until, QList<QByteArray> &messages); static quint64 featuresEnabled; static bool profilingSceneGraph() @@ -318,19 +320,20 @@ public: return featuresEnabled & (1 << QQuickProfiler::ProfileSceneGraph); } - static void initialize(QQmlProfilerService *service); + static void initialize(QObject *parent); virtual ~QQuickProfiler(); protected: - int next; + friend class QQuickProfilerAdapter; + static QQuickProfiler *s_instance; QMutex m_dataMutex; QElapsedTimer m_timer; - QVarLengthArray<QQuickProfilerData> m_data; + QVector<QQuickProfilerData> m_data; QQuickProfilerSceneGraphData m_sceneGraphData; - QQuickProfiler(QQmlProfilerService *service); + QQuickProfiler(QObject *parent); void processMessage(const QQuickProfilerData &message) { @@ -338,6 +341,9 @@ protected: m_data.append(message); } +signals: + void dataReady(const QVector<QQuickProfilerData> &data); + protected slots: void startProfilingImpl(quint64 features); void stopProfilingImpl(); diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index cc7ece9c5b..875b68b3ac 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -1039,7 +1039,8 @@ void QQuickWidget::resizeEvent(QResizeEvent *e) void QQuickWidget::keyPressEvent(QKeyEvent *e) { Q_D(QQuickWidget); - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>()); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyPress, e->key(), + e->modifiers()); QCoreApplication::sendEvent(d->offscreenWindow, e); } @@ -1048,7 +1049,8 @@ void QQuickWidget::keyPressEvent(QKeyEvent *e) void QQuickWidget::keyReleaseEvent(QKeyEvent *e) { Q_D(QQuickWidget); - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>()); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Key, QQuickProfiler::InputKeyRelease, e->key(), + e->modifiers()); QCoreApplication::sendEvent(d->offscreenWindow, e); } @@ -1057,7 +1059,8 @@ void QQuickWidget::keyReleaseEvent(QKeyEvent *e) void QQuickWidget::mouseMoveEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseMove, e->localPos().x(), + e->localPos().y()); // Use the constructor taking localPos and screenPos. That puts localPos into the // event's localPos and windowPos, and screenPos into the event's screenPos. This way @@ -1072,7 +1075,8 @@ void QQuickWidget::mouseMoveEvent(QMouseEvent *e) void QQuickWidget::mouseDoubleClickEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseDoubleClick, + e->button(), e->buttons()); // As the second mouse press is suppressed in widget windows we emulate it here for QML. // See QTBUG-25831 @@ -1120,7 +1124,8 @@ void QQuickWidget::hideEvent(QHideEvent *) void QQuickWidget::mousePressEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMousePress, e->button(), + e->buttons()); QMouseEvent mappedEvent(e->type(), e->localPos(), e->screenPos(), e->button(), e->buttons(), e->modifiers()); QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent); @@ -1131,7 +1136,8 @@ void QQuickWidget::mousePressEvent(QMouseEvent *e) void QQuickWidget::mouseReleaseEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseRelease, e->button(), + e->buttons()); QMouseEvent mappedEvent(e->type(), e->localPos(), e->screenPos(), e->button(), e->buttons(), e->modifiers()); QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent); @@ -1143,7 +1149,8 @@ void QQuickWidget::mouseReleaseEvent(QMouseEvent *e) void QQuickWidget::wheelEvent(QWheelEvent *e) { Q_D(QQuickWidget); - Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseWheel, + e->angleDelta().x(), e->angleDelta().y()); // Wheel events only have local and global positions, no need to map. QCoreApplication::sendEvent(d->offscreenWindow, e); diff --git a/src/src.pro b/src/src.pro index ac48f017e6..18e9ba6704 100644 --- a/src/src.pro +++ b/src/src.pro @@ -14,6 +14,7 @@ qtHaveModule(gui):contains(QT_CONFIG, opengl(es1|es2)?) { SUBDIRS += \ plugins \ + qmldebug \ imports \ qmldevtools diff --git a/sync.profile b/sync.profile index 28d0698da9..46280ade96 100644 --- a/sync.profile +++ b/sync.profile @@ -5,6 +5,8 @@ "QtQuickParticles" => "$basedir/src/particles", "QtQuickTest" => "$basedir/src/qmltest", "QtQmlDevTools" => "$basedir/src/qmldevtools", + "QtPacketProtocol" => "$basedir/src/plugins/qmltooling/packetprotocol", + "QtQmlDebug" => "$basedir/src/qmldebug", ); %moduleheaders = ( # restrict the module headers to those found in relative path "QtQmlDevTools" => "../qml/parser;../qml/jsruntime;../qml/qml/ftw;../qml/compiler;../qml/memory;.", diff --git a/tests/auto/particles/qquickage/qquickage.pro b/tests/auto/particles/qquickage/qquickage.pro index 3fffb28f31..557daac86f 100644 --- a/tests/auto/particles/qquickage/qquickage.pro +++ b/tests/auto/particles/qquickage/qquickage.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro b/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro index 4533f94388..b813b64a3c 100644 --- a/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro +++ b/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro b/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro index ba4a6ba9d9..145bffd3b3 100644 --- a/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro +++ b/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro b/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro index 9442a29fb9..01a831ca9c 100644 --- a/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro +++ b/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro b/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro index 48e7303f86..d02b45457a 100644 --- a/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro +++ b/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro @@ -1,5 +1,4 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qquickcustomparticle SOURCES += tst_qquickcustomparticle.cpp macx:CONFIG -= app_bundle @@ -9,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro b/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro index 324b980e78..a1d79daca7 100644 --- a/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro +++ b/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickfriction/qquickfriction.pro b/tests/auto/particles/qquickfriction/qquickfriction.pro index b90b31ece2..8a15dee4c4 100644 --- a/tests/auto/particles/qquickfriction/qquickfriction.pro +++ b/tests/auto/particles/qquickfriction/qquickfriction.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickgravity/qquickgravity.pro b/tests/auto/particles/qquickgravity/qquickgravity.pro index 07c9eba314..899d58ed38 100644 --- a/tests/auto/particles/qquickgravity/qquickgravity.pro +++ b/tests/auto/particles/qquickgravity/qquickgravity.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro b/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro index 31b6fa5457..3236231f14 100644 --- a/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro +++ b/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private testlib quick-private quickparticles-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro b/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro index 271b2ec57c..cf0f81f0ff 100644 --- a/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro +++ b/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro @@ -7,4 +7,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro b/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro index 7db55d29e9..8c39fc9736 100644 --- a/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro +++ b/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro @@ -1,5 +1,4 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qquickitemparticle SOURCES += tst_qquickitemparticle.cpp macx:CONFIG -= app_bundle @@ -9,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro b/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro index 85e98f3cd4..2ccc5b3765 100644 --- a/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro +++ b/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro b/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro index d83006e523..cf63196539 100644 --- a/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro +++ b/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro b/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro index 3d98e5f3bd..06febb3825 100644 --- a/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro +++ b/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro b/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro index d3aeaecdca..f076d6f0c0 100644 --- a/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro +++ b/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro b/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro index 60b1c1fc7f..2d2c4f375d 100644 --- a/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro +++ b/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro b/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro index e61527a11d..8174e52964 100644 --- a/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro +++ b/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro b/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro index a8b2c1ca95..add9981d0b 100644 --- a/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro +++ b/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro b/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro index eb127c5fc2..f5a5f745bd 100644 --- a/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro +++ b/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private testlib quick-private quickparticles-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro b/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro index 9fe6747378..e8c5c2d33d 100644 --- a/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro +++ b/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro b/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro index 1cb792eff2..2f54e13000 100644 --- a/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro +++ b/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickturbulence/qquickturbulence.pro b/tests/auto/particles/qquickturbulence/qquickturbulence.pro index 2db3d54e4c..8758a5203b 100644 --- a/tests/auto/particles/qquickturbulence/qquickturbulence.pro +++ b/tests/auto/particles/qquickturbulence/qquickturbulence.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/particles/qquickwander/qquickwander.pro b/tests/auto/particles/qquickwander/qquickwander.pro index 41171645a2..58da3f39d8 100644 --- a/tests/auto/particles/qquickwander/qquickwander.pro +++ b/tests/auto/particles/qquickwander/qquickwander.pro @@ -8,4 +8,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/animation/qabstractanimationjob/qabstractanimationjob.pro b/tests/auto/qml/animation/qabstractanimationjob/qabstractanimationjob.pro index f63a437c54..f7ba4c275c 100644 --- a/tests/auto/qml/animation/qabstractanimationjob/qabstractanimationjob.pro +++ b/tests/auto/qml/animation/qabstractanimationjob/qabstractanimationjob.pro @@ -1,6 +1,5 @@ -CONFIG += testcase parallel_test +CONFIG += testcase macx:CONFIG -= app_bundle TARGET = tst_qabstractanimationjob QT = core-private qml-private testlib SOURCES = tst_qabstractanimationjob.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/animation/qanimationgroupjob/qanimationgroupjob.pro b/tests/auto/qml/animation/qanimationgroupjob/qanimationgroupjob.pro index 136999ce13..0c52094bfd 100644 --- a/tests/auto/qml/animation/qanimationgroupjob/qanimationgroupjob.pro +++ b/tests/auto/qml/animation/qanimationgroupjob/qanimationgroupjob.pro @@ -1,6 +1,5 @@ -CONFIG += testcase parallel_test +CONFIG += testcase macx:CONFIG -= app_bundle TARGET = tst_qanimationgroupjob QT = core-private qml-private testlib SOURCES = tst_qanimationgroupjob.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/animation/qparallelanimationgroupjob/qparallelanimationgroupjob.pro b/tests/auto/qml/animation/qparallelanimationgroupjob/qparallelanimationgroupjob.pro index 2cc057cb90..982aafbfe7 100644 --- a/tests/auto/qml/animation/qparallelanimationgroupjob/qparallelanimationgroupjob.pro +++ b/tests/auto/qml/animation/qparallelanimationgroupjob/qparallelanimationgroupjob.pro @@ -1,7 +1,5 @@ CONFIG += testcase -CONFIG += parallel_test macx:CONFIG -= app_bundle TARGET = tst_qparallelanimationgroupjob QT = core-private gui qml-private testlib gui-private SOURCES = tst_qparallelanimationgroupjob.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/animation/qpauseanimationjob/qpauseanimationjob.pro b/tests/auto/qml/animation/qpauseanimationjob/qpauseanimationjob.pro index 7102096384..b80bb0c55c 100644 --- a/tests/auto/qml/animation/qpauseanimationjob/qpauseanimationjob.pro +++ b/tests/auto/qml/animation/qpauseanimationjob/qpauseanimationjob.pro @@ -1,7 +1,5 @@ CONFIG += testcase -CONFIG += parallel_test macx:CONFIG -= app_bundle TARGET = tst_qpauseanimationjob QT = core-private gui-private qml-private testlib SOURCES = tst_qpauseanimationjob.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/animation/qsequentialanimationgroupjob/qsequentialanimationgroupjob.pro b/tests/auto/qml/animation/qsequentialanimationgroupjob/qsequentialanimationgroupjob.pro index eda764cedd..370d33607b 100644 --- a/tests/auto/qml/animation/qsequentialanimationgroupjob/qsequentialanimationgroupjob.pro +++ b/tests/auto/qml/animation/qsequentialanimationgroupjob/qsequentialanimationgroupjob.pro @@ -1,6 +1,5 @@ -CONFIG += testcase parallel_test +CONFIG += testcase macx:CONFIG -= app_bundle TARGET = tst_qsequentialanimationgroupjob QT = core-private qml-private testlib SOURCES = tst_qsequentialanimationgroupjob.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro index 6b47801720..ccb2d71c53 100644 --- a/tests/auto/qml/debugger/debugger.pro +++ b/tests/auto/qml/debugger/debugger.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs PUBLICTESTS += \ + qdebugmessageservice \ qqmlenginedebugservice \ qqmldebugjs \ qqmlinspector \ @@ -14,7 +15,8 @@ PUBLICTESTS += \ PRIVATETESTS += \ qqmldebugclient \ qqmldebuglocal \ - qqmldebugservice + qqmldebugservice \ + qv4debugger SUBDIRS += $$PUBLICTESTS diff --git a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro index 0d6484f8e6..6c729ab235 100644 --- a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro +++ b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro @@ -1,7 +1,7 @@ CONFIG += testcase TARGET = tst_qdebugmessageservice QT += qml network testlib gui-private core-private -macx:CONFIG -= app_bundle +osx:CONFIG -= app_bundle SOURCES += tst_qdebugmessageservice.cpp @@ -12,4 +12,3 @@ include(../shared/debugutil.pri) TESTDATA = data/* OTHER_FILES += data/test.qml -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp index d0801dd4ee..75c301f958 100644 --- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp +++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp @@ -31,14 +31,17 @@ ** ****************************************************************************/ -#include "qqmldebugclient.h" - //QQmlDebugTest #include "debugutil_p.h" #include "../../../shared/util.h" -#include <QtCore/QString> -#include <QtTest/QtTest> +#include <private/qqmldebugclient_p.h> +#include <private/qqmldebugconnection_p.h> +#include <private/qpacket_p.h> + +#include <QtCore/qstring.h> +#include <QtCore/qlibraryinfo.h> +#include <QtTest/qtest.h> const char *NORMALMODE = "-qmljsdebugger=port:3777,3787,block"; const char *QMLFILE = "test.qml"; @@ -76,15 +79,19 @@ struct LogEntry { int line; QString file; QString function; + QString category; - QString toString() const { return QString::number(type) + ": " + message; } + QString toString() const + { + return QString::number(type) + ": " + message + " (" + category + ")"; + } }; bool operator==(const LogEntry &t1, const LogEntry &t2) { return t1.type == t2.type && t1.message == t2.message && t1.line == t2.line && t1.file == t2.file - && t1.function == t2.function; + && t1.function == t2.function && t1.category == t2.category; } class QQmlDebugMsgClient : public QQmlDebugClient @@ -117,7 +124,7 @@ void QQmlDebugMsgClient::stateChanged(State state) void QQmlDebugMsgClient::messageReceived(const QByteArray &data) { - QDataStream ds(data); + QPacket ds(connection()->currentDataStreamVersion(), data); QByteArray command; ds >> command; @@ -126,17 +133,21 @@ void QQmlDebugMsgClient::messageReceived(const QByteArray &data) QByteArray message; QByteArray file; QByteArray function; + QByteArray category; + qint64 timestamp; int line; - ds >> type >> message >> file >> line >> function; + ds >> type >> message >> file >> line >> function >> category >> timestamp; QVERIFY(ds.atEnd()); QVERIFY(type >= QtDebugMsg); QVERIFY(type <= QtFatalMsg); + QVERIFY(timestamp > 0); LogEntry entry((QtMsgType)type, QString::fromUtf8(message)); entry.line = line; entry.file = QString::fromUtf8(file); entry.function = QString::fromUtf8(function); + entry.category = QString::fromUtf8(category); logBuffer << entry; emit debugOutput(); } else { @@ -212,23 +223,20 @@ void tst_QDebugMessageService::retrieveDebugOutput() { init(); - int maxTries = 2; - while ((m_client->logBuffer.size() < 2) - || (maxTries-- > 0)) - QQmlDebugTest::waitForSignal(m_client, SIGNAL(debugOutput()), 1000); - - QVERIFY(m_client->logBuffer.size() >= 2); + QTRY_VERIFY(m_client->logBuffer.size() >= 2); const QString path = QUrl::fromLocalFile(QQmlDataTest::instance()->testFile(QMLFILE)).toString(); LogEntry entry1(QtDebugMsg, QLatin1String("console.log")); - entry1.line = 48; + entry1.line = 40; entry1.file = path; entry1.function = QLatin1String("onCompleted"); + entry1.category = QLatin1String("qml"); LogEntry entry2(QtDebugMsg, QLatin1String("console.count: 1")); - entry2.line = 49; + entry2.line = 41; entry2.file = path; entry2.function = QLatin1String("onCompleted"); + entry2.category = QLatin1String("default"); QVERIFY(m_client->logBuffer.contains(entry1)); QVERIFY(m_client->logBuffer.contains(entry2)); diff --git a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro index 716d8f0be9..a7c0fa7f8e 100644 --- a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro +++ b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro @@ -1,12 +1,10 @@ CONFIG += testcase TARGET = tst_qpacketprotocol -macx:CONFIG -= app_bundle +osx:CONFIG -= app_bundle SOURCES += tst_qpacketprotocol.cpp INCLUDEPATH += ../shared include(../shared/debugutil.pri) -CONFIG += parallel_test QT += qml network testlib gui-private core-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp index db9e621d54..b68cc5d6c9 100644 --- a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp +++ b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp @@ -38,7 +38,8 @@ #include <QDebug> #include <QBuffer> -#include "../../../../../src/plugins/qmltooling/shared/qpacketprotocol.h" +#include <private/qpacketprotocol_p.h> +#include <private/qpacket_p.h> #include "debugutil_p.h" @@ -55,18 +56,10 @@ private slots: void init(); void cleanup(); - void maximumPacketSize(); - void setMaximumPacketSize(); - void setMaximumPacketSize_data(); void send(); - void send_data(); void packetsAvailable(); void packetsAvailable_data(); - void clear(); void read(); - void device(); - - void tst_QPacket_clear(); }; void tst_QPacketProtocol::init() @@ -95,65 +88,26 @@ void tst_QPacketProtocol::cleanup() delete m_server; } -void tst_QPacketProtocol::maximumPacketSize() -{ - QPacketProtocol p(m_client); - QCOMPARE(p.maximumPacketSize(), 0x7FFFFFFF); -} - -void tst_QPacketProtocol::setMaximumPacketSize() -{ - QFETCH(qint32, size); - QFETCH(qint32, expected); - - QPacketProtocol out(m_serverConn); - QCOMPARE(out.setMaximumPacketSize(size), expected); -} - -void tst_QPacketProtocol::setMaximumPacketSize_data() -{ - QTest::addColumn<int>("size"); - QTest::addColumn<int>("expected"); - - QTest::newRow("invalid") << qint32(sizeof(qint32) - 1) << qint32(0x7FFFFFFF); - QTest::newRow("still invalid") << qint32(sizeof(qint32)) << qint32(0x7FFFFFFF); - QTest::newRow("valid") << qint32(sizeof(qint32) + 1) << qint32(sizeof(qint32) + 1); -} - void tst_QPacketProtocol::send() { - QFETCH(bool, useAutoSend); - QPacketProtocol in(m_client); QPacketProtocol out(m_serverConn); QByteArray ba; int num; - if (useAutoSend) { - out.send() << "Hello world" << 123; - } else { - QPacket packet; - packet << "Hello world" << 123; - out.send(packet); - } + QPacket packet(QDataStream::Qt_DefaultCompiledVersion); + packet << "Hello world" << 123; + out.send(packet.data()); QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); - QPacket p = in.read(); + QPacket p(QDataStream::Qt_DefaultCompiledVersion, in.read()); p >> ba >> num; QCOMPARE(ba, QByteArray("Hello world") + '\0'); QCOMPARE(num, 123); } -void tst_QPacketProtocol::send_data() -{ - QTest::addColumn<bool>("useAutoSend"); - - QTest::newRow("auto send") << true; - QTest::newRow("no auto send") << false; -} - void tst_QPacketProtocol::packetsAvailable() { QFETCH(int, packetCount); @@ -164,8 +118,11 @@ void tst_QPacketProtocol::packetsAvailable() QCOMPARE(out.packetsAvailable(), qint64(0)); QCOMPARE(in.packetsAvailable(), qint64(0)); - for (int i=0; i<packetCount; i++) - out.send() << "Hello"; + for (int i=0; i<packetCount; i++) { + QPacket packet(QDataStream::Qt_DefaultCompiledVersion); + packet << "Hello"; + out.send(packet.data()); + } QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); QCOMPARE(in.packetsAvailable(), qint64(packetCount)); @@ -180,19 +137,6 @@ void tst_QPacketProtocol::packetsAvailable_data() QTest::newRow("10") << 10; } -void tst_QPacketProtocol::clear() -{ - QPacketProtocol in(m_client); - QPacketProtocol out(m_serverConn); - - out.send() << 123; - out.send() << 456; - QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); - - in.clear(); - QVERIFY(in.read().isEmpty()); -} - void tst_QPacketProtocol::read() { QPacketProtocol in(m_client); @@ -200,61 +144,30 @@ void tst_QPacketProtocol::read() QVERIFY(in.read().isEmpty()); - out.send() << 123; - out.send() << 456; + QPacket packet(QDataStream::Qt_DefaultCompiledVersion); + packet << 123; + out.send(packet.data()); + + QPacket packet2(QDataStream::Qt_DefaultCompiledVersion); + packet2 << 456; + out.send(packet2.data()); QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); int num; - QPacket p1 = in.read(); - QVERIFY(!p1.isEmpty()); + QPacket p1(QDataStream::Qt_DefaultCompiledVersion, in.read()); + QVERIFY(!p1.atEnd()); p1 >> num; QCOMPARE(num, 123); - QPacket p2 = in.read(); - QVERIFY(!p2.isEmpty()); + QPacket p2(QDataStream::Qt_DefaultCompiledVersion, in.read()); + QVERIFY(!p2.atEnd()); p2 >> num; QCOMPARE(num, 456); QVERIFY(in.read().isEmpty()); } -void tst_QPacketProtocol::device() -{ - QPacketProtocol p(m_client); - QCOMPARE(p.device(), m_client); -} - -void tst_QPacketProtocol::tst_QPacket_clear() -{ - QPacketProtocol protocol(m_client); - - QPacket packet; - - packet << "Hello world!" << 123; - protocol.send(packet); - - packet.clear(); - QVERIFY(packet.isEmpty()); - packet << "Goodbyte world!" << 789; - protocol.send(packet); - - QByteArray ba; - int num; - QPacketProtocol in(m_serverConn); - QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); - - QPacket p1 = in.read(); - p1 >> ba >> num; - QCOMPARE(ba, QByteArray("Hello world!") + '\0'); - QCOMPARE(num, 123); - - QPacket p2 = in.read(); - p2 >> ba >> num; - QCOMPARE(ba, QByteArray("Goodbyte world!") + '\0'); - QCOMPARE(num, 789); -} - QTEST_MAIN(tst_QPacketProtocol) #include "tst_qpacketprotocol.moc" diff --git a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro index ad431d4871..622b373692 100644 --- a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro +++ b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qqmldebugclient -macx:CONFIG -= app_bundle +osx:CONFIG -= app_bundle HEADERS += ../shared/qqmldebugtestservice.h @@ -15,4 +15,3 @@ DEFINES += QT_QML_DEBUG_NO_WARNING CONFIG += qml_debug QT += qml-private testlib gui-private core-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp index 6fc6c6a914..1bf03dbdee 100644 --- a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp +++ b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp @@ -30,19 +30,20 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include <qtest.h> -#include <QSignalSpy> -#include <QTimer> -#include <QHostAddress> -#include <QDebug> -#include <QThread> - -#include <QtQml/qqmlengine.h> #include "debugutil_p.h" #include "qqmldebugtestservice.h" #include <private/qqmldebugconnector_p.h> +#include <private/qqmldebugconnection_p.h> + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtCore/qtimer.h> +#include <QtCore/qdebug.h> +#include <QtCore/qthread.h> +#include <QtNetwork/qhostaddress.h> +#include <QtQml/qqmlengine.h> #define PORT 13770 #define STR_PORT "13770" @@ -68,10 +69,20 @@ private slots: void tst_QQmlDebugClient::initTestCase() { QQmlDebugConnector::setPluginKey(QLatin1String("QQmlDebugServer")); + QQmlDebugConnector::setServices(QStringList() + << QStringLiteral("tst_QQmlDebugClient::handshake()")); QTest::ignoreMessage(QtWarningMsg, "QML debugger: Cannot set plugin key after loading the plugin."); m_service = new QQmlDebugTestService("tst_QQmlDebugClient::handshake()"); + + foreach (const QString &service, QQmlDebuggingEnabler::debuggerServices()) + QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0); + foreach (const QString &service, QQmlDebuggingEnabler::inspectorServices()) + QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0); + foreach (const QString &service, QQmlDebuggingEnabler::profilerServices()) + QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0); + const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT); QTest::ignoreMessage(QtDebugMsg, waitingMsg.toLatin1().constData()); QQmlDebuggingEnabler::startTcpDebugServer(PORT); @@ -144,7 +155,9 @@ void tst_QQmlDebugClient::parallelConnect() QTest::ignoreMessage(QtWarningMsg, "QML Debugger: Another client is already connected."); // will connect & immediately disconnect connection2.connectToHost("127.0.0.1", PORT); - QTRY_COMPARE(connection2.state(), QAbstractSocket::UnconnectedState); + QTest::ignoreMessage(QtWarningMsg, "QQmlDebugConnection: Did not get handshake answer in time"); + QVERIFY(!connection2.waitForConnected(1000)); + QVERIFY(!connection2.isConnected()); QVERIFY(m_conn->isConnected()); } @@ -155,7 +168,6 @@ void tst_QQmlDebugClient::sequentialConnect() m_conn->close(); QVERIFY(!m_conn->isConnected()); - QCOMPARE(m_conn->state(), QAbstractSocket::UnconnectedState); // Make sure that the disconnect is actually delivered to the server QTest::qWait(100); diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp index 98ef590317..27a64842e9 100644 --- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp +++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp @@ -31,18 +31,20 @@ ** ****************************************************************************/ -#include <qtest.h> -#include <QtCore/QProcess> -#include <QtCore/QTimer> -#include <QtCore/QFileInfo> -#include <QtCore/QDir> -#include <QtCore/QMutex> -#include <QtCore/QLibraryInfo> - #include "debugutil_p.h" -#include "qqmldebugclient.h" #include "../../../shared/util.h" +#include <private/qqmldebugclient_p.h> +#include <private/qqmldebugconnection_p.h> + +#include <QtTest/qtest.h> +#include <QtCore/qprocess.h> +#include <QtCore/qtimer.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qdir.h> +#include <QtCore/qmutex.h> +#include <QtCore/qlibraryinfo.h> + class tst_QQmlDebuggingEnabler : public QQmlDataTest { Q_OBJECT @@ -53,13 +55,14 @@ private slots: void initTestCase(); void cleanupTestCase(); void cleanup(); - void qmlscene(); - void qmlsceneBlock(); + void qmlscene_data(); + void qmlscene(); + void custom_data(); void custom(); - void customBlock(); private: + void data(); QQmlDebugProcess *process; QQmlDebugConnection *connection; QTime t; @@ -142,24 +145,92 @@ void tst_QQmlDebuggingEnabler::cleanup() connection = 0; } -void tst_QQmlDebuggingEnabler::qmlscene() +void tst_QQmlDebuggingEnabler::data() { - QVERIFY(init(false, true, 5555, 5565)); + QTest::addColumn<bool>("blockMode"); + QTest::addColumn<QStringList>("services"); + + QTest::newRow("noblock,all") << false << QStringList(); + QTest::newRow("block,all") << true << QStringList(); + QTest::newRow("noblock,debugger") << false << QQmlDebuggingEnabler::debuggerServices(); + QTest::newRow("block,debugger") << true << QQmlDebuggingEnabler::debuggerServices(); + QTest::newRow("noblock,inspector") << false << QQmlDebuggingEnabler::inspectorServices(); + QTest::newRow("block,inspector") << true << QQmlDebuggingEnabler::inspectorServices(); + QTest::newRow("noblock,profiler") << false << QQmlDebuggingEnabler::profilerServices(); + QTest::newRow("block,profiler") << true << QQmlDebuggingEnabler::profilerServices(); + QTest::newRow("noblock,debugger+inspector") + << false << QQmlDebuggingEnabler::debuggerServices() + + QQmlDebuggingEnabler::inspectorServices(); + QTest::newRow("block,debugger+inspector") + << true << QQmlDebuggingEnabler::debuggerServices() + + QQmlDebuggingEnabler::inspectorServices(); + } -void tst_QQmlDebuggingEnabler::qmlsceneBlock() +void tst_QQmlDebuggingEnabler::qmlscene_data() { - QVERIFY(init(true, true, 5555, 5565)); + data(); } -void tst_QQmlDebuggingEnabler::custom() +void tst_QQmlDebuggingEnabler::qmlscene() { - QVERIFY(init(false, false, 5555, 5565)); + QFETCH(bool, blockMode); + QFETCH(QStringList, services); + + connection = new QQmlDebugConnection(); + QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection); + process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", + this); + process->setMaximumBindErrors(1); + process->start(QStringList() + << QString::fromLatin1("-qmljsdebugger=port:5555,5565%1%2%3") + .arg(blockMode ? QLatin1String(",block") : QString()) + .arg(services.isEmpty() ? QString() : QString::fromLatin1(",services:")) + .arg(services.isEmpty() ? QString() : services.join(",")) + << testFile(QLatin1String("test.qml"))); + + QVERIFY(process->waitForSessionStart()); + connection->connectToHost("127.0.0.1", process->debugPort()); + QVERIFY(connection->waitForConnected()); + foreach (QQmlDebugClient *client, clients) + QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ? + QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable); +} + +void tst_QQmlDebuggingEnabler::custom_data() +{ + data(); } -void tst_QQmlDebuggingEnabler::customBlock() +void tst_QQmlDebuggingEnabler::custom() { - QVERIFY(init(true, false, 5555, 5565)); + QFETCH(bool, blockMode); + QFETCH(QStringList, services); + const int portFrom = 5555; + const int portTo = 5565; + + connection = new QQmlDebugConnection(); + QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection); + process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() + + QLatin1String("/qqmldebuggingenablerserver"), this); + process->setMaximumBindErrors(portTo - portFrom); + + QStringList args; + if (blockMode) + args << QLatin1String("-block"); + + args << QString::number(portFrom) << QString::number(portTo); + if (!services.isEmpty()) + args << QLatin1String("-services") << services; + + process->start(args); + + QVERIFY(process->waitForSessionStart()); + connection->connectToHost("127.0.0.1", process->debugPort()); + QVERIFY(connection->waitForConnected()); + foreach (QQmlDebugClient *client, clients) + QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ? + QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable); } QTEST_MAIN(tst_QQmlDebuggingEnabler) diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp index bddece6452..f4fef7ff16 100644 --- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp +++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.cpp @@ -31,8 +31,10 @@ ** ****************************************************************************/ -#include "debugutil_p.h" -#include <QtCore/QCoreApplication> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qlibraryinfo.h> +#include <QtQml/qqmldebug.h> +#include <QtQml/qqmlengine.h> int main(int argc, char *argv[]) { @@ -54,6 +56,9 @@ int main(int argc, char *argv[]) portTo = arguments.takeFirst().toInt(); } + if (arguments.size() && arguments.takeFirst() == QLatin1String("-services")) + QQmlDebuggingEnabler::setServices(arguments); + if (!portFrom || !portTo) qFatal("Port range has to be specified."); diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.pro b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.pro index fdd9ce8f11..a40ff6978b 100644 --- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.pro +++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenablerserver/qqmldebuggingenablerserver.pro @@ -3,7 +3,7 @@ osx:CONFIG -= app_bundle CONFIG -= debug_and_release_target INCLUDEPATH += ../../shared SOURCES += qqmldebuggingenablerserver.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 QT_QML_DEBUG_NO_WARNING +DEFINES += QT_QML_DEBUG_NO_WARNING DESTDIR = ../qqmldebuggingenabler diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro index fb06df9c99..4b3e204dd8 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro @@ -1,7 +1,7 @@ CONFIG += testcase TARGET = tst_qqmldebugjs QT += qml testlib gui-private core-private -macx:CONFIG -= app_bundle +osx:CONFIG -= app_bundle SOURCES += tst_qqmldebugjs.cpp @@ -21,4 +21,3 @@ OTHER_FILES += data/test.qml data/test.js \ data/stepAction.qml \ data/breakpointRelocation.qml \ data/createComponent.qml -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index 7dbe35807d..13674fdb61 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -31,20 +31,23 @@ ** ****************************************************************************/ -#include <qtest.h> -#include <QtCore/QProcess> -#include <QtCore/QTimer> -#include <QtCore/QFileInfo> -#include <QtCore/QDir> -#include <QtCore/QMutex> -#include <QtCore/QLibraryInfo> -#include <QtQml/QJSEngine> - //QQmlDebugTest #include "debugutil_p.h" -#include "qqmldebugclient.h" #include "../../../shared/util.h" +#include <private/qqmldebugclient_p.h> +#include <private/qqmldebugconnection_p.h> +#include <private/qpacket_p.h> + +#include <QtTest/qtest.h> +#include <QtCore/qprocess.h> +#include <QtCore/qtimer.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qdir.h> +#include <QtCore/qmutex.h> +#include <QtCore/qlibraryinfo.h> +#include <QtQml/qjsengine.h> + #if defined (Q_OS_WINCE) #undef IN #undef OUT @@ -557,11 +560,9 @@ void QJSDebugClient::setBreakpoint(QString type, QString target, int line, int c // } if (type == QLatin1String(EVENT)) { - QByteArray reply; - QDataStream rs(&reply, QIODevice::WriteOnly); + QPacket rs(connection()->currentDataStreamVersion()); rs << target.toUtf8() << enabled; - sendMessage(packMessage(QByteArray("breakonsignal"), reply)); - + sendMessage(packMessage(QByteArray("breakonsignal"), rs.data())); } else { VARIANTMAPINIT; jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT))); @@ -709,7 +710,7 @@ void QJSDebugClient::stateChanged(State state) void QJSDebugClient::messageReceived(const QByteArray &data) { - QDataStream ds(data); + QPacket ds(connection()->currentDataStreamVersion(), data); QByteArray command; ds >> command; @@ -794,11 +795,10 @@ void QJSDebugClient::flushSendBuffer() QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray &message) { - QByteArray reply; - QDataStream rs(&reply, QIODevice::WriteOnly); + QPacket rs(connection()->currentDataStreamVersion()); QByteArray cmd = "V8DEBUG"; rs << cmd << type << message; - return reply; + return rs.data(); } void tst_QQmlDebugJS::initTestCase() @@ -831,6 +831,7 @@ void tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode, bool restrict connection = new QQmlDebugConnection(); process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this); client = new QJSDebugClient(connection); + QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(connection); const char *args = 0; if (blockMode) @@ -849,6 +850,11 @@ void tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode, bool restrict if (client->state() != QQmlDebugClient::Enabled) QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(enabled()))); + + foreach (QQmlDebugClient *otherClient, others) + QCOMPARE(otherClient->state(), restrictServices ? QQmlDebugClient::Unavailable : + QQmlDebugClient::Enabled); + qDeleteAll(others); } void tst_QQmlDebugJS::cleanup() diff --git a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro index b612da11de..860d39cca4 100644 --- a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro +++ b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro @@ -10,7 +10,6 @@ SOURCES += tst_qqmldebuglocal.cpp \ INCLUDEPATH += ../shared include(../shared/debugutil.pri) -CONFIG += parallel_test QT += qml-private testlib gui-private core-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 QT_QML_DEBUG_NO_WARNING +DEFINES += QT_QML_DEBUG_NO_WARNING diff --git a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp index 0343ea77ee..083e6de09e 100644 --- a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp +++ b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp @@ -31,18 +31,20 @@ ** ****************************************************************************/ -#include <qtest.h> -#include <QSignalSpy> -#include <QTimer> -#include <QHostAddress> -#include <QDebug> -#include <QThread> -#include <ctime> - -#include "debugutil_p.h" #include "qqmldebugtestservice.h" +#include "debugutil_p.h" #include <private/qqmldebugconnector_p.h> +#include <private/qqmldebugconnection_p.h> + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtNetwork/qhostaddress.h> +#include <QtCore/qtimer.h> +#include <QtCore/qdebug.h> +#include <QtCore/qthread.h> + +#include <ctime> QString fileName; diff --git a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro index 573e58d3a6..79cbe52331 100644 --- a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro +++ b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qqmldebugservice -macx:CONFIG -= app_bundle +osx:CONFIG -= app_bundle HEADERS += ../shared/qqmldebugtestservice.h @@ -19,4 +19,3 @@ OTHER_FILES += \ DEFINES += QT_QML_DEBUG_NO_WARNING QT += qml-private testlib gui-private core-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp index b63c5c0a6d..e2cdc89a56 100644 --- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp +++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp @@ -30,22 +30,25 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include <qtest.h> -#include <QSignalSpy> -#include <QTimer> -#include <QHostAddress> -#include <QDebug> -#include <QThread> -#include <QLibraryInfo> -#include <QtQml/qqmlengine.h> -#include "../../../shared/util.h" -#include "debugutil_p.h" -#include "qqmldebugclient.h" #include "qqmldebugtestservice.h" +#include "debugutil_p.h" +#include "../../../shared/util.h" + +#include <private/qqmldebugclient_p.h> +#include <private/qqmldebugconnection_p.h> #include <private/qqmldebugconnector_p.h> +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtNetwork/qhostaddress.h> +#include <QtQml/qqmlengine.h> +#include <QtCore/qtimer.h> +#include <QtCore/qdebug.h> +#include <QtCore/qthread.h> +#include <QtCore/qlibraryinfo.h> + #define PORT 3769 #define STR_PORT "3769" @@ -74,10 +77,19 @@ void tst_QQmlDebugService::initTestCase() { QQmlDataTest::initTestCase(); QQmlDebugConnector::setPluginKey(QLatin1String("QQmlDebugServer")); + QQmlDebugConnector::setServices(QStringList() + << QStringLiteral("tst_QQmlDebugService")); QTest::ignoreMessage(QtWarningMsg, "QML debugger: Cannot set plugin key after loading the plugin."); m_service = new QQmlDebugTestService("tst_QQmlDebugService", 2); + foreach (const QString &service, QQmlDebuggingEnabler::debuggerServices()) + QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0); + foreach (const QString &service, QQmlDebuggingEnabler::inspectorServices()) + QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0); + foreach (const QString &service, QQmlDebuggingEnabler::profilerServices()) + QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0); + const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT); QTest::ignoreMessage(QtDebugMsg, waitingMsg.toLatin1().constData()); QQmlDebuggingEnabler::startTcpDebugServer(PORT); @@ -195,7 +207,7 @@ void tst_QQmlDebugService::checkSupportForDataStreamVersion() client.sendMessage(msg); QByteArray resp = client.waitForResponse(); QCOMPARE(resp, msg); - QCOMPARE(m_conn->dataStreamVersion(), int(QDataStream::Qt_5_0)); + QCOMPARE(m_conn->currentDataStreamVersion(), int(QDataStream::Qt_DefaultCompiledVersion)); } void tst_QQmlDebugService::idForObject() @@ -238,7 +250,7 @@ void tst_QQmlDebugService::checkSupportForOldDataStreamVersion() //create a new connection; delete m_conn; m_conn = new QQmlDebugConnection(this); - m_conn->setDataStreamVersion(QDataStream::Qt_4_7); + m_conn->setMaximumDataStreamVersion(QDataStream::Qt_5_0); for (int i = 0; i < 50; ++i) { // try for 5 seconds ... m_conn->connectToHost("127.0.0.1", PORT); @@ -258,7 +270,7 @@ void tst_QQmlDebugService::checkSupportForOldDataStreamVersion() client.sendMessage(msg); QByteArray resp = client.waitForResponse(); QCOMPARE(resp, msg); - QCOMPARE(m_conn->dataStreamVersion(), int(QDataStream::Qt_4_7)); + QCOMPARE(m_conn->currentDataStreamVersion(), int(QDataStream::Qt_5_0)); } QTEST_MAIN(tst_QQmlDebugService) diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro index 901dd229c0..2518650493 100644 --- a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro +++ b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qqmlenginecontrol -macx:CONFIG -= app_bundle +osx:CONFIG -= app_bundle SOURCES += tst_qqmlenginecontrol.cpp @@ -11,7 +11,6 @@ include(../shared/debugutil.pri) TESTDATA = data/* QT += core qml testlib gui-private core-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 OTHER_FILES += \ data/test.qml \ diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp index 11fa56d710..fb4d46b8c8 100644 --- a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp +++ b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp @@ -31,60 +31,43 @@ ** ****************************************************************************/ -#include <qtest.h> -#include <QLibraryInfo> - #include "debugutil_p.h" -#include "qqmldebugclient.h" #include "../../../shared/util.h" +#include <private/qqmldebugclient_p.h> +#include <private/qqmldebugconnection_p.h> +#include <private/qpacket_p.h> +#include <private/qqmlenginecontrolclient_p.h> + +#include <QtTest/qtest.h> +#include <QtCore/qlibraryinfo.h> + #define STR_PORT_FROM "13773" #define STR_PORT_TO "13783" -class QQmlEngineControlClient : public QQmlDebugClient +class QQmlEngineBlocker : public QObject { Q_OBJECT public: - enum MessageType { - EngineAboutToBeAdded, - EngineAdded, - EngineAboutToBeRemoved, - EngineRemoved, - - MaximumMessageType - }; - - enum CommandType { - StartWaitingEngine, - StopWaitingEngine, - - MaximumCommandType - }; - - QQmlEngineControlClient(QQmlDebugConnection *connection) - : QQmlDebugClient(QLatin1String("EngineControl"), connection) - {} - - - void command(CommandType command, int engine) { - QByteArray message; - QDataStream stream(&message, QIODevice::WriteOnly); - stream << (int)command << engine; - sendMessage(message); - } + QQmlEngineBlocker(QQmlEngineControlClient *parent); - QList<int> startingEngines; - QList<int> stoppingEngines; +public slots: + void blockEngine(int engineId, const QString &name); +}; -signals: - void engineAboutToBeAdded(); - void engineAdded(); - void engineAboutToBeRemoved(); - void engineRemoved(); +QQmlEngineBlocker::QQmlEngineBlocker(QQmlEngineControlClient *parent): QObject(parent) +{ + connect(parent, &QQmlEngineControlClient::engineAboutToBeAdded, + this, &QQmlEngineBlocker::blockEngine); + connect(parent, &QQmlEngineControlClient::engineAboutToBeRemoved, + this, &QQmlEngineBlocker::blockEngine); +} -protected: - void messageReceived(const QByteArray &message); -}; +void QQmlEngineBlocker::blockEngine(int engineId, const QString &name) +{ + Q_UNUSED(name); + static_cast<QQmlEngineControlClient *>(parent())->blockEngine(engineId); +} class tst_QQmlEngineControl : public QQmlDataTest { @@ -97,7 +80,6 @@ public: , m_client(0) {} - private: QQmlDebugProcess *m_process; QQmlDebugConnection *m_connection; @@ -115,42 +97,6 @@ private slots: void stopEngine(); }; -void QQmlEngineControlClient::messageReceived(const QByteArray &message) -{ - QByteArray msg = message; - QDataStream stream(&msg, QIODevice::ReadOnly); - - int messageType; - int engineId; - stream >> messageType >> engineId; - - switch (messageType) { - case EngineAboutToBeAdded: - startingEngines.append(engineId); - emit engineAboutToBeAdded(); - break; - case EngineAdded: - QVERIFY(startingEngines.contains(engineId)); - startingEngines.removeOne(engineId); - emit engineAdded(); - break; - case EngineAboutToBeRemoved: - stoppingEngines.append(engineId); - emit engineAboutToBeRemoved(); - break; - case EngineRemoved: - QVERIFY(stoppingEngines.contains(engineId)); - stoppingEngines.removeOne(engineId); - emit engineRemoved(); - break; - default: - QString failMsg = QString("Unknown message type:") + messageType; - QFAIL(qPrintable(failMsg)); - break; - } - QVERIFY(stream.atEnd()); -} - void tst_QQmlEngineControl::connect(const QString &testFile, bool restrictServices) { const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"; @@ -167,11 +113,17 @@ void tst_QQmlEngineControl::connect(const QString &testFile, bool restrictServic m_connection = new QQmlDebugConnection(); m_client = new QQmlEngineControlClient(m_connection); + new QQmlEngineBlocker(m_client); + QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection); const int port = m_process->debugPort(); m_connection->connectToHost(QLatin1String("127.0.0.1"), port); QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); + foreach (QQmlDebugClient *other, others) + QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable : + QQmlDebugClient::Enabled); + qDeleteAll(others); } void tst_QQmlEngineControl::cleanup() @@ -179,8 +131,8 @@ void tst_QQmlEngineControl::cleanup() if (QTest::currentTestFailed()) { qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null")); qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null")); - qDebug() << "Connection State:" << (m_connection ? m_connection->stateString() : QLatin1String("null")); - qDebug() << "Client State:" << (m_client ? m_client->stateString() : QLatin1String("null")); + qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection); + qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client); } delete m_process; m_process = 0; @@ -208,10 +160,10 @@ void tst_QQmlEngineControl::startEngine() connect("test.qml", restrictMode); - QTRY_VERIFY(!m_client->startingEngines.empty()); - m_client->command(QQmlEngineControlClient::StartWaitingEngine, m_client->startingEngines.last()); + QTRY_VERIFY(!m_client->blockedEngines().empty()); + m_client->releaseEngine(m_client->blockedEngines().last()); - QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded())), + QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))), "No engine start message received in time."); } @@ -226,16 +178,16 @@ void tst_QQmlEngineControl::stopEngine() connect("exit.qml", restrictMode); - QTRY_VERIFY(!m_client->startingEngines.empty()); - m_client->command(QQmlEngineControlClient::StartWaitingEngine, m_client->startingEngines.last()); + QTRY_VERIFY(!m_client->blockedEngines().empty()); + m_client->releaseEngine(m_client->blockedEngines().last()); - QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded())), + QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))), "No engine start message received in time."); - QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAboutToBeRemoved())), + QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAboutToBeRemoved(int,QString))), "No engine about to stop message received in time."); - m_client->command(QQmlEngineControlClient::StopWaitingEngine, m_client->stoppingEngines.last()); - QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineRemoved())), + m_client->releaseEngine(m_client->blockedEngines().last()); + QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineRemoved(int,QString))), "No engine stop message received in time."); } diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro index 028eb3644d..e11ccdc6ca 100644 --- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro +++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro @@ -2,7 +2,7 @@ CONFIG += testcase TARGET = tst_qqmlenginedebuginspectorintegration QT += qml testlib gui-private core-private -macx:CONFIG -= app_bundle +osx:CONFIG -= app_bundle SOURCES += tst_qqmlenginedebuginspectorintegration.cpp @@ -13,4 +13,3 @@ include(../shared/qqmlenginedebugclient.pri) include(../shared/debugutil.pri) TESTDATA = data/* -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp index 0285bae189..04b068161b 100644 --- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp @@ -31,18 +31,20 @@ ** ****************************************************************************/ -#include <qtest.h> -#include <QSignalSpy> -#include <QTimer> -#include <QHostAddress> -#include <QDebug> -#include <QThread> -#include <QtCore/QLibraryInfo> - -#include "../shared/debugutil_p.h" -#include "../../../shared/util.h" #include "qqmlinspectorclient.h" #include "qqmlenginedebugclient.h" +#include "../shared/debugutil_p.h" +#include "../../../shared/util.h" + +#include <private/qqmldebugconnection_p.h> + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtNetwork/qhostaddress.h> +#include <QtCore/qtimer.h> +#include <QtCore/qdebug.h> +#include <QtCore/qthread.h> +#include <QtCore/qlibraryinfo.h> #define STR_PORT_FROM "3776" #define STR_PORT_TO "3786" @@ -111,9 +113,14 @@ void tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices) QQmlDebugConnection *m_connection = new QQmlDebugConnection(this); m_inspectorClient = new QQmlInspectorClient(m_connection); m_engineDebugClient = new QQmlEngineDebugClient(m_connection); + QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection); m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort()); QVERIFY(m_connection->waitForConnected()); + foreach (QQmlDebugClient *other, others) + QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable : + QQmlDebugClient::Enabled); + qDeleteAll(others); } void tst_QQmlEngineDebugInspectorIntegration::cleanup() diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro index 5dadef62e4..06250d9940 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qqmlenginedebugservice -macx:CONFIG -= app_bundle +osx:CONFIG -= app_bundle SOURCES += \ tst_qqmlenginedebugservice.cpp @@ -13,4 +13,3 @@ include(../shared/debugutil.pri) DEFINES += QT_QML_DEBUG_NO_WARNING QT += core-private qml-private quick-private testlib gui-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp index bc3220ad8c..fe4000bbb4 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp @@ -30,31 +30,33 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include <qtest.h> -#include <QSignalSpy> -#include <QTimer> -#include <QHostAddress> -#include <QDebug> -#include <QThread> -#include <QModelIndex> -#include <QtQml/qqmlengine.h> -#include <QtQml/qqmlcontext.h> -#include <QtQml/qqmlcomponent.h> -#include <QtQml/qqmlexpression.h> -#include <QtQml/qqmlproperty.h> -#include <QtQuick/qquickitem.h> +#include "qqmlenginedebugclient.h" +#include "debugutil_p.h" +#include "../../../shared/util.h" #include <private/qqmlbinding_p.h> #include <private/qqmlboundsignal_p.h> #include <private/qqmldebugservice_p.h> #include <private/qqmlmetatype_p.h> #include <private/qqmlproperty_p.h> +#include <private/qqmldebugconnection_p.h> -#include "debugutil_p.h" -#include "qqmlenginedebugclient.h" +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> -#include "../../../shared/util.h" +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlexpression.h> +#include <QtQml/qqmlproperty.h> +#include <QtQuick/qquickitem.h> + +#include <QtNetwork/qhostaddress.h> +#include <QtCore/qtimer.h> +#include <QtCore/qdebug.h> +#include <QtCore/qthread.h> +#include <QtCore/qabstractitemmodel.h> #define QVERIFYOBJECT(statement) \ do {\ @@ -352,7 +354,11 @@ void tst_QQmlEngineDebugService::initTestCase() bool ok = m_conn->waitForConnected(); QVERIFY(ok); m_dbg = new QQmlEngineDebugClient(m_conn); + QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_conn); QTRY_COMPARE(m_dbg->state(), QQmlEngineDebugClient::Enabled); + foreach (QQmlDebugClient *other, others) + QCOMPARE(other->state(), QQmlDebugClient::Unavailable); + qDeleteAll(others); } void tst_QQmlEngineDebugService::cleanupTestCase() diff --git a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro index 3a1d59f3fa..ee5f3c708a 100644 --- a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro +++ b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro @@ -2,7 +2,7 @@ CONFIG += testcase TARGET = tst_qqmlinspector QT += qml testlib gui-private core-private -macx:CONFIG -= app_bundle +osx:CONFIG -= app_bundle SOURCES += tst_qqmlinspector.cpp @@ -12,4 +12,3 @@ include(../shared/qqmlinspectorclient.pri) include(../shared/debugutil.pri) TESTDATA = data/* -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp index 70833f5e2c..d5aa1f41ad 100644 --- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp +++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp @@ -30,17 +30,20 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include <qtest.h> -#include <QSignalSpy> -#include <QTimer> -#include <QHostAddress> -#include <QDebug> -#include <QThread> -#include <QtCore/QLibraryInfo> +#include "qqmlinspectorclient.h" #include "../shared/debugutil_p.h" #include "../../../shared/util.h" -#include "qqmlinspectorclient.h" + +#include <private/qqmldebugconnection_p.h> + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtCore/qtimer.h> +#include <QtCore/qdebug.h> +#include <QtCore/qthread.h> +#include <QtCore/qlibraryinfo.h> +#include <QtNetwork/qhostaddress.h> #define STR_PORT_FROM "3772" #define STR_PORT_TO "3782" @@ -91,11 +94,16 @@ void tst_QQmlInspector::startQmlsceneProcess(const char * /* qmlFile */, bool re m_connection = new QQmlDebugConnection(); m_client = new QQmlInspectorClient(m_connection); + QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection); m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort()); QVERIFY(m_client); QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); + foreach (QQmlDebugClient *other, others) + QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable : + QQmlDebugClient::Enabled); + qDeleteAll(others); } void tst_QQmlInspector::cleanup() diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro index e422d3ef99..71a58d6f34 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro +++ b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qqmlprofilerservice -macx:CONFIG -= app_bundle +osx:CONFIG -= app_bundle SOURCES += tst_qqmlprofilerservice.cpp @@ -11,7 +11,6 @@ include(../shared/debugutil.pri) TESTDATA = data/* QT += core qml testlib gui-private core-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 OTHER_FILES += \ data/pixmapCacheTest.qml \ diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp index 0e63e18952..3a9666b8fe 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp +++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp @@ -31,20 +31,25 @@ ** ****************************************************************************/ -#include <qtest.h> -#include <QLibraryInfo> - #include "debugutil_p.h" -#include "qqmldebugclient.h" #include "../../../shared/util.h" +#include <private/qqmlprofilerclient_p.h> +#include <private/qqmldebugconnection_p.h> + +#include <QtTest/qtest.h> +#include <QtCore/qlibraryinfo.h> + #define STR_PORT_FROM "13773" #define STR_PORT_TO "13783" struct QQmlProfilerData { - QQmlProfilerData(int messageType = 0, int detailType = 0, const QString &detailData = QString()) - : messageType(messageType), detailType(detailType), detailData(detailData) {} + QQmlProfilerData(qint64 time = -2, int messageType = -1, int detailType = -1, + const QString &detailData = QString()) : + time(time), messageType(messageType), detailType(detailType), detailData(detailData), + line(-1), column(-1), framerate(-1), animationcount(-1), amount(-1) + {} qint64 time; int messageType; @@ -57,109 +62,184 @@ struct QQmlProfilerData int framerate; //used by animation events int animationcount; //used by animation events qint64 amount; //used by heap events - - QByteArray toByteArray() const; }; -class QQmlProfilerClient : public QQmlDebugClient +class QQmlProfilerTestClient : public QQmlProfilerClient { Q_OBJECT public: - enum Message { - Event, - RangeStart, - RangeData, - RangeLocation, - RangeEnd, - Complete, // end of transmission - PixmapCacheEvent, - SceneGraphFrame, - MemoryAllocation, - - MaximumMessage - }; + QQmlProfilerTestClient(QQmlDebugConnection *connection) : QQmlProfilerClient(connection) {} - enum EventType { - FramePaint, - Mouse, - Key, - AnimationFrame, - EndTrace, - StartTrace, + QVector<QQmlProfilerData> qmlMessages; + QVector<QQmlProfilerData> javascriptMessages; + QVector<QQmlProfilerData> jsHeapMessages; + QVector<QQmlProfilerData> asynchronousMessages; + QVector<QQmlProfilerData> pixmapMessages; - MaximumEventType - }; +signals: + void recordingFinished(); - enum RangeType { - Painting, - Compiling, - Creating, - Binding, //running a binding - HandlingSignal, //running a signal handler - Javascript, +private: + void traceStarted(qint64 time, int engineId); + void traceFinished(qint64 time, int engineId); + void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime); + void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, const QString &data); + void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time, + const QQmlEventLocation &location); + void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime); + void animationFrame(qint64 time, int frameRate, int animationCount, int threadId); + void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time, + qint64 numericData1, qint64 numericData2, qint64 numericData3, + qint64 numericData4, qint64 numericData5); + void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time, + const QString &url, int numericData1, int numericData2); + void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 amount); + void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b); + void complete(); - MaximumRangeType - }; + void unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time, int detailType); + void unknownData(QPacket &stream); +}; - enum PixmapEventType { - PixmapSizeKnown, - PixmapReferenceCountChanged, - PixmapCacheCountChanged, - PixmapLoadingStarted, - PixmapLoadingFinished, - PixmapLoadingError, +void QQmlProfilerTestClient::traceStarted(qint64 time, int engineId) +{ + asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event, + QQmlProfilerDefinitions::StartTrace, + QString::number(engineId))); +} - MaximumPixmapEventType - }; +void QQmlProfilerTestClient::traceFinished(qint64 time, int engineId) +{ + asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event, + QQmlProfilerDefinitions::EndTrace, + QString::number(engineId))); +} - enum SceneGraphFrameType { - SceneGraphRendererFrame, - SceneGraphAdaptationLayerFrame, - SceneGraphContextFrame, - SceneGraphRenderLoopFrame, - SceneGraphTexturePrepare, - SceneGraphTextureDeletion, - SceneGraphPolishAndSync, - SceneGraphWindowsRenderShow, - SceneGraphWindowsAnimations, - SceneGraphWindowsPolishFrame, - - MaximumSceneGraphFrameType - }; +void QQmlProfilerTestClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime) +{ + QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType); + QQmlProfilerData data(startTime, QQmlProfilerDefinitions::RangeStart, type); + if (type == QQmlProfilerDefinitions::Javascript) + javascriptMessages.append(data); + else + qmlMessages.append(data); +} - enum MemoryType { - HeapPage, - LargeItem, - SmallItem - }; +void QQmlProfilerTestClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, + const QString &string) +{ + QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType); + QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeData, type, string); + if (type == QQmlProfilerDefinitions::Javascript) + javascriptMessages.append(data); + else + qmlMessages.append(data); +} - QQmlProfilerClient(QQmlDebugConnection *connection) - : QQmlDebugClient(QLatin1String("CanvasFrameRate"), connection) - { - } +void QQmlProfilerTestClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time, + const QQmlEventLocation &location) +{ + QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType); + QVERIFY(location.line >= -2); + QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeLocation, type, location.filename); + data.line = location.line; + data.column = location.column; + if (type == QQmlProfilerDefinitions::Javascript) + javascriptMessages.append(data); + else + qmlMessages.append(data); +} - QVector<QQmlProfilerData> qmlMessages; - QVector<QQmlProfilerData> javascriptMessages; - QVector<QQmlProfilerData> jsHeapMessages; - QVector<QQmlProfilerData> asynchronousMessages; - QVector<QQmlProfilerData> pixmapMessages; +void QQmlProfilerTestClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime) +{ + QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType); + QQmlProfilerData data(endTime, QQmlProfilerDefinitions::RangeEnd, type); + if (type == QQmlProfilerDefinitions::Javascript) + javascriptMessages.append(data); + else + qmlMessages.append(data); +} + +void QQmlProfilerTestClient::animationFrame(qint64 time, int frameRate, int animationCount, int threadId) +{ + QVERIFY(threadId >= 0); + QVERIFY(frameRate != -1); + QVERIFY(animationCount != -1); + QQmlProfilerData data(time, QQmlProfilerDefinitions::Event, + QQmlProfilerDefinitions::AnimationFrame); + data.framerate = frameRate; + data.animationcount = animationCount; + asynchronousMessages.append(data); +} - void setTraceState(bool enabled, quint32 flushInterval = 0) { - QByteArray message; - QDataStream stream(&message, QIODevice::WriteOnly); - stream << enabled; - if (enabled && flushInterval) - stream << -1 << std::numeric_limits<quint64>::max() << flushInterval; - sendMessage(message); +void QQmlProfilerTestClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, + qint64 time, qint64 numericData1, qint64 numericData2, + qint64 numericData3, qint64 numericData4, + qint64 numericData5) +{ + Q_UNUSED(numericData1); + Q_UNUSED(numericData2); + Q_UNUSED(numericData3); + Q_UNUSED(numericData4); + Q_UNUSED(numericData5); + asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::SceneGraphFrame, + type)); +} + +void QQmlProfilerTestClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, + qint64 time, const QString &url, int numericData1, + int numericData2) +{ + QQmlProfilerData data(time, QQmlProfilerDefinitions::PixmapCacheEvent, type, url); + switch (type) { + case QQmlProfilerDefinitions::PixmapSizeKnown: + data.line = numericData1; + data.column = numericData2; + break; + case QQmlProfilerDefinitions::PixmapReferenceCountChanged: + case QQmlProfilerDefinitions::PixmapCacheCountChanged: + data.animationcount = numericData1; + break; + default: + break; } + pixmapMessages.append(data); +} -signals: - void complete(); +void QQmlProfilerTestClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, + qint64 amount) +{ + QQmlProfilerData data(time, QQmlProfilerDefinitions::MemoryAllocation, type); + data.amount = amount; + jsHeapMessages.append(data); +} -protected: - void messageReceived(const QByteArray &message); -}; +void QQmlProfilerTestClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, + int a, int b) +{ + qmlMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event, type, + QString::number(a) + QLatin1Char('x') + + QString::number(b))); +} + +void QQmlProfilerTestClient::unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time, + int detailType) +{ + QFAIL(qPrintable(QString::fromLatin1("Unknown event %1 with detail type %2 received at %3.") + .arg(messageType).arg(detailType).arg(time))); +} + +void QQmlProfilerTestClient::unknownData(QPacket &stream) +{ + QFAIL(qPrintable(QString::fromLatin1("%1 bytes of extra data after receiving message.") + .arg(stream.device()->bytesAvailable()))); +} + +void QQmlProfilerTestClient::complete() +{ + emit recordingFinished(); +} class tst_QQmlProfilerService : public QQmlDataTest { @@ -177,7 +257,7 @@ public: private: QQmlDebugProcess *m_process; QQmlDebugConnection *m_connection; - QQmlProfilerClient *m_client; + QQmlProfilerTestClient *m_client; enum MessageListType { MessageListQML, @@ -219,143 +299,6 @@ private slots: #define VERIFY(type, position, expected, checks) QVERIFY(verify(type, position, expected, checks)) -void QQmlProfilerClient::messageReceived(const QByteArray &message) -{ - QByteArray msg = message; - QDataStream stream(&msg, QIODevice::ReadOnly); - - - QQmlProfilerData data; - data.time = -2; - data.messageType = -1; - data.detailType = -1; - data.line = -1; - data.framerate = -1; - data.animationcount = -1; - - stream >> data.time >> data.messageType; - - switch (data.messageType) { - case (QQmlProfilerClient::Event): { - stream >> data.detailType; - - switch (data.detailType) { - case QQmlProfilerClient::AnimationFrame: { - int threadId; - stream >> data.framerate >> data.animationcount >> threadId; - QVERIFY(threadId >= 0); - QVERIFY(data.framerate != -1); - QVERIFY(data.animationcount != -1); - break; - } - case QQmlProfilerClient::FramePaint: - case QQmlProfilerClient::Mouse: - case QQmlProfilerClient::Key: - break; - case QQmlProfilerClient::EndTrace: - case QQmlProfilerClient::StartTrace: { - int engineId = -1; - if (!stream.atEnd()) { - stream >> engineId; - QVERIFY(engineId >= 0); - } - break; - } - default: { - QString failMsg = QString("Unknown event type:") + data.detailType; - QFAIL(qPrintable(failMsg)); - break; - } - } - break; - } - case QQmlProfilerClient::Complete: { - emit complete(); - return; - } - case QQmlProfilerClient::RangeStart: { - stream >> data.detailType; - QVERIFY(data.detailType >= 0 && data.detailType < QQmlProfilerClient::MaximumRangeType); - break; - } - case QQmlProfilerClient::RangeEnd: { - stream >> data.detailType; - QVERIFY(data.detailType >= 0 && data.detailType < QQmlProfilerClient::MaximumRangeType); - break; - } - case QQmlProfilerClient::RangeData: { - stream >> data.detailType >> data.detailData; - QVERIFY(data.detailType >= 0 && data.detailType < QQmlProfilerClient::MaximumRangeType); - break; - } - case QQmlProfilerClient::RangeLocation: { - stream >> data.detailType >> data.detailData >> data.line >> data.column; - QVERIFY(data.detailType >= 0 && data.detailType < QQmlProfilerClient::MaximumRangeType); - QVERIFY(data.line >= -2); - break; - } - case QQmlProfilerClient::PixmapCacheEvent: { - stream >> data.detailType >> data.detailData; - if (data.detailType == QQmlProfilerClient::PixmapSizeKnown) - stream >> data.line >> data.column; - if (data.detailType == QQmlProfilerClient::PixmapReferenceCountChanged) - stream >> data.animationcount; - if (data.detailType == QQmlProfilerClient::PixmapCacheCountChanged) - stream >> data.animationcount; - break; - } - case QQmlProfilerClient::SceneGraphFrame: { - stream >> data.detailType; - qint64 subtime_1, subtime_2, subtime_3, subtime_4, subtime_5; - int glyphCount; - switch (data.detailType) { - // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime - case QQmlProfilerClient::SceneGraphRendererFrame: stream >> subtime_1 >> subtime_2 >> subtime_3 >> subtime_4; break; - // AdaptationLayerFrame: glyphCount, glyphRenderTime, glyphStoreTime - case QQmlProfilerClient::SceneGraphAdaptationLayerFrame: stream >> glyphCount >> subtime_2 >> subtime_3; break; - // ContextFrame: compiling material time - case QQmlProfilerClient::SceneGraphContextFrame: stream >> subtime_1; break; - // RenderLoop: syncTime, renderTime, swapTime - case QQmlProfilerClient::SceneGraphRenderLoopFrame: stream >> subtime_1 >> subtime_2 >> subtime_3; break; - // TexturePrepare: bind, convert, swizzle, upload, mipmap - case QQmlProfilerClient::SceneGraphTexturePrepare: stream >> subtime_1 >> subtime_2 >> subtime_3 >> subtime_4 >> subtime_5; break; - // TextureDeletion: deletionTime - case QQmlProfilerClient::SceneGraphTextureDeletion: stream >> subtime_1; break; - // PolishAndSync: polishTime, waitTime, syncTime, animationsTime, - case QQmlProfilerClient::SceneGraphPolishAndSync: stream >> subtime_1 >> subtime_2 >> subtime_3 >> subtime_4; break; - // WindowsRenderLoop: GL time, make current time, SceneGraph time - case QQmlProfilerClient::SceneGraphWindowsRenderShow: stream >> subtime_1 >> subtime_2 >> subtime_3; break; - // WindowsAnimations: update time - case QQmlProfilerClient::SceneGraphWindowsAnimations: stream >> subtime_1; break; - // WindowsRenderWindow: polish time - case QQmlProfilerClient::SceneGraphWindowsPolishFrame: stream >> subtime_1; break; - } - break; - } - case QQmlProfilerClient::MemoryAllocation: { - stream >> data.detailType; - stream >> data.amount; - break; - } - default: - QString failMsg = QString("Unknown message type:") + data.messageType; - QFAIL(qPrintable(failMsg)); - break; - } - QVERIFY(stream.atEnd()); - if (data.messageType == QQmlProfilerClient::PixmapCacheEvent) - pixmapMessages.append(data); - else if (data.messageType == QQmlProfilerClient::SceneGraphFrame || - data.messageType == QQmlProfilerClient::Event) - asynchronousMessages.append(data); - else if (data.messageType == QQmlProfilerClient::MemoryAllocation) - jsHeapMessages.append(data); - else if (data.detailType == QQmlProfilerClient::Javascript) - javascriptMessages.append(data); - else - qmlMessages.append(data); -} - void tst_QQmlProfilerService::connect(bool block, const QString &testFile, bool restrictServices) { // ### Still using qmlscene due to QTBUG-33377 @@ -372,24 +315,32 @@ void tst_QQmlProfilerService::connect(bool block, const QString &testFile, bool QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'."); m_connection = new QQmlDebugConnection(); - m_client = new QQmlProfilerClient(m_connection); + m_client = new QQmlProfilerTestClient(m_connection); + QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection); const int port = m_process->debugPort(); m_connection->connectToHost(QLatin1String("127.0.0.1"), port); QVERIFY(m_client); QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); + + foreach (QQmlDebugClient *other, others) + QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable : + QQmlDebugClient::Enabled); + qDeleteAll(others); } void tst_QQmlProfilerService::checkTraceReceived() { - QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time."); + QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(recordingFinished())), + "No trace received in time."); // must start with "StartTrace" - QQmlProfilerData expected(QQmlProfilerClient::Event, QQmlProfilerClient::StartTrace); + QQmlProfilerData expected(0, QQmlProfilerDefinitions::Event, + QQmlProfilerDefinitions::StartTrace); VERIFY(MessageListAsynchronous, 0, expected, CheckMessageType | CheckDetailType); // must end with "EndTrace" - expected.detailType = QQmlProfilerClient::EndTrace; + expected.detailType = QQmlProfilerDefinitions::EndTrace; VERIFY(MessageListAsynchronous, m_client->asynchronousMessages.length() - 1, expected, CheckMessageType | CheckDetailType); } @@ -406,15 +357,15 @@ void tst_QQmlProfilerService::checkJsHeap() qint64 lastTimestamp = -1; foreach (const QQmlProfilerData &message, m_client->jsHeapMessages) { switch (message.detailType) { - case QQmlProfilerClient::HeapPage: + case QV4::Profiling::HeapPage: allocated += message.amount; seen_alloc = true; break; - case QQmlProfilerClient::SmallItem: + case QV4::Profiling::SmallItem: used += message.amount; seen_small = true; break; - case QQmlProfilerClient::LargeItem: + case QV4::Profiling::LargeItem: allocated += message.amount; used += message.amount; seen_large = true; @@ -549,8 +500,8 @@ void tst_QQmlProfilerService::cleanup() qDebug() << " "; qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null")); qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null")); - qDebug() << "Connection State:" << (m_connection ? m_connection->stateString() : QLatin1String("null")); - qDebug() << "Client State:" << m_client->stateString(); + qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection); + qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client); } delete m_process; m_process = 0; @@ -585,9 +536,9 @@ void tst_QQmlProfilerService::connect() // if the engine is waiting, then the first message determines if it starts with trace enabled if (!traceEnabled) - m_client->setTraceState(false); - m_client->setTraceState(true); - m_client->setTraceState(false); + m_client->sendRecordingStatus(false); + m_client->sendRecordingStatus(true); + m_client->sendRecordingStatus(false); checkTraceReceived(); checkJsHeap(); } @@ -596,36 +547,36 @@ void tst_QQmlProfilerService::pixmapCacheData() { connect(true, "pixmapCacheTest.qml"); - m_client->setTraceState(true); + m_client->sendRecordingStatus(true); QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput()))); while (m_process->output().indexOf(QLatin1String("image loaded")) == -1 && m_process->output().indexOf(QLatin1String("image error")) == -1) QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput()))); - m_client->setTraceState(false); + m_client->sendRecordingStatus(false); checkTraceReceived(); checkJsHeap(); - QQmlProfilerData expected(QQmlProfilerClient::PixmapCacheEvent); + QQmlProfilerData expected(0, QQmlProfilerDefinitions::PixmapCacheEvent); // image starting to load - expected.detailType = QQmlProfilerClient::PixmapLoadingStarted; + expected.detailType = QQmlProfilerDefinitions::PixmapLoadingStarted; VERIFY(MessageListPixmap, 0, expected, CheckMessageType | CheckDetailType); // image size - expected.detailType = QQmlProfilerClient::PixmapSizeKnown; + expected.detailType = QQmlProfilerDefinitions::PixmapSizeKnown; expected.line = expected.column = 2; // width and height, in fact VERIFY(MessageListPixmap, 1, expected, CheckMessageType | CheckDetailType | CheckLine | CheckColumn); // image loaded - expected.detailType = QQmlProfilerClient::PixmapLoadingFinished; + expected.detailType = QQmlProfilerDefinitions::PixmapLoadingFinished; VERIFY(MessageListPixmap, 2, expected, CheckMessageType | CheckDetailType); // cache size - expected.detailType = QQmlProfilerClient::PixmapCacheCountChanged; + expected.detailType = QQmlProfilerDefinitions::PixmapCacheCountChanged; VERIFY(MessageListPixmap, 3, expected, CheckMessageType | CheckDetailType); } @@ -633,11 +584,11 @@ void tst_QQmlProfilerService::scenegraphData() { connect(true, "scenegraphTest.qml"); - m_client->setTraceState(true); + m_client->sendRecordingStatus(true); while (!m_process->output().contains(QLatin1String("tick"))) QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput()))); - m_client->setTraceState(false); + m_client->sendRecordingStatus(false); checkTraceReceived(); checkJsHeap(); @@ -653,8 +604,8 @@ void tst_QQmlProfilerService::scenegraphData() qint64 renderFrameTime = -1; foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) { - if (msg.messageType == QQmlProfilerClient::SceneGraphFrame) { - if (msg.detailType == QQmlProfilerClient::SceneGraphContextFrame) { + if (msg.messageType == QQmlProfilerDefinitions::SceneGraphFrame) { + if (msg.detailType == QQmlProfilerDefinitions::SceneGraphContextFrame) { contextFrameTime = msg.time; break; } @@ -664,7 +615,7 @@ void tst_QQmlProfilerService::scenegraphData() QVERIFY(contextFrameTime != -1); foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) { - if (msg.detailType == QQmlProfilerClient::SceneGraphRendererFrame) { + if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRendererFrame) { QVERIFY(msg.time >= contextFrameTime); renderFrameTime = msg.time; break; @@ -674,7 +625,7 @@ void tst_QQmlProfilerService::scenegraphData() QVERIFY(renderFrameTime != -1); foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) { - if (msg.detailType == QQmlProfilerClient::SceneGraphRenderLoopFrame) { + if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRenderLoopFrame) { QVERIFY(msg.time >= renderFrameTime); break; } @@ -685,7 +636,7 @@ void tst_QQmlProfilerService::profileOnExit() { connect(true, "exit.qml"); - m_client->setTraceState(true); + m_client->sendRecordingStatus(true); checkTraceReceived(); checkJsHeap(); @@ -695,7 +646,7 @@ void tst_QQmlProfilerService::controlFromJS() { connect(true, "controlFromJS.qml"); - m_client->setTraceState(false); + m_client->sendRecordingStatus(false); checkTraceReceived(); checkJsHeap(); } @@ -704,15 +655,15 @@ void tst_QQmlProfilerService::signalSourceLocation() { connect(true, "signalSourceLocation.qml"); - m_client->setTraceState(true); + m_client->sendRecordingStatus(true); while (!(m_process->output().contains(QLatin1String("500")))) QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput()))); - m_client->setTraceState(false); + m_client->sendRecordingStatus(false); checkTraceReceived(); checkJsHeap(); - QQmlProfilerData expected(QQmlProfilerClient::RangeLocation, - QQmlProfilerClient::HandlingSignal, + QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeLocation, + QQmlProfilerDefinitions::HandlingSignal, QLatin1String("signalSourceLocation.qml")); expected.line = 8; expected.column = 28; @@ -727,28 +678,29 @@ void tst_QQmlProfilerService::javascript() { connect(true, "javascript.qml"); - m_client->setTraceState(true); + m_client->sendRecordingStatus(true); while (!(m_process->output().contains(QLatin1String("done")))) QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput()))); - m_client->setTraceState(false); + m_client->sendRecordingStatus(false); checkTraceReceived(); checkJsHeap(); - QQmlProfilerData expected(QQmlProfilerClient::RangeStart, QQmlProfilerClient::Javascript); + QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeStart, + QQmlProfilerDefinitions::Javascript); VERIFY(MessageListJavaScript, 6, expected, CheckMessageType | CheckDetailType); - expected.messageType = QQmlProfilerClient::RangeLocation; + expected.messageType = QQmlProfilerDefinitions::RangeLocation; expected.detailData = QLatin1String("javascript.qml"); expected.line = 4; expected.column = 5; VERIFY(MessageListJavaScript, 7, expected, CheckAll); - expected.messageType = QQmlProfilerClient::RangeData; + expected.messageType = QQmlProfilerDefinitions::RangeData; expected.detailData = QLatin1String("something"); VERIFY(MessageListJavaScript, 8, expected, CheckMessageType | CheckDetailType | CheckDataEndsWith); - expected.messageType = QQmlProfilerClient::RangeEnd; + expected.messageType = QQmlProfilerDefinitions::RangeEnd; VERIFY(MessageListJavaScript, 21, expected, CheckMessageType | CheckDetailType); } @@ -756,14 +708,14 @@ void tst_QQmlProfilerService::flushInterval() { connect(true, "timer.qml"); - m_client->setTraceState(true, 1); + m_client->sendRecordingStatus(true, -1, 1); // Make sure we get multiple messages QTRY_VERIFY(m_client->qmlMessages.length() > 0); QVERIFY(m_client->qmlMessages.length() < 100); QTRY_VERIFY(m_client->qmlMessages.length() > 100); - m_client->setTraceState(false); + m_client->sendRecordingStatus(false); checkTraceReceived(); checkJsHeap(); } diff --git a/tests/auto/qml/debugger/qv4debugger/qv4debugger.pro b/tests/auto/qml/debugger/qv4debugger/qv4debugger.pro new file mode 100644 index 0000000000..d11de56e43 --- /dev/null +++ b/tests/auto/qml/debugger/qv4debugger/qv4debugger.pro @@ -0,0 +1,17 @@ +CONFIG += testcase +TARGET = tst_qv4debugger +osx:CONFIG -= app_bundle + +SOURCES += \ + $$PWD/tst_qv4debugger.cpp \ + $$PWD/../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp \ + $$PWD/../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp + +HEADERS += \ + $$PWD/../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h \ + $$PWD/../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h + +INCLUDEPATH += \ + $$PWD/../../../../../src/plugins/qmltooling/qmldbg_debugger + +QT += core-private gui-private qml-private network testlib diff --git a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp index 39a1fbc173..c5fa6be7a0 100644 --- a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp @@ -33,6 +33,7 @@ #include <QtTest/QtTest> #include "qv4datacollector.h" +#include "qv4debugger.h" #include <QJSEngine> #include <QQmlEngine> @@ -159,7 +160,7 @@ public: } public slots: - void debuggerPaused(V4Debugger *debugger, QV4::Debugging::PauseReason reason) + void debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason) { Q_ASSERT(debugger == m_debugger); Q_ASSERT(debugger->engine() == collector.engine()); @@ -167,7 +168,7 @@ public slots: m_pauseReason = reason; m_statesWhenPaused << debugger->currentExecutionState(); - if (debugger->state() == V4Debugger::Paused && + if (debugger->state() == QV4Debugger::Paused && debugger->engine()->hasException) { Refs refs; RefHolder holder(&collector, &refs); @@ -184,7 +185,7 @@ public slots: m_stackTrace = debugger->stackTrace(); while (!m_expressionRequests.isEmpty()) { - Q_ASSERT(debugger->state() == V4Debugger::Paused); + Q_ASSERT(debugger->state() == QV4Debugger::Paused); ExpressionRequest request = m_expressionRequests.takeFirst(); m_expressionResults << Refs(); RefHolder holder(&collector, &m_expressionResults.last()); @@ -196,7 +197,7 @@ public slots: if (m_captureContextInfo) captureContextInfo(debugger); - debugger->resume(V4Debugger::FullThrottle); + debugger->resume(QV4Debugger::FullThrottle); } public: @@ -209,7 +210,7 @@ public: int lineNumber; }; - void captureContextInfo(V4Debugger *debugger) + void captureContextInfo(QV4Debugger *debugger) { for (int i = 0, ei = m_stackTrace.size(); i != ei; ++i) { m_capturedArguments.append(NamedRefs(&collector)); @@ -226,18 +227,17 @@ public: } } - void addDebugger(V4Debugger *debugger) + void addDebugger(QV4Debugger *debugger) { Q_ASSERT(!m_debugger); m_debugger = debugger; - connect(m_debugger, &V4Debugger::debuggerPaused, - this, &TestAgent::debuggerPaused); + connect(m_debugger, &QV4Debugger::debuggerPaused, this, &TestAgent::debuggerPaused); } bool m_wasPaused; - PauseReason m_pauseReason; + QV4Debugger::PauseReason m_pauseReason; bool m_captureContextInfo; - QList<V4Debugger::ExecutionState> m_statesWhenPaused; + QList<QV4Debugger::ExecutionState> m_statesWhenPaused; QList<TestBreakPoint> m_breakPointsToAddWhenPaused; QVector<QV4::StackFrame> m_stackTrace; QVector<NamedRefs> m_capturedArguments; @@ -251,7 +251,7 @@ public: }; QVector<ExpressionRequest> m_expressionRequests; QVector<Refs> m_expressionResults; - V4Debugger *m_debugger; + QV4Debugger *m_debugger; // Utility methods: void dumpStackTrace() const @@ -295,9 +295,9 @@ private slots: void evaluateExpression(); private: - V4Debugger *debugger() const + QV4Debugger *debugger() const { - return static_cast<V4Debugger *>(m_v4->debugger); + return static_cast<QV4Debugger *>(m_v4->debugger); } void evaluateJavaScript(const QString &script, const QString &fileName, int lineNumber = 1) { @@ -319,7 +319,7 @@ void tst_qv4debugger::init() m_engine = new TestEngine; m_v4 = m_engine->v4Engine(); m_v4->iselFactory.reset(new QV4::Moth::ISelFactory); - m_v4->setDebugger(new V4Debugger(m_v4)); + m_v4->setDebugger(new QV4Debugger(m_v4)); m_engine->moveToThread(m_javaScriptThread); m_javaScriptThread->start(); m_debuggerAgent = new TestAgent(m_v4); @@ -359,7 +359,7 @@ void tst_qv4debugger::pendingBreakpoint() evaluateJavaScript(script, "testfile"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1); - V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); + QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); QCOMPARE(state.fileName, QString("testfile")); QCOMPARE(state.lineNumber, 2); } @@ -375,7 +375,7 @@ void tst_qv4debugger::liveBreakPoint() evaluateJavaScript(script, "liveBreakPoint"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 2); - V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(1); + QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(1); QCOMPARE(state.fileName, QString("liveBreakPoint")); QCOMPARE(state.lineNumber, 3); } @@ -404,7 +404,7 @@ void tst_qv4debugger::addBreakPointWhilePaused() QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 2); - V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(0); + QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(0); QCOMPARE(state.fileName, QString("addBreakPointWhilePaused")); QCOMPARE(state.lineNumber, 1); @@ -415,7 +415,7 @@ void tst_qv4debugger::addBreakPointWhilePaused() static QV4::ReturnedValue someCall(QV4::CallContext *ctx) { - static_cast<V4Debugger *>(ctx->d()->engine->debugger) + static_cast<QV4Debugger *>(ctx->d()->engine->debugger) ->removeBreakPoint("removeBreakPointForNextInstruction", 2); return QV4::Encode::undefined(); } @@ -450,7 +450,7 @@ void tst_qv4debugger::conditionalBreakPoint() evaluateJavaScript(script, "conditionalBreakPoint"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 4); - V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); + QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); QCOMPARE(state.fileName, QString("conditionalBreakPoint")); QCOMPARE(state.lineNumber, 3); @@ -465,7 +465,7 @@ void tst_qv4debugger::conditionalBreakPointInQml() { QQmlEngine engine; QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); - V4Debugger *v4Debugger = new V4Debugger(v4); + QV4Debugger *v4Debugger = new QV4Debugger(v4); v4->iselFactory.reset(new QV4::Moth::ISelFactory); v4->setDebugger(v4Debugger); @@ -644,7 +644,7 @@ void tst_qv4debugger::pauseOnThrow() debugger()->setBreakOnThrow(true); evaluateJavaScript(script, "pauseOnThrow"); QVERIFY(m_debuggerAgent->m_wasPaused); - QCOMPARE(m_debuggerAgent->m_pauseReason, Throwing); + QCOMPARE(m_debuggerAgent->m_pauseReason, QV4Debugger::Throwing); QCOMPARE(m_debuggerAgent->m_stackTrace.size(), 2); QVERIFY(m_debuggerAgent->m_thrownValue >= qint64(0)); QJsonObject exception = m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_thrownValue); @@ -665,9 +665,9 @@ void tst_qv4debugger::breakInCatch() debugger()->addBreakPoint("breakInCatch", 4); evaluateJavaScript(script, "breakInCatch"); QVERIFY(m_debuggerAgent->m_wasPaused); - QCOMPARE(m_debuggerAgent->m_pauseReason, BreakPoint); + QCOMPARE(m_debuggerAgent->m_pauseReason, QV4Debugger::BreakPointHit); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1); - V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); + QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); QCOMPARE(state.fileName, QString("breakInCatch")); QCOMPARE(state.lineNumber, 4); } @@ -682,9 +682,9 @@ void tst_qv4debugger::breakInWith() debugger()->addBreakPoint("breakInWith", 2); evaluateJavaScript(script, "breakInWith"); QVERIFY(m_debuggerAgent->m_wasPaused); - QCOMPARE(m_debuggerAgent->m_pauseReason, BreakPoint); + QCOMPARE(m_debuggerAgent->m_pauseReason, QV4Debugger::BreakPointHit); QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 1); - V4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); + QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.first(); QCOMPARE(state.fileName, QString("breakInWith")); QCOMPARE(state.lineNumber, 2); } diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp index 51d706b818..54720fc848 100644 --- a/tests/auto/qml/debugger/shared/debugutil.cpp +++ b/tests/auto/qml/debugger/shared/debugutil.cpp @@ -33,10 +33,12 @@ #include "debugutil_p.h" -#include <QEventLoop> -#include <QTimer> -#include <QFileInfo> -#include <QDir> +#include <private/qqmldebugconnection_p.h> + +#include <QtCore/qeventloop.h> +#include <QtCore/qtimer.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qdir.h> bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) { QEventLoop loop; @@ -51,6 +53,46 @@ bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int tim return timer.isActive(); } +QList<QQmlDebugClient *> QQmlDebugTest::createOtherClients(QQmlDebugConnection *connection) +{ + QList<QQmlDebugClient *> ret; + foreach (const QString &service, QQmlDebuggingEnabler::debuggerServices()) { + if (!connection->client(service)) + ret << new QQmlDebugClient(service, connection); + } + foreach (const QString &service, QQmlDebuggingEnabler::inspectorServices()) { + if (!connection->client(service)) + ret << new QQmlDebugClient(service, connection); + } + foreach (const QString &service, QQmlDebuggingEnabler::profilerServices()) { + if (!connection->client(service)) + ret << new QQmlDebugClient(service, connection); + } + return ret; +} + +QString QQmlDebugTest::clientStateString(const QQmlDebugClient *client) +{ + if (!client) + return QLatin1String("null"); + + switch (client->state()) { + case QQmlDebugClient::NotConnected: return QLatin1String("Not connected"); + case QQmlDebugClient::Unavailable: return QLatin1String("Unavailable"); + case QQmlDebugClient::Enabled: return QLatin1String("Enabled"); + default: return QLatin1String("Invalid"); + } + +} + +QString QQmlDebugTest::connectionStateString(const QQmlDebugConnection *connection) +{ + if (!connection) + return QLatin1String("null"); + + return connection->isConnected() ? QLatin1String("connected") : QLatin1String("not connected"); +} + QQmlDebugTestClient::QQmlDebugTestClient(const QString &s, QQmlDebugConnection *c) : QQmlDebugClient(s, c) { diff --git a/tests/auto/qml/debugger/shared/debugutil.pri b/tests/auto/qml/debugger/shared/debugutil.pri index cb9c761395..1983f3583e 100644 --- a/tests/auto/qml/debugger/shared/debugutil.pri +++ b/tests/auto/qml/debugger/shared/debugutil.pri @@ -1,8 +1,4 @@ -HEADERS += $$PWD/debugutil_p.h \ - $$PWD/qqmldebugclient.h \ - $$PWD/../../../../../src/plugins/qmltooling/shared/qpacketprotocol.h - -SOURCES += $$PWD/debugutil.cpp \ - $$PWD/qqmldebugclient.cpp \ - $$PWD/../../../../../src/plugins/qmltooling/shared/qpacketprotocol.cpp +QT += qmldebug-private +HEADERS += $$PWD/debugutil_p.h +SOURCES += $$PWD/debugutil.cpp diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h index d544a89ff2..7ab817a509 100644 --- a/tests/auto/qml/debugger/shared/debugutil_p.h +++ b/tests/auto/qml/debugger/shared/debugutil_p.h @@ -32,8 +32,8 @@ ** ****************************************************************************/ -#ifndef DEBUGUTIL_H -#define DEBUGUTIL_H +#ifndef DEBUGUTIL_P_H +#define DEBUGUTIL_P_H // // W A R N I N G @@ -46,21 +46,23 @@ // We mean it. // -#include <QEventLoop> -#include <QTimer> -#include <QThread> -#include <QTest> -#include <QProcess> -#include <QMutex> +#include <private/qqmldebugclient_p.h> +#include <QtCore/qeventloop.h> +#include <QtCore/qtimer.h> +#include <QtCore/qthread.h> +#include <QtCore/qprocess.h> +#include <QtCore/qmutex.h> +#include <QtTest/qtest.h> #include <QtQml/qqmlengine.h> -#include "qqmldebugclient.h" - class QQmlDebugTest { public: static bool waitForSignal(QObject *receiver, const char *member, int timeout = 5000); + static QList<QQmlDebugClient *> createOtherClients(QQmlDebugConnection *connection); + static QString clientStateString(const QQmlDebugClient *client); + static QString connectionStateString(const QQmlDebugConnection *connection); }; class QQmlDebugTestClient : public QQmlDebugClient @@ -128,4 +130,4 @@ private: int m_receivedBindErrors; }; -#endif // DEBUGUTIL_H +#endif // DEBUGUTIL_P_H diff --git a/tests/auto/qml/debugger/shared/qqmldebugclient.cpp b/tests/auto/qml/debugger/shared/qqmldebugclient.cpp deleted file mode 100644 index 0f7e572e02..0000000000 --- a/tests/auto/qml/debugger/shared/qqmldebugclient.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmldebugclient.h" -#include "../../../../../src/plugins/qmltooling/shared/qpacketprotocol.h" - -#include <QtCore/qdebug.h> -#include <QtCore/qeventloop.h> -#include <QtCore/qstringlist.h> -#include <QtCore/qtimer.h> -#include <QtNetwork/qnetworkproxy.h> -#include <QtNetwork/qlocalserver.h> -#include <QtNetwork/qlocalsocket.h> - -const int protocolVersion = 1; -const QString serverId = QLatin1String("QDeclarativeDebugServer"); -const QString clientId = QLatin1String("QDeclarativeDebugClient"); - -class QQmlDebugClientPrivate -{ -public: - QQmlDebugClientPrivate(); - - QString name; - QQmlDebugConnection *connection; -}; - -class QQmlDebugConnectionPrivate : public QObject -{ - Q_OBJECT -public: - QQmlDebugConnectionPrivate(QQmlDebugConnection *c); - QQmlDebugConnection *q; - QPacketProtocol *protocol; - QIODevice *device; - QLocalServer *server; - QEventLoop handshakeEventLoop; - QTimer handshakeTimer; - - bool gotHello; - QHash <QString, float> serverPlugins; - QHash<QString, QQmlDebugClient *> plugins; - - void advertisePlugins(); - void connectDeviceSignals(); - -public Q_SLOTS: - void forwardStateChange(QLocalSocket::LocalSocketState state); - void forwardError(QLocalSocket::LocalSocketError error); - - void newConnection(); - void connected(); - void readyRead(); - void deviceAboutToClose(); - void handshakeTimeout(); -}; - -QQmlDebugConnectionPrivate::QQmlDebugConnectionPrivate(QQmlDebugConnection *c) - : QObject(c), q(c), protocol(0), device(0), server(0), gotHello(false) -{ - protocol = new QPacketProtocol(q, this); - QObject::connect(c, SIGNAL(connected()), this, SLOT(connected())); - QObject::connect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); - - handshakeTimer.setSingleShot(true); - handshakeTimer.setInterval(3000); - connect(&handshakeTimer, SIGNAL(timeout()), SLOT(handshakeTimeout())); -} - -void QQmlDebugConnectionPrivate::advertisePlugins() -{ - if (!q->isConnected()) - return; - - QPacket pack; - pack << serverId << 1 << plugins.keys(); - protocol->send(pack); - q->flush(); -} - -void QQmlDebugConnectionPrivate::connected() -{ - QPacket pack; - pack << serverId << 0 << protocolVersion << plugins.keys() - << q->m_dataStreamVersion; - protocol->send(pack); - q->flush(); -} - -void QQmlDebugConnectionPrivate::readyRead() -{ - if (!gotHello) { - QPacket pack = protocol->read(); - QString name; - - pack >> name; - - bool validHello = false; - if (name == clientId) { - int op = -1; - pack >> op; - if (op == 0) { - int version = -1; - pack >> version; - if (version == protocolVersion) { - QStringList pluginNames; - QList<float> pluginVersions; - pack >> pluginNames; - if (!pack.isEmpty()) - pack >> pluginVersions; - - const int pluginNamesSize = pluginNames.size(); - const int pluginVersionsSize = pluginVersions.size(); - for (int i = 0; i < pluginNamesSize; ++i) { - float pluginVersion = 1.0; - if (i < pluginVersionsSize) - pluginVersion = pluginVersions.at(i); - serverPlugins.insert(pluginNames.at(i), pluginVersion); - } - - pack >> q->m_dataStreamVersion; - validHello = true; - } - } - } - - if (!validHello) { - qWarning("QQmlDebugConnection: Invalid hello message"); - QObject::disconnect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); - return; - } - gotHello = true; - - QHash<QString, QQmlDebugClient *>::Iterator iter = plugins.begin(); - for (; iter != plugins.end(); ++iter) { - QQmlDebugClient::State newState = QQmlDebugClient::Unavailable; - if (serverPlugins.contains(iter.key())) - newState = QQmlDebugClient::Enabled; - iter.value()->stateChanged(newState); - } - - handshakeTimer.stop(); - handshakeEventLoop.quit(); - } - - while (protocol->packetsAvailable()) { - QPacket pack = protocol->read(); - QString name; - pack >> name; - - if (name == clientId) { - int op = -1; - pack >> op; - - if (op == 1) { - // Service Discovery - QHash<QString, float> oldServerPlugins = serverPlugins; - serverPlugins.clear(); - - QStringList pluginNames; - QList<float> pluginVersions; - pack >> pluginNames; - if (!pack.isEmpty()) - pack >> pluginVersions; - - const int pluginNamesSize = pluginNames.size(); - const int pluginVersionsSize = pluginVersions.size(); - for (int i = 0; i < pluginNamesSize; ++i) { - float pluginVersion = 1.0; - if (i < pluginVersionsSize) - pluginVersion = pluginVersions.at(i); - serverPlugins.insert(pluginNames.at(i), pluginVersion); - } - - QHash<QString, QQmlDebugClient *>::Iterator iter = plugins.begin(); - for (; iter != plugins.end(); ++iter) { - const QString pluginName = iter.key(); - QQmlDebugClient::State newSate = QQmlDebugClient::Unavailable; - if (serverPlugins.contains(pluginName)) - newSate = QQmlDebugClient::Enabled; - - if (oldServerPlugins.contains(pluginName) - != serverPlugins.contains(pluginName)) { - iter.value()->stateChanged(newSate); - } - } - } else { - qWarning() << "QQmlDebugConnection: Unknown control message id" << op; - } - } else { - QByteArray message; - pack >> message; - - QHash<QString, QQmlDebugClient *>::Iterator iter = - plugins.find(name); - if (iter == plugins.end()) { - qWarning() << "QQmlDebugConnection: Message received for missing plugin" << name; - } else { - (*iter)->messageReceived(message); - } - } - } -} - -void QQmlDebugConnectionPrivate::deviceAboutToClose() -{ - // This is nasty syntax but we want to emit our own aboutToClose signal (by calling QIODevice::close()) - // without calling the underlying device close fn as that would cause an infinite loop - q->QIODevice::close(); -} - -void QQmlDebugConnectionPrivate::handshakeTimeout() -{ - if (!gotHello) { - qWarning() << "Qml Debug Client: Did not get handshake answer in time"; - handshakeEventLoop.quit(); - } -} - -QQmlDebugConnection::QQmlDebugConnection(QObject *parent) - : QIODevice(parent), d(new QQmlDebugConnectionPrivate(this)), - m_dataStreamVersion(QDataStream::Qt_5_0) -{ -} - -QQmlDebugConnection::~QQmlDebugConnection() -{ - QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin(); - for (; iter != d->plugins.end(); ++iter) { - iter.value()->d->connection = 0; - iter.value()->stateChanged(QQmlDebugClient::NotConnected); - } -} - -void QQmlDebugConnection::setDataStreamVersion(int dataStreamVersion) -{ - m_dataStreamVersion = dataStreamVersion; -} - -int QQmlDebugConnection::dataStreamVersion() -{ - return m_dataStreamVersion; -} - -bool QQmlDebugConnection::isConnected() const -{ - return state() == QAbstractSocket::ConnectedState; -} - -qint64 QQmlDebugConnection::readData(char *data, qint64 maxSize) -{ - return d->device->read(data, maxSize); -} - -qint64 QQmlDebugConnection::writeData(const char *data, qint64 maxSize) -{ - return d->device->write(data, maxSize); -} - -qint64 QQmlDebugConnection::bytesAvailable() const -{ - return d->device->bytesAvailable(); -} - -bool QQmlDebugConnection::isSequential() const -{ - return true; -} - -void QQmlDebugConnection::close() -{ - if (isOpen()) { - QIODevice::close(); - d->device->close(); - emit stateChanged(QAbstractSocket::UnconnectedState); - - QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin(); - for (; iter != d->plugins.end(); ++iter) { - iter.value()->stateChanged(QQmlDebugClient::NotConnected); - } - } -} - -bool QQmlDebugConnection::waitForConnected(int msecs) -{ - QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); - if (!socket) { - if (!d->server || (!d->server->hasPendingConnections() && - !d->server->waitForNewConnection(msecs))) - return false; - } else if (!socket->waitForConnected(msecs)) { - return false; - } - // wait for handshake - d->handshakeTimer.start(); - d->handshakeEventLoop.exec(); - return d->gotHello; -} - -QString QQmlDebugConnection::stateString() const -{ - QString state; - - if (isConnected()) - state = "Connected"; - else - state = "Not connected"; - - if (d->gotHello) - state += ", got hello"; - else - state += ", did not get hello!"; - - return state; -} - -QAbstractSocket::SocketState QQmlDebugConnection::state() const -{ - QAbstractSocket *abstractSocket = qobject_cast<QAbstractSocket*>(d->device); - if (abstractSocket) - return abstractSocket->state(); - - QLocalSocket *localSocket = qobject_cast<QLocalSocket*>(d->device); - if (localSocket) - return static_cast<QAbstractSocket::SocketState>(localSocket->state()); - - return QAbstractSocket::UnconnectedState; -} - -void QQmlDebugConnection::flush() -{ - QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); - if (socket) { - socket->flush(); - return; - } -} - -void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port) -{ - QTcpSocket *socket = new QTcpSocket(d); - socket->setProxy(QNetworkProxy::NoProxy); - d->device = socket; - d->connectDeviceSignals(); - d->gotHello = false; - connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SIGNAL(stateChanged(QAbstractSocket::SocketState))); - connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))); - connect(socket, SIGNAL(connected()), this, SIGNAL(connected())); - socket->connectToHost(hostName, port); - QIODevice::open(ReadWrite | Unbuffered); -} - -void QQmlDebugConnection::startLocalServer(const QString &fileName) -{ - d->gotHello = false; - d->server = new QLocalServer(d); - // QueuedConnection so that waitForNewConnection() returns true. - connect(d->server, SIGNAL(newConnection()), d, SLOT(newConnection()), Qt::QueuedConnection); - d->server->listen(fileName); - QIODevice::open(ReadWrite | Unbuffered); -} - -void QQmlDebugConnectionPrivate::newConnection() -{ - QLocalSocket *socket = server->nextPendingConnection(); - server->close(); - device = socket; - connectDeviceSignals(); - connect(socket, SIGNAL(stateChanged(QLocalSocket::LocalSocketState)), - this, SLOT(forwardStateChange(QLocalSocket::LocalSocketState))); - connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)), - this, SLOT(forwardError(QLocalSocket::LocalSocketError))); - emit q->connected(); -} - -void QQmlDebugConnectionPrivate::connectDeviceSignals() -{ - connect(device, SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64))); - connect(device, SIGNAL(readyRead()), q, SIGNAL(readyRead())); - connect(device, SIGNAL(aboutToClose()), this, SLOT(deviceAboutToClose())); -} - -void QQmlDebugConnectionPrivate::forwardStateChange(QLocalSocket::LocalSocketState state) -{ - emit q->stateChanged(static_cast<QAbstractSocket::SocketState>(state)); -} - -void QQmlDebugConnectionPrivate::forwardError(QLocalSocket::LocalSocketError error) -{ - emit q->error(static_cast<QAbstractSocket::SocketError>(error)); -} - -QQmlDebugClientPrivate::QQmlDebugClientPrivate() - : connection(0) -{ -} - -QQmlDebugClient::QQmlDebugClient(const QString &name, - QQmlDebugConnection *parent) - : QObject(parent), - d(new QQmlDebugClientPrivate) -{ - d->name = name; - d->connection = parent; - - if (!d->connection) - return; - - if (d->connection->d->plugins.contains(name)) { - qWarning() << "QQmlDebugClient: Conflicting plugin name" << name; - d->connection = 0; - } else { - d->connection->d->plugins.insert(name, this); - d->connection->d->advertisePlugins(); - } -} - -QQmlDebugClient::~QQmlDebugClient() -{ - if (d->connection && d->connection->d) { - d->connection->d->plugins.remove(d->name); - d->connection->d->advertisePlugins(); - } - delete d; -} - -QString QQmlDebugClient::name() const -{ - return d->name; -} - -float QQmlDebugClient::serviceVersion() const -{ - if (d->connection->d->serverPlugins.contains(d->name)) - return d->connection->d->serverPlugins.value(d->name); - return -1; -} - -QQmlDebugClient::State QQmlDebugClient::state() const -{ - if (!d->connection - || !d->connection->isConnected() - || !d->connection->d->gotHello) - return NotConnected; - - if (d->connection->d->serverPlugins.contains(d->name)) - return Enabled; - - return Unavailable; -} - -QString QQmlDebugClient::stateString() const -{ - switch (state()) { - case NotConnected: return QLatin1String("Not connected"); - case Unavailable: return QLatin1String("Unavailable"); - case Enabled: return QLatin1String("Enabled"); - } - return QLatin1String("Invalid"); -} - -void QQmlDebugClient::sendMessage(const QByteArray &message) -{ - if (state() != Enabled) - return; - - QPacket pack; - pack << d->name << message; - d->connection->d->protocol->send(pack); - d->connection->flush(); -} - -void QQmlDebugClient::stateChanged(State) -{ -} - -void QQmlDebugClient::messageReceived(const QByteArray &) -{ -} - -#include <qqmldebugclient.moc> diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp index 9b48b40c07..ef5c3e09ca 100644 --- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp +++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include "qqmlenginedebugclient.h" -#include "qdatastream.h" +#include <private/qqmldebugconnection_p.h> struct QmlObjectData { QUrl url; @@ -46,7 +46,7 @@ struct QmlObjectData { int parentId; }; -QDataStream &operator>>(QDataStream &ds, QmlObjectData &data) +QPacket &operator>>(QPacket &ds, QmlObjectData &data) { ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString >> data.objectName >> data.objectType >> data.objectId >> data.contextId @@ -64,7 +64,7 @@ struct QmlObjectProperty { bool hasNotifySignal; }; -QDataStream &operator>>(QDataStream &ds, QmlObjectProperty &data) +QPacket &operator>>(QPacket &ds, QmlObjectProperty &data) { int type; ds >> type >> data.name >> data.value >> data.valueTypeName @@ -77,8 +77,7 @@ QQmlEngineDebugClient::QQmlEngineDebugClient( QQmlDebugConnection *connection) : QQmlDebugClient(QLatin1String("QmlDebugger"), connection), m_nextId(0), - m_valid(false), - m_connection(connection) + m_valid(false) { } @@ -89,11 +88,10 @@ quint32 QQmlEngineDebugClient::addWatch( *success = false; if (state() == QQmlDebugClient::Enabled) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("WATCH_PROPERTY") << id << property.objectDebugId << property.name.toUtf8(); - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -115,10 +113,9 @@ quint32 QQmlEngineDebugClient::addWatch( *success = false; if (state() == QQmlDebugClient::Enabled) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("WATCH_EXPR_OBJECT") << id << object.debugId << expr; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -131,10 +128,9 @@ quint32 QQmlEngineDebugClient::addWatch( *success = false; if (state() == QQmlDebugClient::Enabled) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("WATCH_OBJECT") << id << object.debugId; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -152,10 +148,9 @@ void QQmlEngineDebugClient::removeWatch(quint32 id, bool *success) { *success = false; if (state() == QQmlDebugClient::Enabled) { - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("NO_WATCH") << id; - sendMessage(message); + sendMessage(ds.data()); *success = true; } } @@ -167,10 +162,9 @@ quint32 QQmlEngineDebugClient::queryAvailableEngines(bool *success) *success = false; if (state() == QQmlDebugClient::Enabled) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("LIST_ENGINES") << id; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -184,10 +178,9 @@ quint32 QQmlEngineDebugClient::queryRootContexts( *success = false; if (state() == QQmlDebugClient::Enabled && engine.debugId != -1) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("LIST_OBJECTS") << id << engine.debugId; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -201,11 +194,9 @@ quint32 QQmlEngineDebugClient::queryObject( *success = false; if (state() == QQmlDebugClient::Enabled && object.debugId != -1) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("FETCH_OBJECT") << id << object.debugId << false << - true; - sendMessage(message); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("FETCH_OBJECT") << id << object.debugId << false << true; + sendMessage(ds.data()); *success = true; } return id; @@ -219,11 +210,10 @@ quint32 QQmlEngineDebugClient::queryObjectsForLocation( *success = false; if (state() == QQmlDebugClient::Enabled) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("FETCH_OBJECTS_FOR_LOCATION") << id << file << lineNumber << columnNumber << false << true; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -237,11 +227,9 @@ quint32 QQmlEngineDebugClient::queryObjectRecursive( *success = false; if (state() == QQmlDebugClient::Enabled && object.debugId != -1) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("FETCH_OBJECT") << id << object.debugId << true << - true; - sendMessage(message); + QPacket ds(connection()->currentDataStreamVersion()); + ds << QByteArray("FETCH_OBJECT") << id << object.debugId << true << true; + sendMessage(ds.data()); *success = true; } return id; @@ -255,11 +243,10 @@ quint32 QQmlEngineDebugClient::queryObjectsForLocationRecursive(const QString &f *success = false; if (state() == QQmlDebugClient::Enabled) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("FETCH_OBJECTS_FOR_LOCATION") << id << file << lineNumber << columnNumber << true << true; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -273,11 +260,10 @@ quint32 QQmlEngineDebugClient::queryExpressionResult( *success = false; if (state() == QQmlDebugClient::Enabled) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr << engines()[0].debugId; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -291,10 +277,9 @@ quint32 QQmlEngineDebugClient::queryExpressionResultBC( *success = false; if (state() == QQmlDebugClient::Enabled) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -312,11 +297,10 @@ quint32 QQmlEngineDebugClient::setBindingForObject( *success = false; if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("SET_BINDING") << id << objectDebugId << propertyName << bindingExpression << isLiteralValue << source << line; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -331,10 +315,9 @@ quint32 QQmlEngineDebugClient::resetBindingForObject( *success = false; if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("RESET_BINDING") << id << objectDebugId << propertyName; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; @@ -348,17 +331,16 @@ quint32 QQmlEngineDebugClient::setMethodBody( *success = false; if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) { id = getId(); - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("SET_METHOD_BODY") << id << objectDebugId << methodName << methodBody; - sendMessage(message); + sendMessage(ds.data()); *success = true; } return id; } -void QQmlEngineDebugClient::decode(QDataStream &ds, +void QQmlEngineDebugClient::decode(QPacket &ds, QmlDebugObjectReference &o, bool simple) { @@ -419,7 +401,7 @@ void QQmlEngineDebugClient::decode(QDataStream &ds, } } -void QQmlEngineDebugClient::decode(QDataStream &ds, +void QQmlEngineDebugClient::decode(QPacket &ds, QList<QmlDebugObjectReference> &o, bool simple) { @@ -432,7 +414,7 @@ void QQmlEngineDebugClient::decode(QDataStream &ds, } } -void QQmlEngineDebugClient::decode(QDataStream &ds, +void QQmlEngineDebugClient::decode(QPacket &ds, QmlDebugContextReference &c) { ds >> c.name >> c.debugId; @@ -460,9 +442,7 @@ void QQmlEngineDebugClient::decode(QDataStream &ds, void QQmlEngineDebugClient::messageReceived(const QByteArray &data) { m_valid = false; - QDataStream ds(data); - ds.setVersion(m_connection->dataStreamVersion()); - + QPacket ds(connection()->currentDataStreamVersion(), data); int queryId; QByteArray type; diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h index 28adb8b159..cd80a8ed46 100644 --- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h +++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h @@ -34,13 +34,12 @@ #ifndef QQMLENGINEDEBUGCLIENT_H #define QQMLENGINEDEBUGCLIENT_H -#include "qqmldebugclient.h" +#include <private/qqmldebugclient_p.h> +#include <private/qpacket_p.h> #include <QtCore/qurl.h> #include <QtCore/qvariant.h> -class QQmlDebugConnection; - struct QmlDebugPropertyReference { QmlDebugPropertyReference() @@ -207,9 +206,9 @@ public: quint32 getId() { return m_nextId++; } - void decode(QDataStream &, QmlDebugContextReference &); - void decode(QDataStream &, QmlDebugObjectReference &, bool simple); - void decode(QDataStream &ds, QList<QmlDebugObjectReference> &o, bool simple); + void decode(QPacket &ds, QmlDebugContextReference &); + void decode(QPacket &ds, QmlDebugObjectReference &, bool simple); + void decode(QPacket &ds, QList<QmlDebugObjectReference> &o, bool simple); QList<QmlDebugEngineReference> engines() { return m_engines; } QmlDebugContextReference rootContext() { return m_rootContext; } @@ -234,8 +233,6 @@ private: QmlDebugObjectReference m_object; QList<QmlDebugObjectReference> m_objects; QVariant m_exprResult; - - QQmlDebugConnection *m_connection; }; #endif // QQMLENGINEDEBUGCLIENT_H diff --git a/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp b/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp index a46bd9012b..5fce58c17d 100644 --- a/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp +++ b/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp @@ -32,33 +32,34 @@ ****************************************************************************/ #include "qqmlinspectorclient.h" -#include "qdatastream.h" + +#include <private/qpacket_p.h> +#include <private/qqmldebugconnection_p.h> +#include <QtCore/qdebug.h> void QQmlInspectorClient::setShowAppOnTop(bool showOnTop) { - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); ds << QByteArray("request") << m_requestId++ << QByteArray("showAppOnTop") << showOnTop; - sendMessage(message); + sendMessage(ds.data()); } void QQmlInspectorClient::reloadQml(const QHash<QString, QByteArray> &changesHash) { - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); + QPacket ds(connection()->currentDataStreamVersion()); m_reloadRequestId = m_requestId; ds << QByteArray("request") << m_requestId++ << QByteArray("reload") << changesHash; - sendMessage(message); + sendMessage(ds.data()); } void QQmlInspectorClient::messageReceived(const QByteArray &message) { - QDataStream ds(message); + QPacket ds(connection()->currentDataStreamVersion(), message); QByteArray type; ds >> type; diff --git a/tests/auto/qml/debugger/shared/qqmlinspectorclient.h b/tests/auto/qml/debugger/shared/qqmlinspectorclient.h index a8b42c8430..964dac7701 100644 --- a/tests/auto/qml/debugger/shared/qqmlinspectorclient.h +++ b/tests/auto/qml/debugger/shared/qqmlinspectorclient.h @@ -33,7 +33,7 @@ #ifndef QQMLINSPECTORCLIENT_H #define QQMLINSPECTORCLIENT_H -#include "qqmldebugclient.h" +#include <private/qqmldebugclient_p.h> class QQmlInspectorClient : public QQmlDebugClient { diff --git a/tests/auto/qml/parserstress/parserstress.pro b/tests/auto/qml/parserstress/parserstress.pro index 8d92d69494..7c37745585 100644 --- a/tests/auto/qml/parserstress/parserstress.pro +++ b/tests/auto/qml/parserstress/parserstress.pro @@ -6,7 +6,5 @@ SOURCES += tst_parserstress.cpp TESTDATA = tests/* -CONFIG += parallel_test QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qjsengine/qjsengine.pro b/tests/auto/qml/qjsengine/qjsengine.pro index fc2452c2bc..c9d78e22a0 100644 --- a/tests/auto/qml/qjsengine/qjsengine.pro +++ b/tests/auto/qml/qjsengine/qjsengine.pro @@ -1,5 +1,4 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qjsengine QT += qml qml-private widgets testlib gui-private macx:CONFIG -= app_bundle @@ -7,4 +6,3 @@ SOURCES += tst_qjsengine.cpp RESOURCES += qjsengine.qrc TESTDATA = script/* -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qjsonbinding/qjsonbinding.pro b/tests/auto/qml/qjsonbinding/qjsonbinding.pro index a54eab198b..75b48aa854 100644 --- a/tests/auto/qml/qjsonbinding/qjsonbinding.pro +++ b/tests/auto/qml/qjsonbinding/qjsonbinding.pro @@ -12,6 +12,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test QT += core qml testlib gui-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qjsvalue/qjsvalue.pro b/tests/auto/qml/qjsvalue/qjsvalue.pro index d914d40762..3bbbbd4787 100644 --- a/tests/auto/qml/qjsvalue/qjsvalue.pro +++ b/tests/auto/qml/qjsvalue/qjsvalue.pro @@ -1,8 +1,6 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qjsvalue macx:CONFIG -= app_bundle QT += qml widgets testlib gui-private SOURCES += tst_qjsvalue.cpp HEADERS += tst_qjsvalue.h -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index bf9bd18807..6553baea76 100644 --- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp @@ -1015,7 +1015,7 @@ void tst_QJSValue::toVariant() { QVariant var = qobject.toVariant(); QCOMPARE(var.userType(), int(QMetaType::QObjectStar)); - QCOMPARE(qVariantValue<QObject*>(var), (QObject *)&temp); + QCOMPARE(qvariant_cast<QObject*>(var), (QObject *)&temp); } { diff --git a/tests/auto/qml/qjsvalueiterator/qjsvalueiterator.pro b/tests/auto/qml/qjsvalueiterator/qjsvalueiterator.pro index 9f4d4fb371..4ee1693ad8 100644 --- a/tests/auto/qml/qjsvalueiterator/qjsvalueiterator.pro +++ b/tests/auto/qml/qjsvalueiterator/qjsvalueiterator.pro @@ -1,9 +1,7 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qjsvalueiterator macx:CONFIG -= app_bundle QT = core qml testlib SOURCES += tst_qjsvalueiterator.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro index 66c19098ef..5e798f3b48 100644 --- a/tests/auto/qml/qml.pro +++ b/tests/auto/qml/qml.pro @@ -57,7 +57,6 @@ PRIVATETESTS += \ qrcqml \ qqmltimer \ qqmlinstantiator \ - qv4debugger \ qqmlenginecleanup \ v4misc \ qqmltranslation \ diff --git a/tests/auto/qml/qmlmin/qmlmin.pro b/tests/auto/qml/qmlmin/qmlmin.pro index 03b60aea19..6af6653270 100644 --- a/tests/auto/qml/qmlmin/qmlmin.pro +++ b/tests/auto/qml/qmlmin/qmlmin.pro @@ -6,7 +6,5 @@ macx:CONFIG -= app_bundle SOURCES += tst_qmlmin.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" -CONFIG += parallel_test cross_compile: DEFINES += QTEST_CROSS_COMPILED -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qmlplugindump/qmlplugindump.pro b/tests/auto/qml/qmlplugindump/qmlplugindump.pro index 902bcad585..c713edc541 100644 --- a/tests/auto/qml/qmlplugindump/qmlplugindump.pro +++ b/tests/auto/qml/qmlplugindump/qmlplugindump.pro @@ -2,7 +2,5 @@ CONFIG += testcase TARGET = tst_qmlplugindump QT += testlib gui-private macx:CONFIG -= app_bundle -CONFIG += parallel_test SOURCES += tst_qmlplugindump.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlbinding/qqmlbinding.pro b/tests/auto/qml/qqmlbinding/qqmlbinding.pro index 35a5f1ca74..45298f8ffc 100644 --- a/tests/auto/qml/qqmlbinding/qqmlbinding.pro +++ b/tests/auto/qml/qqmlbinding/qqmlbinding.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlchangeset/qqmlchangeset.pro b/tests/auto/qml/qqmlchangeset/qqmlchangeset.pro index b65e58c0b3..9f854f1fa2 100644 --- a/tests/auto/qml/qqmlchangeset/qqmlchangeset.pro +++ b/tests/auto/qml/qqmlchangeset/qqmlchangeset.pro @@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qqmlchangeset.cpp -CONFIG += parallel_test - QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro b/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro index 8151bacd75..9f8c8a4e24 100644 --- a/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro +++ b/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro @@ -13,4 +13,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlconnections/data/test-connection.qml b/tests/auto/qml/qqmlconnections/data/test-connection.qml index ce851fc3db..f44cbc047f 100644 --- a/tests/auto/qml/qqmlconnections/data/test-connection.qml +++ b/tests/auto/qml/qqmlconnections/data/test-connection.qml @@ -6,5 +6,5 @@ Item { property bool tested: false signal testMe - Connections { target: screen; onWidthChanged: screen.tested = true } + Connections { objectName: "connections"; target: screen; onWidthChanged: screen.tested = true } } diff --git a/tests/auto/qml/qqmlconnections/qqmlconnections.pro b/tests/auto/qml/qqmlconnections/qqmlconnections.pro index 7004ee0385..99cc4d0d0b 100644 --- a/tests/auto/qml/qqmlconnections/qqmlconnections.pro +++ b/tests/auto/qml/qqmlconnections/qqmlconnections.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp index e529c74acc..b148baab35 100644 --- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp +++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp @@ -56,6 +56,7 @@ private slots: void errors(); void rewriteErrors(); void singletonTypeTarget(); + void enableDisable_QTBUG_36350(); private: QQmlEngine engine; @@ -329,6 +330,33 @@ void tst_qqmlconnections::singletonTypeTarget() delete object; } +void tst_qqmlconnections::enableDisable_QTBUG_36350() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("test-connection.qml")); + QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QVERIFY(item != 0); + + QQmlConnections *connections = item->findChild<QQmlConnections*>("connections"); + QVERIFY(connections); + + connections->setEnabled(false); + QCOMPARE(item->property("tested").toBool(), false); + QCOMPARE(item->width(), 50.); + emit item->setWidth(100.); + QCOMPARE(item->width(), 100.); + QCOMPARE(item->property("tested").toBool(), false); //Should not have received signal to change property + + connections->setEnabled(true); //Re-enable the connectSignals() + QCOMPARE(item->property("tested").toBool(), false); + QCOMPARE(item->width(), 100.); + emit item->setWidth(50.); + QCOMPARE(item->width(), 50.); + QCOMPARE(item->property("tested").toBool(), true); //Should have received signal to change property + + delete item; +} + QTEST_MAIN(tst_qqmlconnections) #include "tst_qqmlconnections.moc" diff --git a/tests/auto/qml/qqmlconsole/qqmlconsole.pro b/tests/auto/qml/qqmlconsole/qqmlconsole.pro index 0f3f10bd89..99192c4b16 100644 --- a/tests/auto/qml/qqmlconsole/qqmlconsole.pro +++ b/tests/auto/qml/qqmlconsole/qqmlconsole.pro @@ -8,7 +8,4 @@ macx:CONFIG -= app_bundle TESTDATA = data/* -CONFIG += parallel_test - QT += qml testlib gui-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlcontext/qqmlcontext.pro b/tests/auto/qml/qqmlcontext/qqmlcontext.pro index 2fb299cb10..19e5c1072a 100644 --- a/tests/auto/qml/qqmlcontext/qqmlcontext.pro +++ b/tests/auto/qml/qqmlcontext/qqmlcontext.pro @@ -8,7 +8,4 @@ macx:CONFIG -= app_bundle TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlcpputils/qqmlcpputils.pro b/tests/auto/qml/qqmlcpputils/qqmlcpputils.pro index 75436dd8e2..bc692a6e78 100644 --- a/tests/auto/qml/qqmlcpputils/qqmlcpputils.pro +++ b/tests/auto/qml/qqmlcpputils/qqmlcpputils.pro @@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qqmlcpputils.cpp -CONFIG += parallel_test - QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmldirparser/qqmldirparser.pro b/tests/auto/qml/qqmldirparser/qqmldirparser.pro index 0be38a0a35..dda74b1ef9 100644 --- a/tests/auto/qml/qqmldirparser/qqmldirparser.pro +++ b/tests/auto/qml/qqmldirparser/qqmldirparser.pro @@ -6,6 +6,3 @@ macx:CONFIG -= app_bundle SOURCES += tst_qqmldirparser.cpp include (../../shared/util.pri) - -CONFIG += parallel_test -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro b/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro index 6f3f765aba..101181bba0 100644 --- a/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro +++ b/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro @@ -20,5 +20,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private network testlib qtHaveModule(widgets): QT += widgets - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index b30dfcbd0b..5a7732fa9a 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -4910,7 +4910,7 @@ void tst_qqmlecmascript::propertyVarImplicitOwnership() QCOMPARE(rootObject->property("rectCanary").toInt(), 5); QCOMPARE(childObject->property("textCanary").toInt(), 10); QMetaObject::invokeMethod(childObject, "constructQObject"); // creates a reference to a constructed QObject. - QWeakPointer<QObject> qobjectGuard(childObject->property("vp").value<QObject*>()); // get the pointer prior to processing deleteLater events. + QPointer<QObject> qobjectGuard(childObject->property("vp").value<QObject*>()); // get the pointer prior to processing deleteLater events. QVERIFY(!qobjectGuard.isNull()); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper. QCoreApplication::processEvents(); @@ -4933,9 +4933,9 @@ void tst_qqmlecmascript::propertyVarReparent() QObject *rect = object->property("vp").value<QObject*>(); QObject *text = rect->findChild<QObject*>("textOne"); QObject *text2 = rect->findChild<QObject*>("textTwo"); - QWeakPointer<QObject> rectGuard(rect); - QWeakPointer<QObject> textGuard(text); - QWeakPointer<QObject> text2Guard(text2); + QPointer<QObject> rectGuard(rect); + QPointer<QObject> textGuard(text); + QPointer<QObject> text2Guard(text2); QVERIFY(!rectGuard.isNull()); QVERIFY(!textGuard.isNull()); QVERIFY(!text2Guard.isNull()); @@ -4944,7 +4944,7 @@ void tst_qqmlecmascript::propertyVarReparent() // now construct an image which we will reparent. QMetaObject::invokeMethod(text2, "constructQObject"); QObject *image = text2->property("vp").value<QObject*>(); - QWeakPointer<QObject> imageGuard(image); + QPointer<QObject> imageGuard(image); QVERIFY(!imageGuard.isNull()); QCOMPARE(image->property("imageCanary").toInt(), 13); // now reparent the "Image" object (currently, it has JS ownership) @@ -4975,9 +4975,9 @@ void tst_qqmlecmascript::propertyVarReparentNullContext() QObject *rect = object->property("vp").value<QObject*>(); QObject *text = rect->findChild<QObject*>("textOne"); QObject *text2 = rect->findChild<QObject*>("textTwo"); - QWeakPointer<QObject> rectGuard(rect); - QWeakPointer<QObject> textGuard(text); - QWeakPointer<QObject> text2Guard(text2); + QPointer<QObject> rectGuard(rect); + QPointer<QObject> textGuard(text); + QPointer<QObject> text2Guard(text2); QVERIFY(!rectGuard.isNull()); QVERIFY(!textGuard.isNull()); QVERIFY(!text2Guard.isNull()); @@ -4986,7 +4986,7 @@ void tst_qqmlecmascript::propertyVarReparentNullContext() // now construct an image which we will reparent. QMetaObject::invokeMethod(text2, "constructQObject"); QObject *image = text2->property("vp").value<QObject*>(); - QWeakPointer<QObject> imageGuard(image); + QPointer<QObject> imageGuard(image); QVERIFY(!imageGuard.isNull()); QCOMPARE(image->property("imageCanary").toInt(), 13); // now reparent the "Image" object (currently, it has JS ownership) @@ -5044,9 +5044,9 @@ void tst_qqmlecmascript::propertyVarCircular2() QVERIFY(rootObject != 0); QObject *childObject = rootObject->findChild<QObject*>("text"); QVERIFY(childObject != 0); - QWeakPointer<QObject> rootObjectTracker(rootObject); + QPointer<QObject> rootObjectTracker(rootObject); QVERIFY(!rootObjectTracker.isNull()); - QWeakPointer<QObject> childObjectTracker(childObject); + QPointer<QObject> childObjectTracker(childObject); QVERIFY(!childObjectTracker.isNull()); gc(engine); QCOMPARE(rootObject->property("rectCanary").toInt(), 5); @@ -6613,8 +6613,7 @@ void tst_qqmlecmascript::urlPropertyWithEncoding() MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); QVERIFY(object != 0); object->setStringProperty("http://qt-project.org"); - QUrl encoded; - encoded.setEncodedUrl("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode); + const QUrl encoded = QUrl::fromEncoded("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode); QCOMPARE(object->urlProperty(), encoded); QCOMPARE(object->value(), 0); // Interpreting URL as string yields canonicalised version QCOMPARE(object->property("result").toBool(), true); @@ -6632,8 +6631,7 @@ void tst_qqmlecmascript::urlListPropertyWithEncoding() MySequenceConversionObject *msco3 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco3")); MySequenceConversionObject *msco4 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco4")); QVERIFY(msco1 != 0 && msco2 != 0 && msco3 != 0 && msco4 != 0); - QUrl encoded; - encoded.setEncodedUrl("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode); + const QUrl encoded = QUrl::fromEncoded("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode); QCOMPARE(msco1->urlListProperty(), (QList<QUrl>() << encoded)); QCOMPARE(msco2->urlListProperty(), (QList<QUrl>() << encoded)); QCOMPARE(msco3->urlListProperty(), (QList<QUrl>() << encoded << encoded)); @@ -7332,7 +7330,7 @@ void tst_qqmlecmascript::sequenceSort_data() QString fnName = QLatin1String("test_") + testName; bool useComparer = c != 0; testName += useComparer ? QLatin1String("[custom]") : QLatin1String("[default]"); - QTest::newRow(testName.toAscii().constData()) << fnName << useComparer; + QTest::newRow(testName.toLatin1().constData()) << fnName << useComparer; } } } @@ -7351,7 +7349,7 @@ void tst_qqmlecmascript::sequenceSort() QVERIFY(object != 0); QVariant q; - QMetaObject::invokeMethod(object, function.toAscii().constData(), Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, useComparer)); + QMetaObject::invokeMethod(object, function.toLatin1().constData(), Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, useComparer)); QVERIFY(q.toBool()); delete object; diff --git a/tests/auto/qml/qqmlengine/qqmlengine.pro b/tests/auto/qml/qqmlengine/qqmlengine.pro index e84512fae3..e7952d8e3a 100644 --- a/tests/auto/qml/qqmlengine/qqmlengine.pro +++ b/tests/auto/qml/qqmlengine/qqmlengine.pro @@ -7,4 +7,3 @@ include (../../shared/util.pri) SOURCES += tst_qqmlengine.cpp QT += core-private gui-private qml-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro b/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro index 6428933233..5bcec9f5b4 100644 --- a/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro +++ b/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro @@ -7,4 +7,3 @@ include (../../shared/util.pri) SOURCES += tst_qqmlenginecleanup.cpp QT += testlib qml -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlerror/qqmlerror.pro b/tests/auto/qml/qqmlerror/qqmlerror.pro index 5339f8740b..17a1d1dec7 100644 --- a/tests/auto/qml/qqmlerror/qqmlerror.pro +++ b/tests/auto/qml/qqmlerror/qqmlerror.pro @@ -6,9 +6,6 @@ include (../../shared/util.pri) macx:CONFIG -= app_bundle -CONFIG += parallel_test - TESTDATA = data/* QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlexpression/qqmlexpression.pro b/tests/auto/qml/qqmlexpression/qqmlexpression.pro index 45545b084e..5b1d397555 100644 --- a/tests/auto/qml/qqmlexpression/qqmlexpression.pro +++ b/tests/auto/qml/qqmlexpression/qqmlexpression.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro b/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro index 3475fa4b1d..8a55f4de9c 100644 --- a/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro +++ b/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro @@ -8,6 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlglobal/qqmlglobal.pro b/tests/auto/qml/qqmlglobal/qqmlglobal.pro index d0d9fc400e..dbc8806de7 100644 --- a/tests/auto/qml/qqmlglobal/qqmlglobal.pro +++ b/tests/auto/qml/qqmlglobal/qqmlglobal.pro @@ -3,6 +3,4 @@ TARGET = tst_qqmlglobal SOURCES += tst_qqmlglobal.cpp macx:CONFIG -= app_bundle -CONFIG += parallel_test QT += qml-private testlib core-private gui-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlimport/qqmlimport.pro b/tests/auto/qml/qqmlimport/qqmlimport.pro index 6c99c00570..c8b0f68d9f 100644 --- a/tests/auto/qml/qqmlimport/qqmlimport.pro +++ b/tests/auto/qml/qqmlimport/qqmlimport.pro @@ -6,6 +6,3 @@ osx:CONFIG -= app_bundle SOURCES += tst_qqmlimport.cpp include (../../shared/util.pri) - -CONFIG += parallel_test -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp index c53977482b..ab3d020c82 100644 --- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp +++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp @@ -81,7 +81,7 @@ void tst_QQmlImport::testDesignerSupported() warningString.remove('\r'); #endif warningString = warningString.arg(testFileUrl("testfile_unsupported.qml").toString()); - QTest::ignoreMessage(QtWarningMsg, warningString.toAscii()); + QTest::ignoreMessage(QtWarningMsg, warningString.toLocal8Bit()); window->setSource(testFileUrl("testfile_unsupported.qml")); QVERIFY(!window->errors().isEmpty()); diff --git a/tests/auto/qml/qqmlincubator/qqmlincubator.pro b/tests/auto/qml/qqmlincubator/qqmlincubator.pro index 9249061912..e5fa45f1d3 100644 --- a/tests/auto/qml/qqmlincubator/qqmlincubator.pro +++ b/tests/auto/qml/qqmlincubator/qqmlincubator.pro @@ -11,7 +11,5 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test QT += core-private gui-private qml-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlinfo/qqmlinfo.pro b/tests/auto/qml/qqmlinfo/qqmlinfo.pro index e813982210..89b4abd00c 100644 --- a/tests/auto/qml/qqmlinfo/qqmlinfo.pro +++ b/tests/auto/qml/qqmlinfo/qqmlinfo.pro @@ -8,6 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlitemmodels/qqmlitemmodels.pro b/tests/auto/qml/qqmlitemmodels/qqmlitemmodels.pro index f76c6d0d25..d50c630003 100644 --- a/tests/auto/qml/qqmlitemmodels/qqmlitemmodels.pro +++ b/tests/auto/qml/qqmlitemmodels/qqmlitemmodels.pro @@ -9,10 +9,7 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core qml testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 DISTFILES += \ data/modelindex.qml \ diff --git a/tests/auto/qml/qqmllanguage/qqmllanguage.pro b/tests/auto/qml/qqmllanguage/qqmllanguage.pro index f0c8bb6c1b..99c0c3e823 100644 --- a/tests/auto/qml/qqmllanguage/qqmllanguage.pro +++ b/tests/auto/qml/qqmllanguage/qqmllanguage.pro @@ -15,7 +15,6 @@ TESTDATA = data/* QT += core-private gui-private qml-private network testlib include (../../shared/util.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 OTHER_FILES += \ data/readonlyObjectProperty.qml diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 1f299c0dbb..32b0d9661f 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -677,8 +677,7 @@ void tst_qqmllanguage::assignBasicTypes() QCOMPARE(object->variantProperty(), QVariant("Hello World!")); QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2f)); QCOMPARE(object->vector4Property(), QVector4D(10, 1, 2.2f, 2.3f)); - QUrl encoded; - encoded.setEncodedUrl("main.qml?with%3cencoded%3edata", QUrl::TolerantMode); + const QUrl encoded = QUrl::fromEncoded("main.qml?with%3cencoded%3edata", QUrl::TolerantMode); QCOMPARE(object->urlProperty(), component.url().resolved(encoded)); QVERIFY(object->objectProperty() != 0); MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty()); @@ -1156,8 +1155,7 @@ void tst_qqmllanguage::bindTypeToJSValue() } { MyQmlObject *object = root->findChild<MyQmlObject *>("urlProperty"); QJSValue value = object->qjsvalue(); - QUrl encoded; - encoded.setEncodedUrl("main.qml?with%3cencoded%3edata", QUrl::TolerantMode); + const QUrl encoded = QUrl::fromEncoded("main.qml?with%3cencoded%3edata", QUrl::TolerantMode); QCOMPARE(value.toString(), component.url().resolved(encoded).toString()); } { MyQmlObject *object = root->findChild<MyQmlObject *>("objectProperty"); diff --git a/tests/auto/qml/qqmllistcompositor/qqmllistcompositor.pro b/tests/auto/qml/qqmllistcompositor/qqmllistcompositor.pro index e6c9dc3a29..4ada590a2a 100644 --- a/tests/auto/qml/qqmllistcompositor/qqmllistcompositor.pro +++ b/tests/auto/qml/qqmllistcompositor/qqmllistcompositor.pro @@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qqmllistcompositor.cpp -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro b/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro index 1555dc2b2c..8e3aed0baf 100644 --- a/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro +++ b/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmllistmodelworkerscript/qqmllistmodelworkerscript.pro b/tests/auto/qml/qqmllistmodelworkerscript/qqmllistmodelworkerscript.pro index 7647c3d713..9e1cea9867 100644 --- a/tests/auto/qml/qqmllistmodelworkerscript/qqmllistmodelworkerscript.pro +++ b/tests/auto/qml/qqmllistmodelworkerscript/qqmllistmodelworkerscript.pro @@ -9,4 +9,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmllistreference/qqmllistreference.pro b/tests/auto/qml/qqmllistreference/qqmllistreference.pro index f30b245975..dceb7d1133 100644 --- a/tests/auto/qml/qqmllistreference/qqmllistreference.pro +++ b/tests/auto/qml/qqmllistreference/qqmllistreference.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmllocale/qqmllocale.pro b/tests/auto/qml/qqmllocale/qqmllocale.pro index 6d8eccd61c..d3d022b44e 100644 --- a/tests/auto/qml/qqmllocale/qqmllocale.pro +++ b/tests/auto/qml/qqmllocale/qqmllocale.pro @@ -8,7 +8,5 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test QT += qml testlib gui-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro b/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro index 87f70852fa..03aaf8ecdd 100644 --- a/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro +++ b/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro @@ -8,6 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test QT += qml testlib gui-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro b/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro index 54a6e0507f..0d8de91931 100644 --- a/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro +++ b/tests/auto/qml/qqmlmetatype/qqmlmetatype.pro @@ -6,6 +6,4 @@ macx:CONFIG -= app_bundle TESTDATA = data/* include (../../shared/util.pri) -CONFIG += parallel_test QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidFirstCommandModule/invalidFirstCommandModule.pro b/tests/auto/qml/qqmlmoduleplugin/invalidFirstCommandModule/invalidFirstCommandModule.pro index 9a6ee63b88..523c6eaea1 100644 --- a/tests/auto/qml/qqmlmoduleplugin/invalidFirstCommandModule/invalidFirstCommandModule.pro +++ b/tests/auto/qml/qqmlmoduleplugin/invalidFirstCommandModule/invalidFirstCommandModule.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro b/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro index 002f177cfd..4a8ce58edc 100644 --- a/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro +++ b/tests/auto/qml/qqmlmoduleplugin/invalidNamespaceModule/invalidNamespaceModule.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro index 562d109179..150f2f08d3 100644 --- a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro +++ b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/nestedPlugin/nestedPlugin.pro b/tests/auto/qml/qqmlmoduleplugin/nestedPlugin/nestedPlugin.pro index 5636941951..eca74e9bef 100644 --- a/tests/auto/qml/qqmlmoduleplugin/nestedPlugin/nestedPlugin.pro +++ b/tests/auto/qml/qqmlmoduleplugin/nestedPlugin/nestedPlugin.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro index 0d900eb707..49d290132b 100644 --- a/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro +++ b/tests/auto/qml/qqmlmoduleplugin/nonstrictModule/nonstrictModule.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.2.1.pro b/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.2.1.pro index 445b98d647..9389679f2d 100644 --- a/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.2.1.pro +++ b/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.2.1.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro b/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro index 00c076d9cf..76544aa553 100644 --- a/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro +++ b/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro @@ -11,4 +11,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.pro b/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.pro index 3a0455569e..bd1399b1aa 100644 --- a/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.pro +++ b/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginMixed/pluginMixed.pro b/tests/auto/qml/qqmlmoduleplugin/pluginMixed/pluginMixed.pro index d3b237b0f7..c7e0f6dc09 100644 --- a/tests/auto/qml/qqmlmoduleplugin/pluginMixed/pluginMixed.pro +++ b/tests/auto/qml/qqmlmoduleplugin/pluginMixed/pluginMixed.pro @@ -11,4 +11,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginVersion/pluginVersion.pro b/tests/auto/qml/qqmlmoduleplugin/pluginVersion/pluginVersion.pro index 5cec9b8ebd..bc9ee5c102 100644 --- a/tests/auto/qml/qqmlmoduleplugin/pluginVersion/pluginVersion.pro +++ b/tests/auto/qml/qqmlmoduleplugin/pluginVersion/pluginVersion.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro b/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro index ba66d60f18..9decde52bf 100644 --- a/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro +++ b/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro @@ -11,4 +11,3 @@ IMPORT_FILES = \ MyQmlFile.qml include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/pluginWrongCase.pro b/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/pluginWrongCase.pro index 99bac141de..26f553ea89 100644 --- a/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/pluginWrongCase.pro +++ b/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/pluginWrongCase.pro @@ -11,4 +11,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro index 22926bf1ca..45255800f3 100644 --- a/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro +++ b/tests/auto/qml/qqmlmoduleplugin/preemptedStrictModule/preemptedStrictModule.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro b/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro index c07f0621f7..745d1dc405 100644 --- a/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro +++ b/tests/auto/qml/qqmlmoduleplugin/preemptiveModule/preemptiveModule.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro b/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro index 749a440ca8..fb64f4415f 100644 --- a/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro +++ b/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro index b715c6b82e..5c30d8cc00 100644 --- a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro +++ b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro @@ -22,6 +22,4 @@ SUBDIRS =\ tst_qqmlmoduleplugin_pro.depends += plugin SUBDIRS += tst_qqmlmoduleplugin.pro -CONFIG += parallel_test - QT += core-private gui-private qml-private diff --git a/tests/auto/qml/qqmlmoduleplugin/strictModule.2/strictModule.2.pro b/tests/auto/qml/qqmlmoduleplugin/strictModule.2/strictModule.2.pro index 14f3c59c21..b87cd19e0d 100644 --- a/tests/auto/qml/qqmlmoduleplugin/strictModule.2/strictModule.2.pro +++ b/tests/auto/qml/qqmlmoduleplugin/strictModule.2/strictModule.2.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro b/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro index bf1c5df1a7..aedca480d3 100644 --- a/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro +++ b/tests/auto/qml/qqmlmoduleplugin/strictModule/strictModule.pro @@ -10,4 +10,3 @@ IMPORT_FILES = \ qmldir include (../../../shared/imports.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.pro b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.pro index c483ef8ccd..43bd112415 100644 --- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.pro +++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.pro @@ -11,4 +11,3 @@ include (../../shared/util.pri) TESTDATA = data/* imports/* $$OUT_PWD/imports/* QT += core-private gui-private qml-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro b/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro index f8232f8854..88bb630e29 100644 --- a/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro +++ b/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro @@ -4,7 +4,5 @@ osx:CONFIG -= app_bundle SOURCES += tst_qqmlobjectmodel.cpp -CONFIG += parallel_test - QT += qml testlib QT += core-private qml-private diff --git a/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro b/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro index c81394e77e..f29a444395 100644 --- a/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro +++ b/tests/auto/qml/qqmlopenmetaobject/qqmlopenmetaobject.pro @@ -4,6 +4,4 @@ osx:CONFIG -= app_bundle SOURCES += tst_qqmlopenmetaobject.cpp -CONFIG += parallel_test QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlparser/qqmlparser.pro b/tests/auto/qml/qqmlparser/qqmlparser.pro index c666b71d6c..74cb620f06 100644 --- a/tests/auto/qml/qqmlparser/qqmlparser.pro +++ b/tests/auto/qml/qqmlparser/qqmlparser.pro @@ -6,7 +6,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qqmlparser.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" -CONFIG += parallel_test - cross_compile: DEFINES += QTEST_CROSS_COMPILED -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlproperty/qqmlproperty.pro b/tests/auto/qml/qqmlproperty/qqmlproperty.pro index c2177d5fbf..b1bcf1f17d 100644 --- a/tests/auto/qml/qqmlproperty/qqmlproperty.pro +++ b/tests/auto/qml/qqmlproperty/qqmlproperty.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlpropertycache/qqmlpropertycache.pro b/tests/auto/qml/qqmlpropertycache/qqmlpropertycache.pro index 7cc83cd440..9a04c899fe 100644 --- a/tests/auto/qml/qqmlpropertycache/qqmlpropertycache.pro +++ b/tests/auto/qml/qqmlpropertycache/qqmlpropertycache.pro @@ -4,6 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qqmlpropertycache.cpp -CONFIG += parallel_test QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlpropertymap/qqmlpropertymap.pro b/tests/auto/qml/qqmlpropertymap/qqmlpropertymap.pro index 81212bb064..8da300171d 100644 --- a/tests/auto/qml/qqmlpropertymap/qqmlpropertymap.pro +++ b/tests/auto/qml/qqmlpropertymap/qqmlpropertymap.pro @@ -6,7 +6,4 @@ SOURCES += tst_qqmlpropertymap.cpp include (../../shared/util.pri) -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlqt/qqmlqt.pro b/tests/auto/qml/qqmlqt/qqmlqt.pro index 0470156e28..74306d704f 100644 --- a/tests/auto/qml/qqmlqt/qqmlqt.pro +++ b/tests/auto/qml/qqmlqt/qqmlqt.pro @@ -9,4 +9,3 @@ macx:CONFIG -= app_bundle TESTDATA = data/* QT += core-private qml-private quick-private testlib gui gui-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlsettings/qqmlsettings.pro b/tests/auto/qml/qqmlsettings/qqmlsettings.pro index efcef27f7e..392f496dc8 100644 --- a/tests/auto/qml/qqmlsettings/qqmlsettings.pro +++ b/tests/auto/qml/qqmlsettings/qqmlsettings.pro @@ -9,4 +9,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += qml testlib -CONFIG += parallel_test diff --git a/tests/auto/qml/qqmlsqldatabase/qqmlsqldatabase.pro b/tests/auto/qml/qqmlsqldatabase/qqmlsqldatabase.pro index c32f3c6c34..fbb873b649 100644 --- a/tests/auto/qml/qqmlsqldatabase/qqmlsqldatabase.pro +++ b/tests/auto/qml/qqmlsqldatabase/qqmlsqldatabase.pro @@ -9,4 +9,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private sql testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro b/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro index 002af1d707..635f2fa5e0 100644 --- a/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro +++ b/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro @@ -6,6 +6,4 @@ SOURCES += tst_qqmlstatemachine.cpp include (../../shared/util.pri) -CONFIG += parallel_test QT += core-private gui-private qml-private quick-private gui testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmltimer/qqmltimer.pro b/tests/auto/qml/qqmltimer/qqmltimer.pro index 28f8e6959f..da66bc87ca 100644 --- a/tests/auto/qml/qqmltimer/qqmltimer.pro +++ b/tests/auto/qml/qqmltimer/qqmltimer.pro @@ -4,6 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qqmltimer.cpp -CONFIG += parallel_test QT += core-private gui-private qml-private quick-private gui testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmltranslation/qqmltranslation.pro b/tests/auto/qml/qqmltranslation/qqmltranslation.pro index 6ccec6fc7d..ac329a204b 100644 --- a/tests/auto/qml/qqmltranslation/qqmltranslation.pro +++ b/tests/auto/qml/qqmltranslation/qqmltranslation.pro @@ -9,7 +9,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro index 9e2261df8d..3a20e94741 100644 --- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro +++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro @@ -7,5 +7,3 @@ SOURCES += tst_qqmltypeloader.cpp include (../../shared/util.pri) -CONFIG += parallel_test -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlvaluetypeproviders/qqmlvaluetypeproviders.pro b/tests/auto/qml/qqmlvaluetypeproviders/qqmlvaluetypeproviders.pro index 7ef81e0cc4..0c36088853 100644 --- a/tests/auto/qml/qqmlvaluetypeproviders/qqmlvaluetypeproviders.pro +++ b/tests/auto/qml/qqmlvaluetypeproviders/qqmlvaluetypeproviders.pro @@ -11,7 +11,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private gui testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlvaluetypes/qqmlvaluetypes.pro b/tests/auto/qml/qqmlvaluetypes/qqmlvaluetypes.pro index e36be45f41..36b36d2f0e 100644 --- a/tests/auto/qml/qqmlvaluetypes/qqmlvaluetypes.pro +++ b/tests/auto/qml/qqmlvaluetypes/qqmlvaluetypes.pro @@ -11,10 +11,7 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private gui testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 DISTFILES += \ data/customvaluetype.qml diff --git a/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro b/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro index fcfdf23d33..44b2963918 100644 --- a/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro +++ b/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro @@ -13,4 +13,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro b/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro index c4fdcdc7dd..23b9117889 100644 --- a/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro +++ b/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro @@ -8,8 +8,6 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 RESOURCES += data/introspect.qrc diff --git a/tests/auto/qml/qquickworkerscript/qquickworkerscript.pro b/tests/auto/qml/qquickworkerscript/qquickworkerscript.pro index 268b45f4e7..be8b9089a2 100644 --- a/tests/auto/qml/qquickworkerscript/qquickworkerscript.pro +++ b/tests/auto/qml/qquickworkerscript/qquickworkerscript.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qrcqml/qrcqml.pro b/tests/auto/qml/qrcqml/qrcqml.pro index 3bbc6d6085..60ccba27f2 100644 --- a/tests/auto/qml/qrcqml/qrcqml.pro +++ b/tests/auto/qml/qrcqml/qrcqml.pro @@ -5,6 +5,3 @@ macx:CONFIG -= app_bundle SOURCES += tst_qrcqml.cpp RESOURCES = qrcqml.qrc - -CONFIG += parallel_test -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qtqmlmodules/qtqmlmodules.pro b/tests/auto/qml/qtqmlmodules/qtqmlmodules.pro index c6d442ecac..69e14aaecf 100644 --- a/tests/auto/qml/qtqmlmodules/qtqmlmodules.pro +++ b/tests/auto/qml/qtqmlmodules/qtqmlmodules.pro @@ -9,4 +9,3 @@ macx:CONFIG -= app_bundle TESTDATA = data/* QT += core-private qml-private testlib gui gui-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qv4debugger/qv4debugger.pro b/tests/auto/qml/qv4debugger/qv4debugger.pro deleted file mode 100644 index 540cab70e6..0000000000 --- a/tests/auto/qml/qv4debugger/qv4debugger.pro +++ /dev/null @@ -1,15 +0,0 @@ -CONFIG += testcase -TARGET = tst_qv4debugger -macx:CONFIG -= app_bundle - -SOURCES += \ - $$PWD/tst_qv4debugger.cpp \ - $$PWD/../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp - -HEADERS += \ - $$PWD/../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h - -INCLUDEPATH += \ - $$PWD/../../../../src/plugins/qmltooling/qmldbg_debugger - -QT += core-private gui-private qml-private network testlib diff --git a/tests/auto/qml/v4misc/v4misc.pro b/tests/auto/qml/v4misc/v4misc.pro index d68025f410..5150df5999 100644 --- a/tests/auto/qml/v4misc/v4misc.pro +++ b/tests/auto/qml/v4misc/v4misc.pro @@ -4,6 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_v4misc.cpp -CONFIG += parallel_test QT += core-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qmldevtools/compile/compile.pro b/tests/auto/qmldevtools/compile/compile.pro index 0ed113a031..186ef71e8d 100644 --- a/tests/auto/qmldevtools/compile/compile.pro +++ b/tests/auto/qmldevtools/compile/compile.pro @@ -12,4 +12,3 @@ macx:CONFIG -= app_bundle SOURCES += tst_compile.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qmltest/qmltest.pro b/tests/auto/qmltest/qmltest.pro index 7662cb1687..54db7a78ab 100644 --- a/tests/auto/qmltest/qmltest.pro +++ b/tests/auto/qmltest/qmltest.pro @@ -10,6 +10,5 @@ importFiles.files = borderimage buttonclick createbenchmark events qqmlbindi importFiles.path = . DEPLOYMENT += importFiles -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 CONFIG+=insignificant_test # QTBUG-33723 diff --git a/tests/auto/quick/examples/examples.pro b/tests/auto/quick/examples/examples.pro index 3d821fc13d..fd8cfd83c8 100644 --- a/tests/auto/quick/examples/examples.pro +++ b/tests/auto/quick/examples/examples.pro @@ -6,9 +6,7 @@ macx:CONFIG -= app_bundle SOURCES += tst_examples.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" -CONFIG += parallel_test #temporary QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 !qtHaveModule(xmlpatterns): DEFINES += QT_NO_XMLPATTERNS diff --git a/tests/auto/quick/geometry/geometry.pro b/tests/auto/quick/geometry/geometry.pro index 4a225c2546..0b7e64d038 100644 --- a/tests/auto/quick/geometry/geometry.pro +++ b/tests/auto/quick/geometry/geometry.pro @@ -7,4 +7,3 @@ SOURCES += tst_geometry.cpp CONFIG+=parallel_test QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/nodes/nodes.pro b/tests/auto/quick/nodes/nodes.pro index 256318a441..6cfcc43a98 100644 --- a/tests/auto/quick/nodes/nodes.pro +++ b/tests/auto/quick/nodes/nodes.pro @@ -7,4 +7,3 @@ SOURCES += tst_nodestest.cpp CONFIG+=parallel_test QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/nokeywords/nokeywords.pro b/tests/auto/quick/nokeywords/nokeywords.pro index 51fd490cb7..6872dac22a 100644 --- a/tests/auto/quick/nokeywords/nokeywords.pro +++ b/tests/auto/quick/nokeywords/nokeywords.pro @@ -7,4 +7,3 @@ SOURCES += tst_nokeywords.cpp CONFIG+=parallel_test QT += quick core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickaccessible/qquickaccessible.pro b/tests/auto/quick/qquickaccessible/qquickaccessible.pro index bdbe2e3fb4..02915e8e22 100644 --- a/tests/auto/quick/qquickaccessible/qquickaccessible.pro +++ b/tests/auto/quick/qquickaccessible/qquickaccessible.pro @@ -16,12 +16,9 @@ OTHER_FILES += data/checkbuttons.qml \ data/statictext.qml \ data/ignored.qml \ -CONFIG += parallel_test - wince*: { accessneeded.files = $$QT.widgets.plugins/accessible/*.dll accessneeded.path = accessible DEPLOYMENT += accessneeded } -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickanchors/qquickanchors.pro b/tests/auto/quick/qquickanchors/qquickanchors.pro index 184066753b..a5b47e3797 100644 --- a/tests/auto/quick/qquickanchors/qquickanchors.pro +++ b/tests/auto/quick/qquickanchors/qquickanchors.pro @@ -9,7 +9,4 @@ macx:CONFIG -= app_bundle TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickanimatedimage/qquickanimatedimage.pro b/tests/auto/quick/qquickanimatedimage/qquickanimatedimage.pro index 83607137e1..5792626720 100644 --- a/tests/auto/quick/qquickanimatedimage/qquickanimatedimage.pro +++ b/tests/auto/quick/qquickanimatedimage/qquickanimatedimage.pro @@ -11,4 +11,3 @@ macx:CONFIG -= app_bundle TESTDATA = data/* QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro b/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro index 3e47844feb..81c73be831 100644 --- a/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro +++ b/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro @@ -8,10 +8,7 @@ macx:CONFIG -= app_bundle TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 OTHER_FILES += \ data/largeAnimation.qml diff --git a/tests/auto/quick/qquickanimationcontroller/qquickanimationcontroller.pro b/tests/auto/quick/qquickanimationcontroller/qquickanimationcontroller.pro index b5e03ee620..6909922cb1 100644 --- a/tests/auto/quick/qquickanimationcontroller/qquickanimationcontroller.pro +++ b/tests/auto/quick/qquickanimationcontroller/qquickanimationcontroller.pro @@ -3,8 +3,6 @@ TEMPLATE=app TARGET=tst_qquickanimationcontroller CONFIG += qmltestcase -CONFIG += parallel_test SOURCES += tst_qquickanimationcontroller.cpp TESTDATA = data/* -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickanimations/qquickanimations.pro b/tests/auto/quick/qquickanimations/qquickanimations.pro index dc8f471259..8bb1f47af5 100644 --- a/tests/auto/quick/qquickanimations/qquickanimations.pro +++ b/tests/auto/quick/qquickanimations/qquickanimations.pro @@ -8,7 +8,60 @@ macx:CONFIG -= app_bundle TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +OTHER_FILES += \ + data/attached.qml \ + data/badproperty1.qml \ + data/badproperty2.qml \ + data/badtype1.qml \ + data/badtype2.qml \ + data/badtype3.qml \ + data/badtype4.qml \ + data/disabledTransition.qml \ + data/dontAutoStart.qml \ + data/dontStart.qml \ + data/dontStart2.qml \ + data/dotproperty.qml \ + data/Double.qml \ + data/doubleRegistrationBug.qml \ + data/looping.qml \ + data/mixedtype1.qml \ + data/mixedtype2.qml \ + data/nonTransitionBug.qml \ + data/parallelAnimationNullChildBug.qml \ + data/pathAnimation.qml \ + data/pathAnimation2.qml \ + data/pathAnimationInOutBackCrash.qml \ + data/pathAnimationNoStart.qml \ + data/pathInterpolator.qml \ + data/pathInterpolatorBack.qml \ + data/pathInterpolatorBack2.qml \ + data/pathTransition.qml \ + data/pauseBindingBug.qml \ + data/pauseBug.qml \ + data/properties.qml \ + data/properties2.qml \ + data/properties3.qml \ + data/properties4.qml \ + data/properties5.qml \ + data/propertiesTransition.qml \ + data/propertiesTransition2.qml \ + data/propertiesTransition3.qml \ + data/propertiesTransition4.qml \ + data/propertiesTransition5.qml \ + data/propertiesTransition6.qml \ + data/propertiesTransition7.qml \ + data/reanchor.qml \ + data/registrationBug.qml \ + data/reparent.qml \ + data/rotation.qml \ + data/runningTrueBug.qml \ + data/scriptActionBug.qml \ + data/scriptActionCrash.qml \ + data/sequentialAnimationNullChildBug.qml \ + data/signals.qml \ + data/transitionAssignmentBug.qml \ + data/valuesource.qml \ + data/valuesource2.qml diff --git a/tests/auto/quick/qquickapplication/qquickapplication.pro b/tests/auto/quick/qquickapplication/qquickapplication.pro index 7079478628..59445a6c16 100644 --- a/tests/auto/quick/qquickapplication/qquickapplication.pro +++ b/tests/auto/quick/qquickapplication/qquickapplication.pro @@ -1,9 +1,7 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qquickapplication macx:CONFIG -= app_bundle SOURCES += tst_qquickapplication.cpp QT += core-private gui-private qml quick qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickbehaviors/qquickbehaviors.pro b/tests/auto/quick/qquickbehaviors/qquickbehaviors.pro index f005c03a82..51bc42c390 100644 --- a/tests/auto/quick/qquickbehaviors/qquickbehaviors.pro +++ b/tests/auto/quick/qquickbehaviors/qquickbehaviors.pro @@ -8,7 +8,4 @@ macx:CONFIG -= app_bundle TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickborderimage/qquickborderimage.pro b/tests/auto/quick/qquickborderimage/qquickborderimage.pro index ac213f0265..3e16063559 100644 --- a/tests/auto/quick/qquickborderimage/qquickborderimage.pro +++ b/tests/auto/quick/qquickborderimage/qquickborderimage.pro @@ -11,4 +11,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro b/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro index c770dbb488..3c41d498e5 100644 --- a/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro +++ b/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro @@ -8,7 +8,6 @@ SOURCES += tst_qquickcanvasitem.cpp TESTDATA = data/* OTHER_FILES += \ - data/testhelper.js \ data/tst_transform.qml \ data/tst_text.qml \ data/tst_strokeStyle.qml \ @@ -19,15 +18,38 @@ OTHER_FILES += \ data/tst_line.qml \ data/tst_fillStyle.qml \ data/tst_fillrect.qml \ - data/tst_drawimage.qml \ data/tst_composite.qml \ data/tst_canvas.qml \ data/tst_pixel.qml \ data/tst_gradient.qml \ data/tst_arcto.qml \ data/tst_arc.qml \ - data/tst_context.qml + data/tst_context.qml \ + data/CanvasTestCase.qml \ + data/CanvasComponent.qml \ + data/tst_image.qml \ + data/tst_svgpath.qml \ + data/anim-gr.gif \ + data/anim-gr.png \ + data/anim-poster-gr.png \ + data/background.png \ + data/broken.png \ + data/ggrr-256x256.png \ + data/green-1x1.png \ + data/green-2x2.png \ + data/green-16x16.png \ + data/green-256x256.png \ + data/green.png \ + data/grgr-256x256.png \ + data/red-16x16.png \ + data/red.png \ + data/redtransparent.png \ + data/rgrg-256x256.png \ + data/rrgg-256x256.png \ + data/transparent.png \ + data/transparent50.png \ + data/yellow.png \ + data/yellow75.png -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 CONFIG += insignificant_test # QTBUG-41043 diff --git a/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro b/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro index af932d834b..6e1ad6b95e 100644 --- a/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro +++ b/tests/auto/quick/qquickdesignersupport/qquickdesignersupport.pro @@ -10,7 +10,6 @@ osx:CONFIG -= app_bundle TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 DISTFILES += \ data/TestComponent.qml diff --git a/tests/auto/quick/qquickdrag/qquickdrag.pro b/tests/auto/quick/qquickdrag/qquickdrag.pro index 6e02a4d443..4bc6b2b2f6 100644 --- a/tests/auto/quick/qquickdrag/qquickdrag.pro +++ b/tests/auto/quick/qquickdrag/qquickdrag.pro @@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qquickdrag.cpp -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickdroparea/qquickdroparea.pro b/tests/auto/quick/qquickdroparea/qquickdroparea.pro index c7ffbfd427..a34d5ad009 100644 --- a/tests/auto/quick/qquickdroparea/qquickdroparea.pro +++ b/tests/auto/quick/qquickdroparea/qquickdroparea.pro @@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qquickdroparea.cpp -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickdynamicpropertyanimation/qquickdynamicpropertyanimation.pro b/tests/auto/quick/qquickdynamicpropertyanimation/qquickdynamicpropertyanimation.pro index a67daa91ba..33fa9aff7a 100644 --- a/tests/auto/quick/qquickdynamicpropertyanimation/qquickdynamicpropertyanimation.pro +++ b/tests/auto/quick/qquickdynamicpropertyanimation/qquickdynamicpropertyanimation.pro @@ -8,7 +8,4 @@ macx:CONFIG -= app_bundle TESTDATA = data/* -CONFIG += parallel_test - QT += core gui qml quick testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickflickable/qquickflickable.pro b/tests/auto/quick/qquickflickable/qquickflickable.pro index 88dc2fbc2a..99a840218d 100644 --- a/tests/auto/quick/qquickflickable/qquickflickable.pro +++ b/tests/auto/quick/qquickflickable/qquickflickable.pro @@ -10,4 +10,3 @@ include (../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickflipable/qquickflipable.pro b/tests/auto/quick/qquickflipable/qquickflipable.pro index 3e4d04a401..5a1fb6e816 100644 --- a/tests/auto/quick/qquickflipable/qquickflipable.pro +++ b/tests/auto/quick/qquickflipable/qquickflipable.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickfocusscope/qquickfocusscope.pro b/tests/auto/quick/qquickfocusscope/qquickfocusscope.pro index 9ec643dc4d..7a4b7302d0 100644 --- a/tests/auto/quick/qquickfocusscope/qquickfocusscope.pro +++ b/tests/auto/quick/qquickfocusscope/qquickfocusscope.pro @@ -10,4 +10,3 @@ macx:CONFIG -= app_bundle TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickfontloader/qquickfontloader.pro b/tests/auto/quick/qquickfontloader/qquickfontloader.pro index 2e7300564e..cea5b55bdf 100644 --- a/tests/auto/quick/qquickfontloader/qquickfontloader.pro +++ b/tests/auto/quick/qquickfontloader/qquickfontloader.pro @@ -11,4 +11,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickfontmetrics/qquickfontmetrics.pro b/tests/auto/quick/qquickfontmetrics/qquickfontmetrics.pro index 452dd70bd3..15e3bb00c1 100644 --- a/tests/auto/quick/qquickfontmetrics/qquickfontmetrics.pro +++ b/tests/auto/quick/qquickfontmetrics/qquickfontmetrics.pro @@ -4,7 +4,4 @@ osx:CONFIG -= app_bundle SOURCES += tst_quickfontmetrics.cpp -CONFIG += parallel_test - QT += core gui qml quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro b/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro index 612b6f7283..f4e9e1f890 100644 --- a/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro +++ b/tests/auto/quick/qquickframebufferobject/qquickframebufferobject.pro @@ -7,7 +7,6 @@ include(../../shared/util.pri) macx:CONFIG -= app_bundle -CONFIG += parallel_test QT += quick testlib OTHER_FILES += \ diff --git a/tests/auto/quick/qquickgridview/qquickgridview.pro b/tests/auto/quick/qquickgridview/qquickgridview.pro index 3b98ed4dea..3c33cc78fb 100644 --- a/tests/auto/quick/qquickgridview/qquickgridview.pro +++ b/tests/auto/quick/qquickgridview/qquickgridview.pro @@ -12,4 +12,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickimage/qquickimage.pro b/tests/auto/quick/qquickimage/qquickimage.pro index 9581ae02d1..5b1059bd24 100644 --- a/tests/auto/quick/qquickimage/qquickimage.pro +++ b/tests/auto/quick/qquickimage/qquickimage.pro @@ -12,4 +12,3 @@ include (../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickimageprovider/qquickimageprovider.pro b/tests/auto/quick/qquickimageprovider/qquickimageprovider.pro index 496dc31d30..f67b697c0f 100644 --- a/tests/auto/quick/qquickimageprovider/qquickimageprovider.pro +++ b/tests/auto/quick/qquickimageprovider/qquickimageprovider.pro @@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qquickimageprovider.cpp -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickitem/qquickitem.pro b/tests/auto/quick/qquickitem/qquickitem.pro index 1d8ae0148b..9aca5926f2 100644 --- a/tests/auto/quick/qquickitem/qquickitem.pro +++ b/tests/auto/quick/qquickitem/qquickitem.pro @@ -11,4 +11,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickitem2/qquickitem2.pro b/tests/auto/quick/qquickitem2/qquickitem2.pro index ac4200a8a3..37bfb68f1c 100644 --- a/tests/auto/quick/qquickitem2/qquickitem2.pro +++ b/tests/auto/quick/qquickitem2/qquickitem2.pro @@ -9,4 +9,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro b/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro index a087948f6d..ec890b99b4 100644 --- a/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro +++ b/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro @@ -8,7 +8,6 @@ TESTDATA = data/* include(../../shared/util.pri) -CONFIG += parallel_test QT += core-private gui-private qml-private quick-private testlib OTHER_FILES += \ @@ -27,4 +26,3 @@ OTHER_FILES += \ data/ItemEffect.qml \ data/RectangleEffect.qml \ data/TextureMirroring.qml -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicklistview/qquicklistview.pro b/tests/auto/quick/qquicklistview/qquicklistview.pro index c9b634b9e8..a95b6fdf33 100644 --- a/tests/auto/quick/qquicklistview/qquicklistview.pro +++ b/tests/auto/quick/qquicklistview/qquicklistview.pro @@ -18,5 +18,4 @@ include (../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickloader/qquickloader.pro b/tests/auto/quick/qquickloader/qquickloader.pro index 567917877c..32350388e8 100644 --- a/tests/auto/quick/qquickloader/qquickloader.pro +++ b/tests/auto/quick/qquickloader/qquickloader.pro @@ -13,4 +13,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index f4fab1d79f..b9d058ab80 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -111,6 +111,8 @@ private slots: void asynchronous(); void asynchronous_clear(); void simultaneousSyncAsync(); + void asyncToSync1(); + void asyncToSync2(); void loadedSignal(); void parented(); @@ -1035,6 +1037,73 @@ void tst_QQuickLoader::simultaneousSyncAsync() delete root; } +void tst_QQuickLoader::asyncToSync1() +{ + QQmlEngine engine; + PeriodicIncubationController *controller = new PeriodicIncubationController; + QQmlIncubationController *previous = engine.incubationController(); + engine.setIncubationController(controller); + delete previous; + + QQmlComponent component(&engine, testFileUrl("asynchronous.qml")); + QQuickItem *root = qobject_cast<QQuickItem*>(component.create()); + QVERIFY(root); + + QQuickLoader *loader = root->findChild<QQuickLoader*>("loader"); + QVERIFY(loader); + + QVERIFY(!loader->item()); + root->setProperty("comp", "BigComponent.qml"); + QMetaObject::invokeMethod(root, "loadComponent"); + QVERIFY(!loader->item()); + + controller->start(); + QCOMPARE(loader->status(), QQuickLoader::Loading); + QCOMPARE(engine.incubationController()->incubatingObjectCount(), 0); + + // force completion before component created + loader->setAsynchronous(false); + QVERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(loader->status(), QQuickLoader::Ready); + QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1); + + delete root; +} + +void tst_QQuickLoader::asyncToSync2() +{ + PeriodicIncubationController *controller = new PeriodicIncubationController; + QQmlIncubationController *previous = engine.incubationController(); + engine.setIncubationController(controller); + delete previous; + + QQmlComponent component(&engine, testFileUrl("asynchronous.qml")); + QQuickItem *root = qobject_cast<QQuickItem*>(component.create()); + QVERIFY(root); + + QQuickLoader *loader = root->findChild<QQuickLoader*>("loader"); + QVERIFY(loader); + + QVERIFY(!loader->item()); + root->setProperty("comp", "BigComponent.qml"); + QMetaObject::invokeMethod(root, "loadComponent"); + QVERIFY(!loader->item()); + + controller->start(); + QCOMPARE(loader->status(), QQuickLoader::Loading); + QTRY_COMPARE(engine.incubationController()->incubatingObjectCount(), 1); + + // force completion after component created but before incubation complete + loader->setAsynchronous(false); + QVERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(loader->status(), QQuickLoader::Ready); + QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1); + + delete root; +} + void tst_QQuickLoader::loadedSignal() { PeriodicIncubationController *controller = new PeriodicIncubationController; diff --git a/tests/auto/quick/qquickmousearea/qquickmousearea.pro b/tests/auto/quick/qquickmousearea/qquickmousearea.pro index dd7b434898..15a080aa3e 100644 --- a/tests/auto/quick/qquickmousearea/qquickmousearea.pro +++ b/tests/auto/quick/qquickmousearea/qquickmousearea.pro @@ -11,4 +11,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro b/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro index 5724a7179e..e5a2bae840 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro +++ b/tests/auto/quick/qquickmultipointtoucharea/qquickmultipointtoucharea.pro @@ -1,6 +1,5 @@ TARGET = tst_qquickmultipointtoucharea CONFIG += testcase -CONFIG += parallel_test macx:CONFIG -= app_bundle SOURCES += tst_qquickmultipointtoucharea.cpp @@ -11,4 +10,3 @@ include(../../shared/util.pri) include(../shared/util.pri) QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickopenglinfo/qquickopenglinfo.pro b/tests/auto/quick/qquickopenglinfo/qquickopenglinfo.pro index 8489dfffd2..650ec04029 100644 --- a/tests/auto/quick/qquickopenglinfo/qquickopenglinfo.pro +++ b/tests/auto/quick/qquickopenglinfo/qquickopenglinfo.pro @@ -7,7 +7,6 @@ include(../../shared/util.pri) osx:CONFIG -= app_bundle -CONFIG += parallel_test QT += quick testlib OTHER_FILES += \ diff --git a/tests/auto/quick/qquickpainteditem/qquickpainteditem.pro b/tests/auto/quick/qquickpainteditem/qquickpainteditem.pro index 381167cd09..a188001bd4 100644 --- a/tests/auto/quick/qquickpainteditem/qquickpainteditem.pro +++ b/tests/auto/quick/qquickpainteditem/qquickpainteditem.pro @@ -4,7 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qquickpainteditem.cpp -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickpath/qquickpath.pro b/tests/auto/quick/qquickpath/qquickpath.pro index 4898f28c14..492f82f53d 100644 --- a/tests/auto/quick/qquickpath/qquickpath.pro +++ b/tests/auto/quick/qquickpath/qquickpath.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickpathview/qquickpathview.pro b/tests/auto/quick/qquickpathview/qquickpathview.pro index e6cf9a488f..90c1eb0c67 100644 --- a/tests/auto/quick/qquickpathview/qquickpathview.pro +++ b/tests/auto/quick/qquickpathview/qquickpathview.pro @@ -11,4 +11,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib qtHaveModule(widgets): QT += widgets -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickpincharea/qquickpincharea.pro b/tests/auto/quick/qquickpincharea/qquickpincharea.pro index fa14afa261..d37b37309d 100644 --- a/tests/auto/quick/qquickpincharea/qquickpincharea.pro +++ b/tests/auto/quick/qquickpincharea/qquickpincharea.pro @@ -1,5 +1,4 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qquickpincharea macx:CONFIG -= app_bundle @@ -11,4 +10,3 @@ include (../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro b/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro index 62678dc660..185eb2c213 100644 --- a/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro +++ b/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro @@ -15,4 +15,3 @@ TESTDATA = data/* # LIBS += -lgcov QT += core-private gui-private qml-private quick-private network testlib concurrent -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickpositioners/qquickpositioners.pro b/tests/auto/quick/qquickpositioners/qquickpositioners.pro index f6a046e622..6e85ba9db8 100644 --- a/tests/auto/quick/qquickpositioners/qquickpositioners.pro +++ b/tests/auto/quick/qquickpositioners/qquickpositioners.pro @@ -10,4 +10,3 @@ macx:CONFIG -= app_bundle TESTDATA = data/* QT += testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickrectangle/qquickrectangle.pro b/tests/auto/quick/qquickrectangle/qquickrectangle.pro index e881926c80..daefb5fe75 100644 --- a/tests/auto/quick/qquickrectangle/qquickrectangle.pro +++ b/tests/auto/quick/qquickrectangle/qquickrectangle.pro @@ -10,4 +10,3 @@ include (../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickrepeater/qquickrepeater.pro b/tests/auto/quick/qquickrepeater/qquickrepeater.pro index a27c34c84b..5554342943 100644 --- a/tests/auto/quick/qquickrepeater/qquickrepeater.pro +++ b/tests/auto/quick/qquickrepeater/qquickrepeater.pro @@ -9,6 +9,4 @@ include (../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickscreen/qquickscreen.pro b/tests/auto/quick/qquickscreen/qquickscreen.pro index fa64556a69..145ae0f04e 100644 --- a/tests/auto/quick/qquickscreen/qquickscreen.pro +++ b/tests/auto/quick/qquickscreen/qquickscreen.pro @@ -6,6 +6,4 @@ include (../../shared/util.pri) macx:CONFIG -= app_bundle -CONFIG += parallel_test QT += core-private gui-private qml-private testlib quick-private -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro b/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro index 0af54f83f6..437a548a90 100644 --- a/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro +++ b/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro @@ -5,6 +5,4 @@ SOURCES += tst_qquickshadereffect.cpp include (../../shared/util.pri) macx:CONFIG -= app_bundle -CONFIG += parallel_test QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickshortcut/qquickshortcut.pro b/tests/auto/quick/qquickshortcut/qquickshortcut.pro index 917a7605e6..d780d9061a 100644 --- a/tests/auto/quick/qquickshortcut/qquickshortcut.pro +++ b/tests/auto/quick/qquickshortcut/qquickshortcut.pro @@ -8,4 +8,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core gui qml quick testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicksmoothedanimation/qquicksmoothedanimation.pro b/tests/auto/quick/qquicksmoothedanimation/qquicksmoothedanimation.pro index 4694172ac4..3d71ef4c62 100644 --- a/tests/auto/quick/qquicksmoothedanimation/qquicksmoothedanimation.pro +++ b/tests/auto/quick/qquicksmoothedanimation/qquicksmoothedanimation.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickspringanimation/qquickspringanimation.pro b/tests/auto/quick/qquickspringanimation/qquickspringanimation.pro index 2f0395d3ea..bf8ddfe8ae 100644 --- a/tests/auto/quick/qquickspringanimation/qquickspringanimation.pro +++ b/tests/auto/quick/qquickspringanimation/qquickspringanimation.pro @@ -8,7 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro b/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro index ee5cb5d25b..a61396bd0e 100644 --- a/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro +++ b/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro @@ -8,7 +8,4 @@ macx:CONFIG -= app_bundle TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickstates/qquickstates.pro b/tests/auto/quick/qquickstates/qquickstates.pro index 1b638dfa67..85fdebff96 100644 --- a/tests/auto/quick/qquickstates/qquickstates.pro +++ b/tests/auto/quick/qquickstates/qquickstates.pro @@ -8,6 +8,4 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickstyledtext/qquickstyledtext.pro b/tests/auto/quick/qquickstyledtext/qquickstyledtext.pro index e9a8ffe8ee..def2a27bf7 100644 --- a/tests/auto/quick/qquickstyledtext/qquickstyledtext.pro +++ b/tests/auto/quick/qquickstyledtext/qquickstyledtext.pro @@ -4,6 +4,4 @@ macx:CONFIG -= app_bundle SOURCES += tst_qquickstyledtext.cpp -CONFIG += parallel_test QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicksystempalette/qquicksystempalette.pro b/tests/auto/quick/qquicksystempalette/qquicksystempalette.pro index 48fd7e8e9a..9aa57b146b 100644 --- a/tests/auto/quick/qquicksystempalette/qquicksystempalette.pro +++ b/tests/auto/quick/qquicksystempalette/qquicksystempalette.pro @@ -4,7 +4,5 @@ macx:CONFIG -= app_bundle SOURCES += tst_qquicksystempalette.cpp -CONFIG += parallel_test QT += core-private gui-private qml-private quick-private testlib qtHaveModule(widgets): QT += widgets -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicktext/qquicktext.pro b/tests/auto/quick/qquicktext/qquicktext.pro index ee0a9be776..4f4b77ed7b 100644 --- a/tests/auto/quick/qquicktext/qquicktext.pro +++ b/tests/auto/quick/qquicktext/qquicktext.pro @@ -13,4 +13,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private network testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicktextdocument/qquicktextdocument.pro b/tests/auto/quick/qquicktextdocument/qquicktextdocument.pro index e6bfdbd099..b5866e9e89 100644 --- a/tests/auto/quick/qquicktextdocument/qquicktextdocument.pro +++ b/tests/auto/quick/qquicktextdocument/qquicktextdocument.pro @@ -8,8 +8,5 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicktextedit/qquicktextedit.pro b/tests/auto/quick/qquicktextedit/qquicktextedit.pro index 2a6d753536..a61f46cb49 100644 --- a/tests/auto/quick/qquicktextedit/qquicktextedit.pro +++ b/tests/auto/quick/qquicktextedit/qquicktextedit.pro @@ -13,4 +13,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private network-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicktextinput/qquicktextinput.pro b/tests/auto/quick/qquicktextinput/qquicktextinput.pro index c14b09c545..205ee4f672 100644 --- a/tests/auto/quick/qquicktextinput/qquicktextinput.pro +++ b/tests/auto/quick/qquicktextinput/qquicktextinput.pro @@ -13,4 +13,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicktextmetrics/qquicktextmetrics.pro b/tests/auto/quick/qquicktextmetrics/qquicktextmetrics.pro index 6ef68db8e2..a5c088d454 100644 --- a/tests/auto/quick/qquicktextmetrics/qquicktextmetrics.pro +++ b/tests/auto/quick/qquicktextmetrics/qquicktextmetrics.pro @@ -4,7 +4,4 @@ osx:CONFIG -= app_bundle SOURCES += tst_qquicktextmetrics.cpp -CONFIG += parallel_test - QT += core gui qml quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquicktimeline/qquicktimeline.pro b/tests/auto/quick/qquicktimeline/qquicktimeline.pro index 3fafc33505..489fc7e081 100644 --- a/tests/auto/quick/qquicktimeline/qquicktimeline.pro +++ b/tests/auto/quick/qquicktimeline/qquicktimeline.pro @@ -1,9 +1,7 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qquicktimeline macx:CONFIG -= app_bundle SOURCES += tst_qquicktimeline.cpp QT += core-private gui-private qml quick qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickview/qquickview.pro b/tests/auto/quick/qquickview/qquickview.pro index 3e9c39e2ce..1302908bf7 100644 --- a/tests/auto/quick/qquickview/qquickview.pro +++ b/tests/auto/quick/qquickview/qquickview.pro @@ -1,5 +1,4 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qquickview macx:CONFIG -= app_bundle @@ -10,4 +9,3 @@ include (../../shared/util.pri) TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickvisualdatamodel/qquickvisualdatamodel.pro b/tests/auto/quick/qquickvisualdatamodel/qquickvisualdatamodel.pro index d9aff688ab..9222e39477 100644 --- a/tests/auto/quick/qquickvisualdatamodel/qquickvisualdatamodel.pro +++ b/tests/auto/quick/qquickvisualdatamodel/qquickvisualdatamodel.pro @@ -11,4 +11,3 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib qtHaveModule(widgets): QT += widgets -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp index d578a0900c..a1d8779555 100644 --- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp +++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp @@ -102,15 +102,20 @@ public: }; SingleRoleModel(const QStringList &list = QStringList(), const QByteArray &role = "name", QObject *parent = 0) - : QAbstractItemModel(parent) { - QHash<int, QByteArray> roles; - roles.insert(Qt::DisplayRole , role); - setRoleNames(roles); + : QAbstractItemModel(parent), m_role(role) + { foreach (const QString &string, list) trunk.children.append(Node(string)); } ~SingleRoleModel() {} + QHash<int,QByteArray> roleNames() const + { + QHash<int,QByteArray> roles; + roles.insert(Qt::DisplayRole, m_role); + return roles; + } + Branch *branchForIndex(const QModelIndex &index) const { return index.isValid() ? static_cast<Branch *>(index.internalPointer())->children.at(index.row()).branch @@ -235,6 +240,7 @@ public slots: } private: + const QByteArray m_role; Branch trunk; }; diff --git a/tests/auto/quick/qquickwindow/qquickwindow.pro b/tests/auto/quick/qquickwindow/qquickwindow.pro index e95b7dbb10..f0d287f30f 100644 --- a/tests/auto/quick/qquickwindow/qquickwindow.pro +++ b/tests/auto/quick/qquickwindow/qquickwindow.pro @@ -17,5 +17,3 @@ OTHER_FILES += \ data/Headless.qml \ data/showHideAnimate.qml \ data/windoworder.qml - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index f53ade9541..b16b7b3686 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -397,7 +397,7 @@ void tst_qquickwindow::openglContextCreatedSignal() QVERIFY(spy.size() > 0); QVariant ctx = spy.at(0).at(0); - QCOMPARE(qVariantValue<QOpenGLContext *>(ctx), window.openglContext()); + QCOMPARE(qvariant_cast<QOpenGLContext *>(ctx), window.openglContext()); } void tst_qquickwindow::aboutToStopSignal() diff --git a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro b/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro index 574481c456..642345a4bb 100644 --- a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro +++ b/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro @@ -8,10 +8,7 @@ include (../../shared/util.pri) TESTDATA = data/* -CONFIG += parallel_test - QT += core-private gui-private qml-private network testlib xmlpatterns -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 OTHER_FILES += \ data/groups.qml diff --git a/tests/auto/quick/rendernode/rendernode.pro b/tests/auto/quick/rendernode/rendernode.pro index bedcefde86..e4397713d9 100644 --- a/tests/auto/quick/rendernode/rendernode.pro +++ b/tests/auto/quick/rendernode/rendernode.pro @@ -8,7 +8,6 @@ TESTDATA = data/* include(../../shared/util.pri) -CONFIG += parallel_test QT += core-private gui-private qml-private quick-private testlib OTHER_FILES += \ @@ -16,4 +15,3 @@ OTHER_FILES += \ data/MessUpState.qml \ data/matrix.qml -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/scenegraph/scenegraph.pro b/tests/auto/quick/scenegraph/scenegraph.pro index 0ad13a086f..320228bd08 100644 --- a/tests/auto/quick/scenegraph/scenegraph.pro +++ b/tests/auto/quick/scenegraph/scenegraph.pro @@ -8,7 +8,6 @@ macx:CONFIG -= app_bundle QT += core-private gui-private qml-private quick-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 OTHER_FILES += \ data/render_OutOfFloatRange.qml \ diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp index 1330cbccc9..9121314420 100644 --- a/tests/auto/quick/shared/viewtestutil.cpp +++ b/tests/auto/quick/shared/viewtestutil.cpp @@ -148,10 +148,6 @@ QList<int> QQuickViewTestUtil::adjustIndexesForRemoveDisplaced(const QList<int> QQuickViewTestUtil::QaimModel::QaimModel(QObject *parent) : QAbstractListModel(parent) { - QHash<int, QByteArray> roles; - roles[Name] = "name"; - roles[Number] = "number"; - setRoleNames(roles); } int QQuickViewTestUtil::QaimModel::rowCount(const QModelIndex &parent) const @@ -160,6 +156,14 @@ int QQuickViewTestUtil::QaimModel::rowCount(const QModelIndex &parent) const return list.count(); } +QHash<int,QByteArray> QQuickViewTestUtil::QaimModel::roleNames() const +{ + QHash<int,QByteArray> roles = QAbstractListModel::roleNames(); + roles.insert(Name, "name"); + roles.insert(Number, "number"); + return roles; +} + QVariant QQuickViewTestUtil::QaimModel::data(const QModelIndex &index, int role) const { QVariant rv; diff --git a/tests/auto/quick/shared/viewtestutil.h b/tests/auto/quick/shared/viewtestutil.h index 1643eca979..1de2f54d8a 100644 --- a/tests/auto/quick/shared/viewtestutil.h +++ b/tests/auto/quick/shared/viewtestutil.h @@ -80,6 +80,7 @@ namespace QQuickViewTestUtil int rowCount(const QModelIndex &parent=QModelIndex()) const; QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const; + QHash<int,QByteArray> roleNames() const; int count() const; QString name(int index) const; diff --git a/tests/auto/quick/touchmouse/touchmouse.pro b/tests/auto/quick/touchmouse/touchmouse.pro index 7d23dfc0ae..0df9bc53d3 100644 --- a/tests/auto/quick/touchmouse/touchmouse.pro +++ b/tests/auto/quick/touchmouse/touchmouse.pro @@ -14,4 +14,3 @@ TESTDATA = data/* # OTHER_FILES += data/foo.qml -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro b/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro index 069270da3c..aeeff8b479 100644 --- a/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro +++ b/tests/auto/quickwidgets/qquickwidget/qquickwidget.pro @@ -16,4 +16,3 @@ OTHER_FILES += \ rectangle.qml \ resizemodeitem.qml -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/toolsupport/toolsupport.pro b/tests/auto/toolsupport/toolsupport.pro index 40dd7c5200..89de3086c3 100644 --- a/tests/auto/toolsupport/toolsupport.pro +++ b/tests/auto/toolsupport/toolsupport.pro @@ -1,4 +1,4 @@ -CONFIG += testcase parallel_test +CONFIG += testcase TARGET = tst_toolsupport QT = testlib core-private qml-private SOURCES = $$PWD/tst_toolsupport.cpp diff --git a/tests/benchmarks/particles/affectors/affectors.pro b/tests/benchmarks/particles/affectors/affectors.pro index 112c4ea3ec..88d260591e 100644 --- a/tests/benchmarks/particles/affectors/affectors.pro +++ b/tests/benchmarks/particles/affectors/affectors.pro @@ -8,4 +8,3 @@ testDataFiles.path = . DEPLOYMENT += testDataFiles QT += quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/particles/emission/emission.pro b/tests/benchmarks/particles/emission/emission.pro index 0ebd75b738..3a49405730 100644 --- a/tests/benchmarks/particles/emission/emission.pro +++ b/tests/benchmarks/particles/emission/emission.pro @@ -8,4 +8,3 @@ testDataFiles.path = . DEPLOYMENT += testDataFiles QT += quickparticles-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/animation/animation.pro b/tests/benchmarks/qml/animation/animation.pro index e089884a7e..6369ecddd1 100644 --- a/tests/benchmarks/qml/animation/animation.pro +++ b/tests/benchmarks/qml/animation/animation.pro @@ -7,4 +7,3 @@ macx:CONFIG -= app_bundle SOURCES += tst_animation.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/binding/binding.pro b/tests/benchmarks/qml/binding/binding.pro index fc0f731da6..776c8390a3 100644 --- a/tests/benchmarks/qml/binding/binding.pro +++ b/tests/benchmarks/qml/binding/binding.pro @@ -9,4 +9,3 @@ HEADERS += testtypes.h # Define SRCDIR equal to test's source directory DEFINES += SRCDIR=\\\"$$PWD\\\" -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/compilation/compilation.pro b/tests/benchmarks/qml/compilation/compilation.pro index a55864f696..31abb23e69 100644 --- a/tests/benchmarks/qml/compilation/compilation.pro +++ b/tests/benchmarks/qml/compilation/compilation.pro @@ -9,4 +9,3 @@ CONFIG += release SOURCES += tst_compilation.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/creation/creation.pro b/tests/benchmarks/qml/creation/creation.pro index 0cfac64d5f..ef7a8cf2ce 100644 --- a/tests/benchmarks/qml/creation/creation.pro +++ b/tests/benchmarks/qml/creation/creation.pro @@ -7,4 +7,3 @@ macx:CONFIG -= app_bundle SOURCES += tst_creation.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/holistic/holistic.pro b/tests/benchmarks/qml/holistic/holistic.pro index 8fd87c88bd..82f2ef6e4e 100644 --- a/tests/benchmarks/qml/holistic/holistic.pro +++ b/tests/benchmarks/qml/holistic/holistic.pro @@ -11,4 +11,3 @@ SOURCES += tst_holistic.cpp \ HEADERS += testtypes.h DEFINES += SRCDIR=\\\"$$PWD\\\" -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/javascript/javascript.pro b/tests/benchmarks/qml/javascript/javascript.pro index b8f23f47d5..281bbd0069 100644 --- a/tests/benchmarks/qml/javascript/javascript.pro +++ b/tests/benchmarks/qml/javascript/javascript.pro @@ -9,4 +9,3 @@ HEADERS += testtypes.h # Define SRCDIR equal to test's source directory DEFINES += SRCDIR=\\\"$$PWD\\\" -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/js/qjsengine/qjsengine.pro b/tests/benchmarks/qml/js/qjsengine/qjsengine.pro index f736e59222..f8f2874a63 100644 --- a/tests/benchmarks/qml/js/qjsengine/qjsengine.pro +++ b/tests/benchmarks/qml/js/qjsengine/qjsengine.pro @@ -5,4 +5,3 @@ TARGET = tst_bench_qjsengine SOURCES += tst_qjsengine.cpp QT += qml testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/js/qjsvalue/qjsvalue.pro b/tests/benchmarks/qml/js/qjsvalue/qjsvalue.pro index 7b8363b6c4..772aa5da8c 100644 --- a/tests/benchmarks/qml/js/qjsvalue/qjsvalue.pro +++ b/tests/benchmarks/qml/js/qjsvalue/qjsvalue.pro @@ -5,4 +5,3 @@ TARGET = tst_bench_qjsvalue SOURCES += tst_qjsvalue.cpp QT += qml testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/js/qjsvalueiterator/qjsvalueiterator.pro b/tests/benchmarks/qml/js/qjsvalueiterator/qjsvalueiterator.pro index 34ed9caa15..7601789ca9 100644 --- a/tests/benchmarks/qml/js/qjsvalueiterator/qjsvalueiterator.pro +++ b/tests/benchmarks/qml/js/qjsvalueiterator/qjsvalueiterator.pro @@ -5,4 +5,3 @@ TARGET = tst_bench_qjsvalueiterator SOURCES += tst_qjsvalueiterator.cpp QT = core qml testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/painting/painting.pro b/tests/benchmarks/qml/painting/painting.pro index bde891e12d..7e97915f43 100644 --- a/tests/benchmarks/qml/painting/painting.pro +++ b/tests/benchmarks/qml/painting/painting.pro @@ -5,4 +5,3 @@ CONFIG += console macx:CONFIG -= app_bundle SOURCES += paintbenchmark.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/pointers/pointers.pro b/tests/benchmarks/qml/pointers/pointers.pro index ccf85d659a..a2c9a0828f 100644 --- a/tests/benchmarks/qml/pointers/pointers.pro +++ b/tests/benchmarks/qml/pointers/pointers.pro @@ -5,5 +5,3 @@ TARGET = tst_pointers macx:CONFIG -= app_bundle SOURCES += tst_pointers.cpp - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/pointers/tst_pointers.cpp b/tests/benchmarks/qml/pointers/tst_pointers.cpp index 8b981f4532..1fec42ca42 100644 --- a/tests/benchmarks/qml/pointers/tst_pointers.cpp +++ b/tests/benchmarks/qml/pointers/tst_pointers.cpp @@ -60,7 +60,7 @@ void tst_pointers::weakPointer() { QObject *obj = new QObject; QBENCHMARK { - QWeakPointer<QObject> guardedObject; + QPointer<QObject> guardedObject; guardedObject = obj; } } diff --git a/tests/benchmarks/qml/qmltime/qmltime.pro b/tests/benchmarks/qml/qmltime/qmltime.pro index 4e3e9471a4..57966be7a2 100644 --- a/tests/benchmarks/qml/qmltime/qmltime.pro +++ b/tests/benchmarks/qml/qmltime/qmltime.pro @@ -6,4 +6,3 @@ macx:CONFIG -= app_bundle SOURCES += qmltime.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/qqmlcomponent/qqmlcomponent.pro b/tests/benchmarks/qml/qqmlcomponent/qqmlcomponent.pro index 12a53f5e20..ba41f5a95b 100644 --- a/tests/benchmarks/qml/qqmlcomponent/qqmlcomponent.pro +++ b/tests/benchmarks/qml/qqmlcomponent/qqmlcomponent.pro @@ -9,4 +9,3 @@ HEADERS += testtypes.h # Define SRCDIR equal to test's source directory DEFINES += SRCDIR=\\\"$$PWD\\\" -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/qqmldebugtrace/qqmldebugtrace.pro b/tests/benchmarks/qml/qqmldebugtrace/qqmldebugtrace.pro index 4cf6bbe4bc..ebf0ae074f 100644 --- a/tests/benchmarks/qml/qqmldebugtrace/qqmldebugtrace.pro +++ b/tests/benchmarks/qml/qqmldebugtrace/qqmldebugtrace.pro @@ -6,4 +6,3 @@ macx:CONFIG -= app_bundle SOURCES += tst_qqmldebugtrace.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/qqmlimage/qqmlimage.pro b/tests/benchmarks/qml/qqmlimage/qqmlimage.pro index 6a94052898..21d3efdd1f 100644 --- a/tests/benchmarks/qml/qqmlimage/qqmlimage.pro +++ b/tests/benchmarks/qml/qqmlimage/qqmlimage.pro @@ -9,4 +9,3 @@ SOURCES += tst_qqmlimage.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/qqmlmetaproperty/qqmlmetaproperty.pro b/tests/benchmarks/qml/qqmlmetaproperty/qqmlmetaproperty.pro index ce66e1e51f..b80b88f4bc 100644 --- a/tests/benchmarks/qml/qqmlmetaproperty/qqmlmetaproperty.pro +++ b/tests/benchmarks/qml/qqmlmetaproperty/qqmlmetaproperty.pro @@ -8,4 +8,3 @@ SOURCES += tst_qqmlmetaproperty.cpp # Define SRCDIR equal to test's source directory DEFINES += SRCDIR=\\\"$$PWD\\\" -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/qml/qquickwindow/qquickwindow.pro b/tests/benchmarks/qml/qquickwindow/qquickwindow.pro index 0676405e23..50f956f220 100644 --- a/tests/benchmarks/qml/qquickwindow/qquickwindow.pro +++ b/tests/benchmarks/qml/qquickwindow/qquickwindow.pro @@ -8,4 +8,3 @@ testDataFiles.path = . DEPLOYMENT += testDataFiles QT += core-private gui-private qml-private quick-private opengl-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
\ No newline at end of file diff --git a/tests/benchmarks/qml/typeimports/typeimports.pro b/tests/benchmarks/qml/typeimports/typeimports.pro index b8db7bd134..dc58e4044b 100644 --- a/tests/benchmarks/qml/typeimports/typeimports.pro +++ b/tests/benchmarks/qml/typeimports/typeimports.pro @@ -7,4 +7,3 @@ macx:CONFIG -= app_bundle SOURCES += tst_typeimports.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/script/qjsvalue/qjsvalue.pro b/tests/benchmarks/script/qjsvalue/qjsvalue.pro index b0134b085a..03b877ae9d 100644 --- a/tests/benchmarks/script/qjsvalue/qjsvalue.pro +++ b/tests/benchmarks/script/qjsvalue/qjsvalue.pro @@ -8,4 +8,3 @@ CONFIG += release SOURCES += tst_qjsvalue.cpp QT += core-private qml-private testlib -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tools/qmleasing/splineeditor.cpp b/tools/qmleasing/splineeditor.cpp index 9e35af6189..2ae4d11309 100644 --- a/tools/qmleasing/splineeditor.cpp +++ b/tools/qmleasing/splineeditor.cpp @@ -228,6 +228,7 @@ void SplineEditor::mouseReleaseEvent(QMouseEvent *e) } } +#ifndef QT_NO_CONTEXTMENU void SplineEditor::contextMenuEvent(QContextMenuEvent *e) { int index = findControlPoint(e->pos()); @@ -247,6 +248,7 @@ void SplineEditor::contextMenuEvent(QContextMenuEvent *e) addPoint(e->pos()); } } +#endif // QT_NO_CONTEXTMENU void SplineEditor::invalidate() { diff --git a/tools/qmleasing/splineeditor.h b/tools/qmleasing/splineeditor.h index 595580bba2..4b9da14a7a 100644 --- a/tools/qmleasing/splineeditor.h +++ b/tools/qmleasing/splineeditor.h @@ -84,7 +84,9 @@ protected: void mousePressEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); +#ifndef QT_NO_CONTEXTMENU void contextMenuEvent(QContextMenuEvent *); +#endif // QT_NO_CONTEXTMENU void invalidate(); void invalidateSmoothList(); diff --git a/tools/qmlmin/main.cpp b/tools/qmlmin/main.cpp index a3f2b92bde..82fdb92801 100644 --- a/tools/qmlmin/main.cpp +++ b/tools/qmlmin/main.cpp @@ -590,7 +590,7 @@ int runQmlmin(int argc, char *argv[]) } } else if (arg.startsWith(QLatin1String("-w"))) { bool ok; - width = arg.mid(2).toInt(&ok); + width = arg.midRef(2).toInt(&ok); if (!ok) { std::cerr << "qmlmin: argument to '-w' is invalid" << std::endl; diff --git a/tools/qmlprofiler/qmlprofiler.pro b/tools/qmlprofiler/qmlprofiler.pro index 4fa36f5127..a65e25c657 100644 --- a/tools/qmlprofiler/qmlprofiler.pro +++ b/tools/qmlprofiler/qmlprofiler.pro @@ -1,22 +1,17 @@ -QT = qml qml-private network core-private +QT = qml-private network core qmldebug-private CONFIG += no_import_scan SOURCES += main.cpp \ qmlprofilerapplication.cpp \ commandlistener.cpp \ - qqmldebugclient.cpp \ qmlprofilerdata.cpp \ - qmlprofilerclient.cpp \ - qpacketprotocol.cpp + qmlprofilerclient.cpp HEADERS += \ qmlprofilerapplication.h \ commandlistener.h \ constants.h \ qmlprofilerdata.h \ - qmlprofilerclient.h \ - qmlprofilereventlocation.h \ - qqmldebugclient.h \ - qpacketprotocol.h + qmlprofilerclient.h load(qt_tool) diff --git a/tools/qmlprofiler/qmlprofilerapplication.cpp b/tools/qmlprofiler/qmlprofilerapplication.cpp index 347e7d3b55..455faeb1c0 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.cpp +++ b/tools/qmlprofiler/qmlprofilerapplication.cpp @@ -41,6 +41,7 @@ #include <QtCore/QFileInfo> #include <QtCore/QDebug> #include <QtCore/QCommandLineParser> +#include <QtCore/QTemporaryFile> static const char commandTextC[] = "The following commands are available:\n" @@ -70,60 +71,35 @@ static const char *features[] = { "creating", "binding", "handlingsignal", - "inputevents" + "inputevents", + "debugmessages" }; +Q_STATIC_ASSERT(sizeof(features) == + QQmlProfilerDefinitions::MaximumProfileFeature * sizeof(char *)); + QmlProfilerApplication::QmlProfilerApplication(int &argc, char **argv) : QCoreApplication(argc, argv), m_runMode(LaunchMode), m_process(0), m_hostName(QLatin1String("127.0.0.1")), - m_port(3768), + m_port(0), m_pendingRequest(REQUEST_NONE), m_verbose(false), m_recording(true), m_interactive(false), - m_qmlProfilerClient(&m_connection), - m_v8profilerClient(&m_connection), - m_connectionAttempts(0), - m_qmlDataReady(false), - m_v8DataReady(false) + m_qmlProfilerClient(&m_connection, &m_profilerData), + m_connectionAttempts(0) { m_connectTimer.setInterval(1000); connect(&m_connectTimer, SIGNAL(timeout()), this, SLOT(tryToConnect())); connect(&m_connection, SIGNAL(connected()), this, SLOT(connected())); - connect(&m_connection, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(connectionStateChanged(QAbstractSocket::SocketState))); - connect(&m_connection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectionError(QAbstractSocket::SocketError))); - - connect(&m_qmlProfilerClient, SIGNAL(enabledChanged()), this, SLOT(traceClientEnabled())); - connect(&m_qmlProfilerClient, SIGNAL(range(QQmlProfilerDefinitions::RangeType,QQmlProfilerDefinitions::BindingType,qint64,qint64,QStringList,QmlEventLocation)), - &m_profilerData, SLOT(addQmlEvent(QQmlProfilerDefinitions::RangeType,QQmlProfilerDefinitions::BindingType,qint64,qint64,QStringList,QmlEventLocation))); - connect(&m_qmlProfilerClient, SIGNAL(traceFinished(qint64)), &m_profilerData, SLOT(setTraceEndTime(qint64))); - connect(&m_qmlProfilerClient, SIGNAL(traceStarted(qint64)), &m_profilerData, SLOT(setTraceStartTime(qint64))); - connect(&m_qmlProfilerClient, SIGNAL(traceStarted(qint64)), this, SLOT(notifyTraceStarted())); - connect(&m_qmlProfilerClient, SIGNAL(frame(qint64,int,int,int)), &m_profilerData, SLOT(addFrameEvent(qint64,int,int,int))); - connect(&m_qmlProfilerClient, SIGNAL(sceneGraphFrame(QQmlProfilerDefinitions::SceneGraphFrameType, - qint64,qint64,qint64,qint64,qint64,qint64)), - &m_profilerData, SLOT(addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGraphFrameType, - qint64,qint64,qint64,qint64,qint64,qint64))); - connect(&m_qmlProfilerClient, SIGNAL(pixmapCache(QQmlProfilerDefinitions::PixmapEventType,qint64, - QmlEventLocation,int,int,int)), - &m_profilerData, SLOT(addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType,qint64, - QmlEventLocation,int,int,int))); - connect(&m_qmlProfilerClient, SIGNAL(memoryAllocation(QQmlProfilerDefinitions::MemoryType,qint64, - qint64)), - &m_profilerData, SLOT(addMemoryEvent(QQmlProfilerDefinitions::MemoryType,qint64, - qint64))); - connect(&m_qmlProfilerClient, SIGNAL(inputEvent(QQmlProfilerDefinitions::EventType,qint64)), - &m_profilerData, SLOT(addInputEvent(QQmlProfilerDefinitions::EventType,qint64))); - - connect(&m_qmlProfilerClient, SIGNAL(complete()), this, SLOT(qmlComplete())); - - connect(&m_v8profilerClient, SIGNAL(enabledChanged()), this, SLOT(profilerClientEnabled())); - connect(&m_v8profilerClient, SIGNAL(range(int,QString,QString,int,double,double)), - &m_profilerData, SLOT(addV8Event(int,QString,QString,int,double,double))); - connect(&m_v8profilerClient, SIGNAL(complete()), this, SLOT(v8Complete())); + + connect(&m_qmlProfilerClient, SIGNAL(enabledChanged(bool)), + this, SLOT(traceClientEnabledChanged(bool))); + connect(&m_qmlProfilerClient, SIGNAL(recordingStarted()), this, SLOT(notifyTraceStarted())); + connect(&m_qmlProfilerClient, SIGNAL(error(QString)), this, SLOT(logError(QString))); connect(&m_profilerData, SIGNAL(error(QString)), this, SLOT(logError(QString))); connect(&m_profilerData, SIGNAL(dataReady()), this, SLOT(traceFinished())); @@ -228,6 +204,7 @@ void QmlProfilerApplication::parseArguments() if (parser.isSet(attach)) { m_hostName = parser.value(attach); m_runMode = AttachMode; + m_port = 3768; } if (parser.isSet(port)) { @@ -237,6 +214,10 @@ void QmlProfilerApplication::parseArguments() logError(tr("'%1' is not a valid port.").arg(parser.value(port))); parser.showHelp(1); } + } else if (m_port == 0) { + QTemporaryFile file; + if (file.open()) + m_socketFile = file.fileName(); } m_outputFile = parser.value(output); @@ -316,7 +297,6 @@ void QmlProfilerApplication::flush() if (m_recording) { m_pendingRequest = REQUEST_FLUSH; m_qmlProfilerClient.sendRecordingStatus(false); - m_v8profilerClient.sendRecordingStatus(false); } else { if (m_profilerData.save(m_interactiveOutputFile)) { m_profilerData.clear(); @@ -407,7 +387,6 @@ void QmlProfilerApplication::userCommand(const QString &command) if (cmd == Constants::CMD_RECORD || cmd == Constants::CMD_RECORD2) { m_pendingRequest = REQUEST_TOGGLE_RECORDING; m_qmlProfilerClient.sendRecordingStatus(!m_recording); - m_v8profilerClient.sendRecordingStatus(!m_recording); } else if (cmd == Constants::CMD_QUIT || cmd == Constants::CMD_QUIT2) { m_pendingRequest = REQUEST_QUIT; if (m_recording) { @@ -474,10 +453,15 @@ void QmlProfilerApplication::outputData() void QmlProfilerApplication::run() { if (m_runMode == LaunchMode) { + if (!m_socketFile.isEmpty()) { + logStatus(QString::fromLatin1("Listening on %1 ...").arg(m_socketFile)); + m_connection.startLocalServer(m_socketFile); + } m_process = new QProcess(this); QStringList arguments; - arguments << QString::fromLatin1("-qmljsdebugger=port:%1,block,services:CanvasFrameRate") - .arg(m_port); + arguments << QString::fromLatin1("-qmljsdebugger=%1:%2,block,services:CanvasFrameRate") + .arg(QLatin1String(m_socketFile.isEmpty() ? "port" : "file")) + .arg(m_socketFile.isEmpty() ? QString::number(m_port) : m_socketFile); arguments << m_programArguments; m_process->setProcessChannelMode(QProcess::MergedChannels); @@ -492,7 +476,6 @@ void QmlProfilerApplication::run() m_process->errorString())); exit(1); } - } m_connectTimer.start(); } @@ -503,15 +486,18 @@ void QmlProfilerApplication::tryToConnect() ++ m_connectionAttempts; if (!m_verbose && !(m_connectionAttempts % 5)) {// print every 5 seconds - if (!m_verbose) - logError(QString("Could not connect to %1:%2 for %3 seconds ...").arg( - m_hostName, QString::number(m_port), - QString::number(m_connectionAttempts))); + if (m_verbose) { + if (m_socketFile.isEmpty()) + logError(QString::fromLatin1("Could not connect to %1:%2 for %3 seconds ...") + .arg(m_hostName).arg(m_port).arg(m_connectionAttempts)); + else + logError(QString::fromLatin1("No connection received on %1 for %2 seconds ...") + .arg(m_socketFile).arg(m_connectionAttempts)); + } } - if (m_connection.state() == QAbstractSocket::UnconnectedState) { - logStatus(QString("Connecting to %1:%2 ...").arg(m_hostName, - QString::number(m_port))); + if (m_socketFile.isEmpty()) { + logStatus(QString::fromLatin1("Connecting to %1:%2 ...").arg(m_hostName).arg(m_port)); m_connection.connectToHost(m_hostName, m_port); } } @@ -519,22 +505,12 @@ void QmlProfilerApplication::tryToConnect() void QmlProfilerApplication::connected() { m_connectTimer.stop(); - prompt(tr("Connected to host:port %1:%2. Wait for profile data or type a command (type 'help' " - "to show list of commands).\nRecording Status: %3") - .arg(m_hostName).arg((m_port)).arg(m_recording ? tr("on") : tr("off"))); -} - -void QmlProfilerApplication::connectionStateChanged( - QAbstractSocket::SocketState state) -{ - if (m_verbose) - qDebug() << state; -} - -void QmlProfilerApplication::connectionError(QAbstractSocket::SocketError error) -{ - if (m_verbose) - qDebug() << error; + QString endpoint = m_socketFile.isEmpty() ? + QString::fromLatin1("%1:%2").arg(m_hostName).arg(m_port) : + m_socketFile; + prompt(tr("Connected to %1. Wait for profile data or type a command (type 'help' to show list " + "of commands).\nRecording Status: %2") + .arg(endpoint).arg(m_recording ? tr("on") : tr("off"))); } void QmlProfilerApplication::processHasOutput() @@ -562,35 +538,24 @@ void QmlProfilerApplication::processFinished() } if (!m_interactive) exit(exitCode); + else + m_qmlProfilerClient.clearPendingData(); } -void QmlProfilerApplication::traceClientEnabled() +void QmlProfilerApplication::traceClientEnabledChanged(bool enabled) { - logStatus("Trace client is attached."); - // blocked server is waiting for recording message from both clients - // once the last one is connected, both messages should be sent - m_qmlProfilerClient.sendRecordingStatus(m_recording); - m_v8profilerClient.sendRecordingStatus(m_recording); -} - -void QmlProfilerApplication::profilerClientEnabled() -{ - logStatus("Profiler client is attached."); - - // blocked server is waiting for recording message from both clients - // once the last one is connected, both messages should be sent - m_qmlProfilerClient.sendRecordingStatus(m_recording); - m_v8profilerClient.sendRecordingStatus(m_recording); + if (enabled) { + logStatus("Trace client is attached."); + // blocked server is waiting for recording message from both clients + // once the last one is connected, both messages should be sent + m_qmlProfilerClient.sendRecordingStatus(m_recording); + } } void QmlProfilerApplication::traceFinished() { m_recording = false; // only on "Complete" we know that the trace is really finished. - // after receiving both notifications, reset the flags - m_qmlDataReady = false; - m_v8DataReady = false; - if (m_pendingRequest == REQUEST_FLUSH) { flush(); } else if (m_pendingRequest == REQUEST_TOGGLE_RECORDING) { @@ -599,6 +564,8 @@ void QmlProfilerApplication::traceFinished() } else { prompt(tr("Application stopped recording."), false); } + + m_qmlProfilerClient.clearPendingData(); } void QmlProfilerApplication::prompt(const QString &line, bool ready) @@ -626,21 +593,3 @@ void QmlProfilerApplication::logStatus(const QString &status) QTextStream err(stderr); err << status << endl; } - -void QmlProfilerApplication::qmlComplete() -{ - m_qmlDataReady = true; - if (m_v8profilerClient.state() != QQmlDebugClient::Enabled || - m_v8DataReady) { - m_profilerData.complete(); - } -} - -void QmlProfilerApplication::v8Complete() -{ - m_v8DataReady = true; - if (m_qmlProfilerClient.state() != QQmlDebugClient::Enabled || - m_qmlDataReady) { - m_profilerData.complete(); - } -} diff --git a/tools/qmlprofiler/qmlprofilerapplication.h b/tools/qmlprofiler/qmlprofilerapplication.h index f1bf6c3e93..ef79a902e7 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.h +++ b/tools/qmlprofiler/qmlprofilerapplication.h @@ -34,13 +34,16 @@ #ifndef QMLPROFILERAPPLICATION_H #define QMLPROFILERAPPLICATION_H -#include <QtCore/QCoreApplication> -#include <QtCore/QProcess> -#include <QtCore/QTimer> - #include "qmlprofilerclient.h" #include "qmlprofilerdata.h" +#include <private/qqmldebugconnection_p.h> + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qprocess.h> +#include <QtCore/qtimer.h> +#include <QtNetwork/qabstractsocket.h> + enum PendingRequest { REQUEST_QUIT, REQUEST_FLUSH_FILE, @@ -73,22 +76,16 @@ private slots: void run(); void tryToConnect(); void connected(); - void connectionStateChanged(QAbstractSocket::SocketState state); - void connectionError(QAbstractSocket::SocketError error); void processHasOutput(); void processFinished(); - void traceClientEnabled(); - void profilerClientEnabled(); + void traceClientEnabledChanged(bool enabled); void traceFinished(); void prompt(const QString &line = QString(), bool ready = true); void logError(const QString &error); void logStatus(const QString &status); - void qmlComplete(); - void v8Complete(); - private: quint64 parseFeatures(const QStringList &featureList, const QString &values, bool exclude); bool checkOutputFile(PendingRequest pending); @@ -105,6 +102,7 @@ private: QStringList m_programArguments; QProcess *m_process; + QString m_socketFile; QString m_hostName; quint16 m_port; QString m_outputFile; @@ -117,13 +115,9 @@ private: QQmlDebugConnection m_connection; QmlProfilerClient m_qmlProfilerClient; - V8ProfilerClient m_v8profilerClient; QmlProfilerData m_profilerData; QTimer m_connectTimer; uint m_connectionAttempts; - - bool m_qmlDataReady; - bool m_v8DataReady; }; #endif // QMLPROFILERAPPLICATION_H diff --git a/tools/qmlprofiler/qmlprofilerclient.cpp b/tools/qmlprofiler/qmlprofilerclient.cpp index b4768e6934..4a0dfb8394 100644 --- a/tools/qmlprofiler/qmlprofilerclient.cpp +++ b/tools/qmlprofiler/qmlprofilerclient.cpp @@ -32,317 +32,174 @@ ****************************************************************************/ #include "qmlprofilerclient.h" +#include "qmlprofilerdata.h" + +#include <private/qqmlprofilerclient_p_p.h> #include <QtCore/QStack> #include <QtCore/QStringList> -#include <QtCore/QDataStream> #include <limits> -ProfilerClient::ProfilerClient(const QString &clientName, - QQmlDebugConnection *client) - : QQmlDebugClient(clientName, client), - m_enabled(false) -{ -} - -ProfilerClient::~ProfilerClient() -{ -} - -void ProfilerClient::clearData() -{ - emit cleared(); -} - -bool ProfilerClient::isEnabled() const -{ - return m_enabled; -} - -void ProfilerClient::stateChanged(State status) -{ - if ((m_enabled && status != Enabled) || - (!m_enabled && status == Enabled)) - emit enabledChanged(); - - m_enabled = status == Enabled; - -} - -class QmlProfilerClientPrivate +class QmlProfilerClientPrivate : public QQmlProfilerClientPrivate { + Q_DECLARE_PUBLIC(QmlProfilerClient) public: - QmlProfilerClientPrivate() - : inProgressRanges(0) , features(std::numeric_limits<quint64>::max()) - { - ::memset(rangeCount, 0, QQmlProfilerDefinitions::MaximumRangeType * sizeof(int)); - } + QmlProfilerClientPrivate(QQmlDebugConnection *connection, QmlProfilerData *data); + + QmlProfilerData *data; qint64 inProgressRanges; QStack<qint64> rangeStartTimes[QQmlProfilerDefinitions::MaximumRangeType]; QStack<QStringList> rangeDatas[QQmlProfilerDefinitions::MaximumRangeType]; - QStack<QmlEventLocation> rangeLocations[QQmlProfilerDefinitions::MaximumRangeType]; - QStack<QQmlProfilerDefinitions::BindingType> bindingTypes; + QStack<QQmlEventLocation> rangeLocations[QQmlProfilerDefinitions::MaximumRangeType]; int rangeCount[QQmlProfilerDefinitions::MaximumRangeType]; - quint64 features; + bool enabled; }; -QmlProfilerClient::QmlProfilerClient( - QQmlDebugConnection *client) - : ProfilerClient(QStringLiteral("CanvasFrameRate"), client), - d(new QmlProfilerClientPrivate) +QmlProfilerClientPrivate::QmlProfilerClientPrivate(QQmlDebugConnection *connection, + QmlProfilerData *data) : + QQmlProfilerClientPrivate(connection), data(data), inProgressRanges(0), enabled(false) { + ::memset(rangeCount, 0, QQmlProfilerDefinitions::MaximumRangeType * sizeof(int)); } -QmlProfilerClient::~QmlProfilerClient() +QmlProfilerClient::QmlProfilerClient(QQmlDebugConnection *connection, QmlProfilerData *data) : + QQmlProfilerClient(*(new QmlProfilerClientPrivate(connection, data))) { - delete d; } -void QmlProfilerClient::setFeatures(quint64 features) +void QmlProfilerClient::clearPendingData() { - d->features = features; + Q_D(QmlProfilerClient); + for (int i = 0; i < QQmlProfilerDefinitions::MaximumRangeType; ++i) { + d->rangeCount[i] = 0; + d->rangeDatas[i].clear(); + d->rangeLocations[i].clear(); + } } -void QmlProfilerClient::clearData() +void QmlProfilerClient::stateChanged(State state) { - ::memset(d->rangeCount, 0, QQmlProfilerDefinitions::MaximumRangeType * sizeof(int)); - d->bindingTypes.clear(); - ProfilerClient::clearData(); + Q_D(QmlProfilerClient); + if ((d->enabled && state != Enabled) || (!d->enabled && state == Enabled)) { + d->enabled = (state == Enabled); + emit enabledChanged(d->enabled); + } } -void QmlProfilerClient::sendRecordingStatus(bool record) +void QmlProfilerClient::traceStarted(qint64 time, int engineId) { - QByteArray ba; - QDataStream stream(&ba, QIODevice::WriteOnly); - stream.setVersion(QDataStream::Qt_4_7); - stream << record << -1 << d->features; - sendMessage(ba); + Q_UNUSED(engineId); + Q_D(QmlProfilerClient); + d->data->setTraceStartTime(time); + emit recordingStarted(); } -inline QQmlProfilerDefinitions::ProfileFeature featureFromRangeType( - QQmlProfilerDefinitions::RangeType range) +void QmlProfilerClient::traceFinished(qint64 time, int engineId) { - switch (range) { - case QQmlProfilerDefinitions::Painting: - return QQmlProfilerDefinitions::ProfilePainting; - case QQmlProfilerDefinitions::Compiling: - return QQmlProfilerDefinitions::ProfileCompiling; - case QQmlProfilerDefinitions::Creating: - return QQmlProfilerDefinitions::ProfileCreating; - case QQmlProfilerDefinitions::Binding: - return QQmlProfilerDefinitions::ProfileBinding; - case QQmlProfilerDefinitions::HandlingSignal: - return QQmlProfilerDefinitions::ProfileHandlingSignal; - case QQmlProfilerDefinitions::Javascript: - return QQmlProfilerDefinitions::ProfileJavaScript; - default: - return QQmlProfilerDefinitions::MaximumProfileFeature; - } + Q_UNUSED(engineId); + Q_D(QmlProfilerClient); + d->data->setTraceEndTime(time); } -void QmlProfilerClient::messageReceived(const QByteArray &data) +void QmlProfilerClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime) { - QByteArray rwData = data; - QDataStream stream(&rwData, QIODevice::ReadOnly); - stream.setVersion(QDataStream::Qt_4_7); + Q_D(QmlProfilerClient); + d->rangeStartTimes[type].push(startTime); + d->inProgressRanges |= (static_cast<qint64>(1) << type); + ++d->rangeCount[type]; +} - // Force all the 1 << <FLAG> expressions to be done in 64 bit, to silence some warnings - const quint64 one = static_cast<quint64>(1); +void QmlProfilerClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, + const QString &data) +{ + Q_UNUSED(time); + Q_D(QmlProfilerClient); + int count = d->rangeCount[type]; + if (count > 0) { + while (d->rangeDatas[type].count() < count) + d->rangeDatas[type].push(QStringList()); + d->rangeDatas[type][count - 1] << data; + } +} - qint64 time; - int messageType; +void QmlProfilerClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time, + const QQmlEventLocation &location) +{ + Q_UNUSED(time); + Q_D(QmlProfilerClient); + if (d->rangeCount[type] > 0) + d->rangeLocations[type].push(location); +} - stream >> time >> messageType; +void QmlProfilerClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime) +{ + Q_D(QmlProfilerClient); - if (messageType >= QQmlProfilerDefinitions::MaximumMessage) + if (d->rangeCount[type] == 0) { + emit error(tr("Spurious range end detected.")); return; + } - if (messageType == QQmlProfilerDefinitions::Event) { - int event; - stream >> event; - - if (event == QQmlProfilerDefinitions::EndTrace) { - emit this->traceFinished(time); - } else if (event == QQmlProfilerDefinitions::AnimationFrame) { - if (!(d->features & one << QQmlProfilerDefinitions::ProfileAnimations)) - return; - int frameRate, animationCount; - int threadId = 0; - stream >> frameRate >> animationCount; - if (!stream.atEnd()) - stream >> threadId; - emit this->frame(time, frameRate, animationCount, threadId); - } else if (event == QQmlProfilerDefinitions::StartTrace) { - emit this->traceStarted(time); - } else if (event == QQmlProfilerDefinitions::Key || - event == QQmlProfilerDefinitions::Mouse) { - if (!(d->features & one << QQmlProfilerDefinitions::ProfileInputEvents)) - return; - emit this->inputEvent((QQmlProfilerDefinitions::EventType)event, time); - } - } else if (messageType == QQmlProfilerDefinitions::Complete) { - emit complete(); - } else if (messageType == QQmlProfilerDefinitions::SceneGraphFrame) { - if (!(d->features & one << QQmlProfilerDefinitions::ProfileSceneGraph)) - return; - int sgEventType; - int count = 0; - qint64 params[5]; - - stream >> sgEventType; - while (!stream.atEnd()) { - stream >> params[count++]; - } - while (count<5) - params[count++] = 0; - emit sceneGraphFrame((QQmlProfilerDefinitions::SceneGraphFrameType)sgEventType, time, - params[0], params[1], params[2], params[3], params[4]); - } else if (messageType == QQmlProfilerDefinitions::PixmapCacheEvent) { - if (!(d->features & one << QQmlProfilerDefinitions::ProfilePixmapCache)) - return; - int pixEvTy, width = 0, height = 0, refcount = 0; - QString pixUrl; - stream >> pixEvTy >> pixUrl; - if (pixEvTy == (int)QQmlProfilerDefinitions::PixmapReferenceCountChanged || - pixEvTy == (int)QQmlProfilerDefinitions::PixmapCacheCountChanged) { - stream >> refcount; - } else if (pixEvTy == (int)QQmlProfilerDefinitions::PixmapSizeKnown) { - stream >> width >> height; - refcount = 1; - } - emit pixmapCache((QQmlProfilerDefinitions::PixmapEventType)pixEvTy, time, - QmlEventLocation(pixUrl,0,0), width, height, refcount); - } else if (messageType == QQmlProfilerDefinitions::MemoryAllocation) { - if (!(d->features & one << QQmlProfilerDefinitions::ProfileMemory)) - return; - int type; - qint64 delta; - stream >> type >> delta; - emit memoryAllocation((QQmlProfilerDefinitions::MemoryType)type, time, delta); - } else { - int range; - stream >> range; - - if (range >= QQmlProfilerDefinitions::MaximumRangeType) - return; - - if (!(d->features & one << featureFromRangeType( - static_cast<QQmlProfilerDefinitions::RangeType>(range)))) - return; - - if (messageType == QQmlProfilerDefinitions::RangeStart) { - d->rangeStartTimes[range].push(time); - d->inProgressRanges |= (static_cast<qint64>(1) << range); - ++d->rangeCount[range]; - - // read binding type - if (range == (int)QQmlProfilerDefinitions::Binding) { - int bindingType = (int)QQmlProfilerDefinitions::QmlBinding; - if (!stream.atEnd()) - stream >> bindingType; - d->bindingTypes.push((QQmlProfilerDefinitions::BindingType)bindingType); - } - } else if (messageType == QQmlProfilerDefinitions::RangeData) { - QString data; - stream >> data; - - int count = d->rangeCount[range]; - if (count > 0) { - while (d->rangeDatas[range].count() < count) - d->rangeDatas[range].push(QStringList()); - d->rangeDatas[range][count-1] << data; - } - - } else if (messageType == QQmlProfilerDefinitions::RangeLocation) { - QString fileName; - int line; - int column = -1; - stream >> fileName >> line; - - if (!stream.atEnd()) - stream >> column; - - if (d->rangeCount[range] > 0) { - d->rangeLocations[range].push(QmlEventLocation(fileName, line, - column)); - } - } else { - if (d->rangeCount[range] > 0) { - --d->rangeCount[range]; - if (d->inProgressRanges & (static_cast<qint64>(1) << range)) - d->inProgressRanges &= ~(static_cast<qint64>(1) << range); - - QStringList data = d->rangeDatas[range].count() ? - d->rangeDatas[range].pop() : QStringList(); - QmlEventLocation location = d->rangeLocations[range].count() ? - d->rangeLocations[range].pop() : QmlEventLocation(); - - qint64 startTime = d->rangeStartTimes[range].pop(); - QQmlProfilerDefinitions::BindingType bindingType = - QQmlProfilerDefinitions::QmlBinding; - if (range == (int)QQmlProfilerDefinitions::Binding) - bindingType = d->bindingTypes.pop(); - emit this->range((QQmlProfilerDefinitions::RangeType)range, - bindingType, startTime, time - startTime, data, location); - if (d->rangeCount[range] == 0) { - int count = d->rangeDatas[range].count() + - d->rangeStartTimes[range].count() + - d->rangeLocations[range].count(); - if (count != 0) - qWarning() << "incorrectly nested data"; - } - } - } + --d->rangeCount[type]; + if (d->inProgressRanges & (static_cast<qint64>(1) << type)) + d->inProgressRanges &= ~(static_cast<qint64>(1) << type); + QStringList data = d->rangeDatas[type].count() ? d->rangeDatas[type].pop() : QStringList(); + QQmlEventLocation location = d->rangeLocations[type].count() ? d->rangeLocations[type].pop() : + QQmlEventLocation(); + qint64 startTime = d->rangeStartTimes[type].pop(); + + if (d->rangeCount[type] == 0 && d->rangeDatas[type].count() + d->rangeStartTimes[type].count() + + d->rangeLocations[type].count() != 0) { + emit error(tr("Incorrectly nested range data")); + return; } + + d->data->addQmlEvent(type, QQmlProfilerDefinitions::QmlBinding, startTime, endTime - startTime, + data, location); } -V8ProfilerClient::V8ProfilerClient(QQmlDebugConnection *client) - : ProfilerClient(QStringLiteral("V8Profiler"), client) +void QmlProfilerClient::animationFrame(qint64 time, int frameRate, int animationCount, int threadId) { + Q_D(QmlProfilerClient); + d->data->addFrameEvent(time, frameRate, animationCount, threadId); } -V8ProfilerClient::~V8ProfilerClient() +void QmlProfilerClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, + qint64 time, qint64 numericData1, qint64 numericData2, + qint64 numericData3, qint64 numericData4, + qint64 numericData5) { + Q_D(QmlProfilerClient); + d->data->addSceneGraphFrameEvent(type, time, numericData1, numericData2, numericData3, + numericData4, numericData5); } -void V8ProfilerClient::sendRecordingStatus(bool record) +void QmlProfilerClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time, + const QString &url, int numericData1, int numericData2) { - QByteArray ba; - QDataStream stream(&ba, QIODevice::WriteOnly); - QByteArray cmd("V8PROFILER"); - QByteArray option(record ? "start" : "stop"); - QByteArray title(""); - - stream << cmd << option << title; - sendMessage(ba); + Q_D(QmlProfilerClient); + d->data->addPixmapCacheEvent(type, time, url, numericData1, numericData2); } -void V8ProfilerClient::messageReceived(const QByteArray &data) +void QmlProfilerClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, + qint64 amount) { - QByteArray rwData = data; - QDataStream stream(&rwData, QIODevice::ReadOnly); - - int messageType; - - stream >> messageType; - - if (messageType == V8Complete) { - emit complete(); - } else if (messageType == V8Entry) { - QString filename; - QString function; - int lineNumber; - double totalTime; - double selfTime; - int depth; + Q_D(QmlProfilerClient); + d->data->addMemoryEvent(type, time, amount); +} - stream >> filename >> function >> lineNumber >> totalTime >> - selfTime >> depth; - emit this->range(depth, function, filename, lineNumber, totalTime, - selfTime); - } +void QmlProfilerClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, + int a, int b) +{ + Q_D(QmlProfilerClient); + d->data->addInputEvent(type, time, a, b); } +void QmlProfilerClient::complete() +{ + Q_D(QmlProfilerClient); + d->data->complete(); +} diff --git a/tools/qmlprofiler/qmlprofilerclient.h b/tools/qmlprofiler/qmlprofilerclient.h index 731ab99973..fc4dad639d 100644 --- a/tools/qmlprofiler/qmlprofilerclient.h +++ b/tools/qmlprofiler/qmlprofilerclient.h @@ -34,100 +34,45 @@ #ifndef QMLPROFILERCLIENT_H #define QMLPROFILERCLIENT_H -#include "qqmldebugclient.h" -#include "qmlprofilereventlocation.h" -#include <QtQml/private/qqmlprofilerdefinitions_p.h> +#include <private/qqmleventlocation_p.h> +#include <private/qqmlprofilerclient_p.h> +#include <private/qqmlprofilerdefinitions_p.h> -class ProfilerClientPrivate; -class ProfilerClient : public QQmlDebugClient +class QmlProfilerData; +class QmlProfilerClientPrivate; +class QmlProfilerClient : public QQmlProfilerClient { Q_OBJECT + Q_DECLARE_PRIVATE(QmlProfilerClient) - Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabledChanged) public: - ProfilerClient(const QString &clientName, - QQmlDebugConnection *client); - ~ProfilerClient(); - - bool isEnabled() const; - -public slots: - virtual void clearData(); + QmlProfilerClient(QQmlDebugConnection *connection, QmlProfilerData *data); + void clearPendingData(); signals: - void complete(); - void enabledChanged(); - void cleared(); - -protected: - virtual void stateChanged(State); - -protected: - bool m_enabled; -}; - -class QmlProfilerClient : public ProfilerClient -{ - Q_OBJECT - -public: - QmlProfilerClient(QQmlDebugConnection *client); - ~QmlProfilerClient(); - - void setFeatures(quint64 features); + void enabledChanged(bool enabled); + void recordingStarted(); + void error(const QString &error); -public slots: - void clearData(); - void sendRecordingStatus(bool record); - -signals: - void traceFinished( qint64 time ); - void traceStarted( qint64 time ); - void range(QQmlProfilerDefinitions::RangeType type, - QQmlProfilerDefinitions::BindingType bindingType, - qint64 startTime, qint64 length, - const QStringList &data, - const QmlEventLocation &location); - void frame(qint64 time, int frameRate, int animationCount, int threadId); - void sceneGraphFrame(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time, +private: + virtual void stateChanged(State state); + + void traceStarted(qint64 time, int engineId); + void traceFinished(qint64 time, int engineId); + void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime); + void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, const QString &data); + void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time, + const QQmlEventLocation &location); + void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime); + void animationFrame(qint64 time, int frameRate, int animationCount, int threadId); + void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time, qint64 numericData1, qint64 numericData2, qint64 numericData3, qint64 numericData4, qint64 numericData5); - void pixmapCache(QQmlProfilerDefinitions::PixmapEventType, qint64 time, - const QmlEventLocation &location, int width, int height, int refCount); + void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time, + const QString &url, int numericData1, int numericData2); void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 amount); - void inputEvent(QQmlProfilerDefinitions::EventType, qint64 time); - -protected: - virtual void messageReceived(const QByteArray &); - -private: - class QmlProfilerClientPrivate *d; -}; - -class V8ProfilerClient : public ProfilerClient -{ - Q_OBJECT - -public: - enum Message { - V8Entry, - V8Complete, - - V8MaximumMessage - }; - - V8ProfilerClient(QQmlDebugConnection *client); - ~V8ProfilerClient(); - -public slots: - void sendRecordingStatus(bool record); - -signals: - void range(int depth, const QString &function, const QString &filename, - int lineNumber, double totalTime, double selfTime); - -protected: - virtual void messageReceived(const QByteArray &); + void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b); + void complete(); }; #endif // QMLPROFILERCLIENT_H diff --git a/tools/qmlprofiler/qmlprofilerdata.cpp b/tools/qmlprofiler/qmlprofilerdata.cpp index 307b9d3686..fd2b5acea1 100644 --- a/tools/qmlprofiler/qmlprofilerdata.cpp +++ b/tools/qmlprofiler/qmlprofilerdata.cpp @@ -73,14 +73,14 @@ Q_STATIC_ASSERT(sizeof(MESSAGE_STRINGS) == struct QmlRangeEventData { QmlRangeEventData() {} // never called QmlRangeEventData(const QString &_displayName, int _detailType, const QString &_eventHashStr, - const QmlEventLocation &_location, const QString &_details, + const QQmlEventLocation &_location, const QString &_details, QQmlProfilerDefinitions::Message _message, QQmlProfilerDefinitions::RangeType _rangeType) : displayName(_displayName), eventHashStr(_eventHashStr), location(_location), details(_details), message(_message), rangeType(_rangeType), detailType(_detailType) {} QString displayName; QString eventHashStr; - QmlEventLocation location; + QQmlEventLocation location; QString details; QQmlProfilerDefinitions::Message message; QQmlProfilerDefinitions::RangeType rangeType; @@ -107,14 +107,17 @@ struct QmlRangeEventStartInstance { qint64 duration; union { int frameRate; + int inputType; qint64 numericData1; }; union { int animationCount; + int inputA; qint64 numericData2; }; union { int threadId; + int inputB; qint64 numericData3; }; qint64 numericData4; @@ -127,18 +130,6 @@ Q_DECLARE_TYPEINFO(QmlRangeEventData, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QmlRangeEventStartInstance, Q_MOVABLE_TYPE); QT_END_NAMESPACE -struct QV8EventInfo { - QString displayName; - QString eventHashStr; - QString functionName; - QString fileName; - int line; - qint64 totalTime; - qint64 selfTime; - - QHash<QString, qint64> v8children; -}; - ///////////////////////////////////////////////////////////////// class QmlProfilerDataPrivate { @@ -148,18 +139,12 @@ public: // data storage QHash<QString, QmlRangeEventData *> eventDescriptions; QVector<QmlRangeEventStartInstance> startInstanceList; - QHash<QString, QV8EventInfo *> v8EventHash; qint64 traceStartTime; qint64 traceEndTime; // internal state while collecting events qint64 qmlMeasuredTime; - qint64 v8MeasuredTime; - QHash<int, QV8EventInfo *> v8parents; - void clearV8RootEvent(); - QV8EventInfo v8RootEvent; - QmlProfilerData::State state; }; @@ -183,12 +168,6 @@ void QmlProfilerData::clear() d->eventDescriptions.clear(); d->startInstanceList.clear(); - qDeleteAll(d->v8EventHash); - d->v8EventHash.clear(); - d->v8parents.clear(); - d->clearV8RootEvent(); - d->v8MeasuredTime = 0; - d->traceEndTime = std::numeric_limits<qint64>::min(); d->traceStartTime = std::numeric_limits<qint64>::max(); d->qmlMeasuredTime = 0; @@ -196,7 +175,7 @@ void QmlProfilerData::clear() setState(Empty); } -QString QmlProfilerData::getHashStringForQmlEvent(const QmlEventLocation &location, int eventType) +QString QmlProfilerData::getHashStringForQmlEvent(const QQmlEventLocation &location, int eventType) { return QString(QStringLiteral("%1:%2:%3:%4")).arg( location.filename, @@ -205,14 +184,9 @@ QString QmlProfilerData::getHashStringForQmlEvent(const QmlEventLocation &locati QString::number(eventType)); } -QString QmlProfilerData::getHashStringForV8Event(const QString &displayName, const QString &function) -{ - return QString(QStringLiteral("%1:%2")).arg(displayName, function); -} - QString QmlProfilerData::qmlRangeTypeAsString(QQmlProfilerDefinitions::RangeType type) { - if (type * sizeof(QString) < sizeof(RANGE_TYPE_STRINGS)) + if (type * sizeof(char *) < sizeof(RANGE_TYPE_STRINGS)) return QLatin1String(RANGE_TYPE_STRINGS[type]); else return QString::number(type); @@ -220,7 +194,7 @@ QString QmlProfilerData::qmlRangeTypeAsString(QQmlProfilerDefinitions::RangeType QString QmlProfilerData::qmlMessageAsString(QQmlProfilerDefinitions::Message type) { - if (type * sizeof(QString) < sizeof(MESSAGE_STRINGS)) + if (type * sizeof(char *) < sizeof(MESSAGE_STRINGS)) return QLatin1String(MESSAGE_STRINGS[type]); else return QString::number(type); @@ -253,15 +227,13 @@ void QmlProfilerData::addQmlEvent(QQmlProfilerDefinitions::RangeType type, qint64 startTime, qint64 duration, const QStringList &data, - const QmlEventLocation &location) + const QQmlEventLocation &location) { setState(AcquiringData); QString details; // generate details string - if (data.isEmpty()) - details = tr("Source code not available"); - else { + if (!data.isEmpty()) { details = data.join(QLatin1Char(' ')).replace( QLatin1Char('\n'), QLatin1Char(' ')).simplified(); QRegExp rewrite(QStringLiteral("\\(function \\$(\\w+)\\(\\) \\{ (return |)(.+) \\}\\)")); @@ -273,7 +245,7 @@ void QmlProfilerData::addQmlEvent(QQmlProfilerDefinitions::RangeType type, details = details.mid(details.lastIndexOf(QLatin1Char('/')) + 1); } - QmlEventLocation eventLocation = location; + QQmlEventLocation eventLocation = location; QString displayName, eventHashStr; // generate hash if (eventLocation.filename.isEmpty()) { @@ -315,7 +287,7 @@ void QmlProfilerData::addFrameEvent(qint64 time, int framerate, int animationcou } else { newEvent = new QmlRangeEventData(displayName, QQmlProfilerDefinitions::AnimationFrame, eventHashStr, - QmlEventLocation(), details, + QQmlEventLocation(), details, QQmlProfilerDefinitions::Event, QQmlProfilerDefinitions::MaximumRangeType); d->eventDescriptions.insert(eventHashStr, newEvent); @@ -340,7 +312,7 @@ void QmlProfilerData::addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGrap newEvent = d->eventDescriptions[eventHashStr]; } else { newEvent = new QmlRangeEventData(QStringLiteral("<SceneGraph>"), type, eventHashStr, - QmlEventLocation(), QString(), + QQmlEventLocation(), QString(), QQmlProfilerDefinitions::SceneGraphFrame, QQmlProfilerDefinitions::MaximumRangeType); d->eventDescriptions.insert(eventHashStr, newEvent); @@ -353,12 +325,12 @@ void QmlProfilerData::addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGrap } void QmlProfilerData::addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, - qint64 time, const QmlEventLocation &location, - int width, int height, int refcount) + qint64 time, const QString &location, + int numericData1, int numericData2) { setState(AcquiringData); - QString filePath = QUrl(location.filename).path(); + QString filePath = QUrl(location).path(); QString eventHashStr = filePath.mid(filePath.lastIndexOf(QLatin1Char('/')) + 1) + QStringLiteral(":") + QString::number(type); @@ -366,13 +338,14 @@ void QmlProfilerData::addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventTy if (d->eventDescriptions.contains(eventHashStr)) { newEvent = d->eventDescriptions[eventHashStr]; } else { - newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, location, QString(), + newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, + QQmlEventLocation(location, -1, -1), QString(), QQmlProfilerDefinitions::PixmapCacheEvent, QQmlProfilerDefinitions::MaximumRangeType); d->eventDescriptions.insert(eventHashStr, newEvent); } - QmlRangeEventStartInstance rangeEventStartInstance(time, width, height, refcount, 0, 0, + QmlRangeEventStartInstance rangeEventStartInstance(time, numericData1, numericData2, 0, 0, 0, newEvent); d->startInstanceList.append(rangeEventStartInstance); } @@ -386,7 +359,7 @@ void QmlProfilerData::addMemoryEvent(QQmlProfilerDefinitions::MemoryType type, q if (d->eventDescriptions.contains(eventHashStr)) { newEvent = d->eventDescriptions[eventHashStr]; } else { - newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, QmlEventLocation(), + newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, QQmlEventLocation(), QString(), QQmlProfilerDefinitions::MemoryAllocation, QQmlProfilerDefinitions::MaximumRangeType); d->eventDescriptions.insert(eventHashStr, newEvent); @@ -395,93 +368,36 @@ void QmlProfilerData::addMemoryEvent(QQmlProfilerDefinitions::MemoryType type, q d->startInstanceList.append(rangeEventStartInstance); } -void QmlProfilerData::addInputEvent(QQmlProfilerDefinitions::EventType type, qint64 time) +void QmlProfilerData::addInputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, + int a, int b) { setState(AcquiringData); - QString eventHashStr = QString::fromLatin1("Input:%1").arg(type); + QQmlProfilerDefinitions::EventType eventType; + switch (type) { + case QQmlProfilerDefinitions::InputKeyPress: + case QQmlProfilerDefinitions::InputKeyRelease: + case QQmlProfilerDefinitions::InputKeyUnknown: + eventType = QQmlProfilerDefinitions::Key; + break; + default: + eventType = QQmlProfilerDefinitions::Mouse; + break; + } + + QString eventHashStr = QString::fromLatin1("Input:%1").arg(eventType); QmlRangeEventData *newEvent; if (d->eventDescriptions.contains(eventHashStr)) { newEvent = d->eventDescriptions[eventHashStr]; } else { - newEvent = new QmlRangeEventData(QString(), type, eventHashStr, QmlEventLocation(), + newEvent = new QmlRangeEventData(QString(), eventType, eventHashStr, QQmlEventLocation(), QString(), QQmlProfilerDefinitions::Event, QQmlProfilerDefinitions::MaximumRangeType); d->eventDescriptions.insert(eventHashStr, newEvent); } - d->startInstanceList.append(QmlRangeEventStartInstance(time, -1, 0, 0, 0, newEvent)); -} - -QString QmlProfilerData::rootEventName() -{ - return tr("<program>"); -} - -QString QmlProfilerData::rootEventDescription() -{ - return tr("Main Program"); -} - -void QmlProfilerDataPrivate::clearV8RootEvent() -{ - v8RootEvent.displayName = QmlProfilerData::rootEventName(); - v8RootEvent.eventHashStr = QmlProfilerData::rootEventName(); - v8RootEvent.functionName = QmlProfilerData::rootEventDescription(); - v8RootEvent.line = -1; - v8RootEvent.totalTime = 0; - v8RootEvent.selfTime = 0; - v8RootEvent.v8children.clear(); -} - -void QmlProfilerData::addV8Event(int depth, const QString &function, const QString &filename, - int lineNumber, double totalTime, double selfTime) -{ - QString displayName = filename.mid(filename.lastIndexOf(QLatin1Char('/')) + 1) + - QLatin1Char(':') + QString::number(lineNumber); - QString hashStr = getHashStringForV8Event(displayName, function); - - setState(AcquiringData); - - // time is given in milliseconds, but internally we store it in microseconds - totalTime *= 1e6; - selfTime *= 1e6; - - // accumulate information - QV8EventInfo *eventData = d->v8EventHash[hashStr]; - if (!eventData) { - eventData = new QV8EventInfo; - eventData->displayName = displayName; - eventData->eventHashStr = hashStr; - eventData->fileName = filename; - eventData->functionName = function; - eventData->line = lineNumber; - eventData->totalTime = totalTime; - eventData->selfTime = selfTime; - d->v8EventHash[hashStr] = eventData; - } else { - eventData->totalTime += totalTime; - eventData->selfTime += selfTime; - } - d->v8parents[depth] = eventData; - - QV8EventInfo *parentEvent = 0; - if (depth == 0) { - parentEvent = &d->v8RootEvent; - d->v8MeasuredTime += totalTime; - } - if (depth > 0 && d->v8parents.contains(depth-1)) { - parentEvent = d->v8parents.value(depth-1); - } - - if (parentEvent != 0) { - if (!parentEvent->v8children.contains(eventData->eventHashStr)) { - parentEvent->v8children[eventData->eventHashStr] = totalTime; - } else { - parentEvent->v8children[eventData->eventHashStr] += totalTime; - } - } + d->startInstanceList.append(QmlRangeEventStartInstance(time, -1, type, a, b, newEvent)); } void QmlProfilerData::computeQmlTime() @@ -567,7 +483,7 @@ void QmlProfilerData::complete() bool QmlProfilerData::isEmpty() const { - return d->startInstanceList.isEmpty() && d->v8EventHash.isEmpty(); + return d->startInstanceList.isEmpty(); } bool QmlProfilerData::save(const QString &filename) @@ -608,21 +524,24 @@ bool QmlProfilerData::save(const QString &filename) stream.writeStartElement(QStringLiteral("event")); stream.writeAttribute(QStringLiteral("index"), QString::number( d->eventDescriptions.keys().indexOf(eventData->eventHashStr))); - stream.writeTextElement(QStringLiteral("displayname"), eventData->displayName); + if (!eventData->displayName.isEmpty()) + stream.writeTextElement(QStringLiteral("displayname"), eventData->displayName); if (eventData->rangeType != QQmlProfilerDefinitions::MaximumRangeType) stream.writeTextElement(QStringLiteral("type"), qmlRangeTypeAsString(eventData->rangeType)); else stream.writeTextElement(QStringLiteral("type"), qmlMessageAsString(eventData->message)); - if (!eventData->location.filename.isEmpty()) { + if (!eventData->location.filename.isEmpty()) stream.writeTextElement(QStringLiteral("filename"), eventData->location.filename); + if (eventData->location.line >= 0) stream.writeTextElement(QStringLiteral("line"), QString::number(eventData->location.line)); + if (eventData->location.column >= 0) stream.writeTextElement(QStringLiteral("column"), QString::number(eventData->location.column)); - } - stream.writeTextElement(QStringLiteral("details"), eventData->details); + if (!eventData->details.isEmpty()) + stream.writeTextElement(QStringLiteral("details"), eventData->details); if (eventData->rangeType == QQmlProfilerDefinitions::Binding) stream.writeTextElement(QStringLiteral("bindingType"), QString::number((int)eventData->detailType)); @@ -663,13 +582,23 @@ bool QmlProfilerData::save(const QString &filename) QString::number(event.duration)); stream.writeAttribute(QStringLiteral("eventIndex"), QString::number( d->eventDescriptions.keys().indexOf(event.data->eventHashStr))); - if (event.data->message == QQmlProfilerDefinitions::Event && - event.data->detailType == QQmlProfilerDefinitions::AnimationFrame) { - // special: animation frame - stream.writeAttribute(QStringLiteral("framerate"), QString::number(event.frameRate)); - stream.writeAttribute(QStringLiteral("animationcount"), - QString::number(event.animationCount)); - stream.writeAttribute(QStringLiteral("thread"), QString::number(event.threadId)); + if (event.data->message == QQmlProfilerDefinitions::Event) { + if (event.data->detailType == QQmlProfilerDefinitions::AnimationFrame) { + // special: animation frame + stream.writeAttribute(QStringLiteral("framerate"), QString::number(event.frameRate)); + stream.writeAttribute(QStringLiteral("animationcount"), + QString::number(event.animationCount)); + stream.writeAttribute(QStringLiteral("thread"), QString::number(event.threadId)); + } else if (event.data->detailType == QQmlProfilerDefinitions::Key || + event.data->detailType == QQmlProfilerDefinitions::Mouse) { + // numerical value here, to keep the format a bit more compact + stream.writeAttribute(QStringLiteral("type"), + QString::number(event.inputType)); + stream.writeAttribute(QStringLiteral("data1"), + QString::number(event.inputA)); + stream.writeAttribute(QStringLiteral("data2"), + QString::number(event.inputB)); + } } else if (event.data->message == QQmlProfilerDefinitions::PixmapCacheEvent) { // special: pixmap cache event if (event.data->detailType == QQmlProfilerDefinitions::PixmapSizeKnown) { @@ -682,7 +611,7 @@ bool QmlProfilerData::save(const QString &filename) event.data->detailType == QQmlProfilerDefinitions::PixmapCacheCountChanged) { stream.writeAttribute(QStringLiteral("refCount"), - QString::number(event.numericData3)); + QString::number(event.numericData1)); } } else if (event.data->message == QQmlProfilerDefinitions::SceneGraphFrame) { // special: scenegraph frame events @@ -708,38 +637,6 @@ bool QmlProfilerData::save(const QString &filename) } stream.writeEndElement(); // profilerDataModel - stream.writeStartElement(QStringLiteral("v8profile")); // v8 profiler output - stream.writeAttribute(QStringLiteral("totalTime"), QString::number(d->v8MeasuredTime)); - foreach (QV8EventInfo *v8event, d->v8EventHash.values()) { - stream.writeStartElement(QStringLiteral("event")); - stream.writeAttribute(QStringLiteral("index"),QString::number( - d->v8EventHash.keys().indexOf(v8event->eventHashStr))); - stream.writeTextElement(QStringLiteral("displayname"), v8event->displayName); - stream.writeTextElement(QStringLiteral("functionname"), v8event->functionName); - if (!v8event->fileName.isEmpty()) { - stream.writeTextElement(QStringLiteral("filename"), v8event->fileName); - stream.writeTextElement(QStringLiteral("line"), QString::number(v8event->line)); - } - stream.writeTextElement(QStringLiteral("totalTime"), QString::number(v8event->totalTime)); - stream.writeTextElement(QStringLiteral("selfTime"), QString::number(v8event->selfTime)); - if (!v8event->v8children.isEmpty()) { - stream.writeStartElement(QStringLiteral("childrenEvents")); - QStringList childrenIndexes; - QStringList childrenTimes; - foreach (const QString &childHash, v8event->v8children.keys()) { - childrenIndexes << QString::number(v8EventIndex(childHash)); - childrenTimes << QString::number(v8event->v8children[childHash]); - } - - stream.writeAttribute(QStringLiteral("list"), childrenIndexes.join(QString(", "))); - stream.writeAttribute(QStringLiteral("childrenTimes"), - childrenTimes.join(QString(", "))); - stream.writeEndElement(); - } - stream.writeEndElement(); - } - stream.writeEndElement(); // v8 profiler output - stream.writeEndElement(); // trace stream.writeEndDocument(); @@ -747,15 +644,6 @@ bool QmlProfilerData::save(const QString &filename) return true; } -int QmlProfilerData::v8EventIndex(const QString &hashStr) -{ - if (!d->v8EventHash.contains(hashStr)) { - emit error("Trying to index nonexisting v8 event"); - return -1; - } - return d->v8EventHash.keys().indexOf( hashStr ); -} - void QmlProfilerData::setState(QmlProfilerData::State state) { // It's not an error, we are continuously calling "AcquiringData" for example diff --git a/tools/qmlprofiler/qmlprofilerdata.h b/tools/qmlprofiler/qmlprofilerdata.h index 91c16c3222..345f7f2d12 100644 --- a/tools/qmlprofiler/qmlprofilerdata.h +++ b/tools/qmlprofiler/qmlprofilerdata.h @@ -34,9 +34,9 @@ #ifndef QMLPROFILERDATA_H #define QMLPROFILERDATA_H -#include "qmlprofilereventlocation.h" +#include <private/qqmleventlocation_p.h> +#include <private/qqmlprofilerdefinitions_p.h> -#include <QtQml/private/qqmlprofilerdefinitions_p.h> #include <QObject> class QmlProfilerDataPrivate; @@ -54,12 +54,9 @@ public: explicit QmlProfilerData(QObject *parent = 0); ~QmlProfilerData(); - static QString getHashStringForQmlEvent(const QmlEventLocation &location, int eventType); - static QString getHashStringForV8Event(const QString &displayName, const QString &function); + static QString getHashStringForQmlEvent(const QQmlEventLocation &location, int eventType); static QString qmlRangeTypeAsString(QQmlProfilerDefinitions::RangeType type); static QString qmlMessageAsString(QQmlProfilerDefinitions::Message type); - static QString rootEventName(); - static QString rootEventDescription(); qint64 traceStartTime() const; qint64 traceEndTime() const; @@ -78,24 +75,21 @@ public slots: void addQmlEvent(QQmlProfilerDefinitions::RangeType type, QQmlProfilerDefinitions::BindingType bindingType, qint64 startTime, qint64 duration, const QStringList &data, - const QmlEventLocation &location); - void addV8Event(int depth, const QString &function, const QString &filename, - int lineNumber, double totalTime, double selfTime); + const QQmlEventLocation &location); void addFrameEvent(qint64 time, int framerate, int animationcount, int threadId); void addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time, qint64 numericData1, qint64 numericData2, qint64 numericData3, qint64 numericData4, qint64 numericData5); void addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time, - const QmlEventLocation &location, int width, int height, int refcount); + const QString &location, int numericData1, int numericData2); void addMemoryEvent(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 size); - void addInputEvent(QQmlProfilerDefinitions::EventType type, qint64 time); + void addInputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b); void complete(); bool save(const QString &filename); private: void sortStartTimes(); - int v8EventIndex(const QString &hashStr); void computeQmlTime(); void setState(QmlProfilerData::State state); diff --git a/tools/qmlprofiler/qpacketprotocol.cpp b/tools/qmlprofiler/qpacketprotocol.cpp deleted file mode 100644 index 096bc142c5..0000000000 --- a/tools/qmlprofiler/qpacketprotocol.cpp +++ /dev/null @@ -1,527 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpacketprotocol.h" - -#include <QtCore/QBuffer> -#include <QtCore/QElapsedTimer> -#include <private/qiodevice_p.h> // for qt_subtract_from_timeout - -static const unsigned int MAX_PACKET_SIZE = 0x7FFFFFFF; - -/*! - \class QPacketProtocol - \internal - - \brief The QPacketProtocol class encapsulates communicating discrete packets - across fragmented IO channels, such as TCP sockets. - - QPacketProtocol makes it simple to send arbitrary sized data "packets" across - fragmented transports such as TCP and UDP. - - As transmission boundaries are not respected, sending packets over protocols - like TCP frequently involves "stitching" them back together at the receiver. - QPacketProtocol makes this easier by performing this task for you. Packet - data sent using QPacketProtocol is prepended with a 4-byte size header - allowing the receiving QPacketProtocol to buffer the packet internally until - it has all been received. QPacketProtocol does not perform any sanity - checking on the size or on the data, so this class should only be used in - prototyping or trusted situations where DOS attacks are unlikely. - - QPacketProtocol does not perform any communications itself. Instead it can - operate on any QIODevice that supports the QIODevice::readyRead() signal. A - logical "packet" is encapsulated by the companion QPacket class. The - following example shows two ways to send data using QPacketProtocol. The - transmitted data is equivalent in both. - - \code - QTcpSocket socket; - // ... connect socket ... - - QPacketProtocol protocol(&socket); - - // Send packet the quick way - protocol.send() << "Hello world" << 123; - - // Send packet the longer way - QPacket packet; - packet << "Hello world" << 123; - protocol.send(packet); - \endcode - - Likewise, the following shows how to read data from QPacketProtocol, assuming - that the QPacketProtocol::readyRead() signal has been emitted. - - \code - // ... QPacketProtocol::readyRead() is emitted ... - - int a; - QByteArray b; - - // Receive packet the quick way - protocol.read() >> a >> b; - - // Receive packet the longer way - QPacket packet = protocol.read(); - p >> a >> b; - \endcode - - \ingroup io - \sa QPacket -*/ - -class QPacketProtocolPrivate : public QObject -{ - Q_OBJECT -public: - QPacketProtocolPrivate(QPacketProtocol *parent, QIODevice *_dev) - : QObject(parent), inProgressSize(-1), maxPacketSize(MAX_PACKET_SIZE), - waitingForPacket(false), dev(_dev) - { - Q_ASSERT(4 == sizeof(qint32)); - - QObject::connect(this, SIGNAL(readyRead()), - parent, SIGNAL(readyRead())); - QObject::connect(this, SIGNAL(packetWritten()), - parent, SIGNAL(packetWritten())); - QObject::connect(this, SIGNAL(invalidPacket()), - parent, SIGNAL(invalidPacket())); - QObject::connect(dev, SIGNAL(readyRead()), - this, SLOT(readyToRead())); - QObject::connect(dev, SIGNAL(aboutToClose()), - this, SLOT(aboutToClose())); - QObject::connect(dev, SIGNAL(bytesWritten(qint64)), - this, SLOT(bytesWritten(qint64))); - } - -Q_SIGNALS: - void readyRead(); - void packetWritten(); - void invalidPacket(); - -public Q_SLOTS: - void aboutToClose() - { - inProgress.clear(); - sendingPackets.clear(); - inProgressSize = -1; - } - - void bytesWritten(qint64 bytes) - { - Q_ASSERT(!sendingPackets.isEmpty()); - - while (bytes) { - if (sendingPackets.at(0) > bytes) { - sendingPackets[0] -= bytes; - bytes = 0; - } else { - bytes -= sendingPackets.at(0); - sendingPackets.removeFirst(); - emit packetWritten(); - } - } - } - - void readyToRead() - { - while (true) { - // Need to get trailing data - if (-1 == inProgressSize) { - // We need a size header of sizeof(qint32) - if (sizeof(qint32) > (uint)dev->bytesAvailable()) - return; - - // Read size header - int read = dev->read((char *)&inProgressSize, sizeof(qint32)); - Q_ASSERT(read == sizeof(qint32)); - Q_UNUSED(read); - - // Check sizing constraints - if (inProgressSize > maxPacketSize) { - QObject::disconnect(dev, SIGNAL(readyRead()), - this, SLOT(readyToRead())); - QObject::disconnect(dev, SIGNAL(aboutToClose()), - this, SLOT(aboutToClose())); - QObject::disconnect(dev, SIGNAL(bytesWritten(qint64)), - this, SLOT(bytesWritten(qint64))); - dev = 0; - emit invalidPacket(); - return; - } - - inProgressSize -= sizeof(qint32); - } else { - inProgress.append(dev->read(inProgressSize - inProgress.size())); - - if (inProgressSize == inProgress.size()) { - // Packet has arrived! - packets.append(inProgress); - inProgressSize = -1; - inProgress.clear(); - - waitingForPacket = false; - emit readyRead(); - } else - return; - } - } - } - -public: - QList<qint64> sendingPackets; - QList<QByteArray> packets; - QByteArray inProgress; - qint32 inProgressSize; - qint32 maxPacketSize; - bool waitingForPacket; - QIODevice *dev; -}; - -/*! - Construct a QPacketProtocol instance that works on \a dev with the - specified \a parent. - */ -QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent) - : QObject(parent), d(new QPacketProtocolPrivate(this, dev)) -{ - Q_ASSERT(dev); -} - -/*! - Destroys the QPacketProtocol instance. - */ -QPacketProtocol::~QPacketProtocol() -{ -} - -/*! - Returns the maximum packet size allowed. By default this is - 2,147,483,647 bytes. - - If a packet claiming to be larger than the maximum packet size is received, - the QPacketProtocol::invalidPacket() signal is emitted. - - \sa QPacketProtocol::setMaximumPacketSize() - */ -qint32 QPacketProtocol::maximumPacketSize() const -{ - return d->maxPacketSize; -} - -/*! - Sets the maximum allowable packet size to \a max. - - \sa QPacketProtocol::maximumPacketSize() - */ -qint32 QPacketProtocol::setMaximumPacketSize(qint32 max) -{ - if (max > (signed)sizeof(qint32)) - d->maxPacketSize = max; - return d->maxPacketSize; -} - -/*! - Returns a streamable object that is transmitted on destruction. For example - - \code - protocol.send() << "Hello world" << 123; - \endcode - - will send a packet containing "Hello world" and 123. To construct more - complex packets, explicitly construct a QPacket instance. - */ -QPacketAutoSend QPacketProtocol::send() -{ - return QPacketAutoSend(this); -} - -/*! - \fn void QPacketProtocol::send(const QPacket & packet) - - Transmit the \a packet. - */ -void QPacketProtocol::send(const QPacket & p) -{ - if (p.b.isEmpty()) - return; // We don't send empty packets - - qint64 sendSize = p.b.size() + sizeof(qint32); - - d->sendingPackets.append(sendSize); - qint32 sendSize32 = sendSize; - qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32)); - Q_UNUSED(writeBytes); - Q_ASSERT(writeBytes == sizeof(qint32)); - writeBytes = d->dev->write(p.b); - Q_ASSERT(writeBytes == p.b.size()); -} - -/*! - Returns the number of received packets yet to be read. - */ -qint64 QPacketProtocol::packetsAvailable() const -{ - return d->packets.count(); -} - -/*! - Discard any unread packets. - */ -void QPacketProtocol::clear() -{ - d->packets.clear(); -} - -/*! - Return the next unread packet, or an invalid QPacket instance if no packets - are available. This method does NOT block. - */ -QPacket QPacketProtocol::read() -{ - if (0 == d->packets.count()) - return QPacket(); - - QPacket rv(d->packets.at(0)); - d->packets.removeFirst(); - return rv; -} - -/*! - This function locks until a new packet is available for reading and the - \l{QIODevice::}{readyRead()} signal has been emitted. The function - will timeout after \a msecs milliseconds; the default timeout is - 30000 milliseconds. - - The function returns true if the readyRead() signal is emitted and - there is new data available for reading; otherwise it returns false - (if an error occurred or the operation timed out). - */ - -bool QPacketProtocol::waitForReadyRead(int msecs) -{ - if (!d->packets.isEmpty()) - return true; - - QElapsedTimer stopWatch; - stopWatch.start(); - - d->waitingForPacket = true; - do { - if (!d->dev->waitForReadyRead(msecs)) - return false; - if (!d->waitingForPacket) - return true; - msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed()); - } while (true); -} - -/*! - Return the QIODevice passed to the QPacketProtocol constructor. -*/ -QIODevice *QPacketProtocol::device() -{ - return d->dev; -} - -/*! - \fn void QPacketProtocol::readyRead() - - Emitted whenever a new packet is received. Applications may use - QPacketProtocol::read() to retrieve this packet. - */ - -/*! - \fn void QPacketProtocol::invalidPacket() - - A packet larger than the maximum allowable packet size was received. The - packet will be discarded and, as it indicates corruption in the protocol, no - further packets will be received. - */ - -/*! - \fn void QPacketProtocol::packetWritten() - - Emitted each time a packet is completing written to the device. This signal - may be used for communications flow control. - */ - -/*! - \class QPacket - \internal - - \brief The QPacket class encapsulates an unfragmentable packet of data to be - transmitted by QPacketProtocol. - - The QPacket class works together with QPacketProtocol to make it simple to - send arbitrary sized data "packets" across fragmented transports such as TCP - and UDP. - - QPacket provides a QDataStream interface to an unfragmentable packet. - Applications should construct a QPacket, propagate it with data and then - transmit it over a QPacketProtocol instance. For example: - \code - QPacketProtocol protocol(...); - - QPacket myPacket; - myPacket << "Hello world!" << 123; - protocol.send(myPacket); - \endcode - - As long as both ends of the connection are using the QPacketProtocol class, - the data within this packet will be delivered unfragmented at the other end, - ready for extraction. - - \code - QByteArray greeting; - int count; - - QPacket myPacket = protocol.read(); - - myPacket >> greeting >> count; - \endcode - - Only packets returned from QPacketProtocol::read() may be read from. QPacket - instances constructed by directly by applications are for transmission only - and are considered "write only". Attempting to read data from them will - result in undefined behavior. - - \ingroup io - \sa QPacketProtocol - */ - -/*! - Constructs an empty write-only packet. - */ -QPacket::QPacket() - : QDataStream(), buf(0) -{ - buf = new QBuffer(&b); - buf->open(QIODevice::WriteOnly); - setDevice(buf); - setVersion(QDataStream::Qt_4_7); -} - -/*! - Destroys the QPacket instance. - */ -QPacket::~QPacket() -{ - if (buf) { - delete buf; - buf = 0; - } -} - -/*! - Creates a copy of \a other. The initial stream positions are shared, but the - two packets are otherwise independent. - */ -QPacket::QPacket(const QPacket & other) - : QDataStream(), b(other.b), buf(0) -{ - buf = new QBuffer(&b); - buf->open(other.buf->openMode()); - setDevice(buf); -} - -/*! - \internal - */ -QPacket::QPacket(const QByteArray & ba) - : QDataStream(), b(ba), buf(0) -{ - buf = new QBuffer(&b); - buf->open(QIODevice::ReadOnly); - setDevice(buf); -} - -/*! - Returns true if this packet is empty - that is, contains no data. - */ -bool QPacket::isEmpty() const -{ - return b.isEmpty(); -} - -/*! - Returns raw packet data. - */ -QByteArray QPacket::data() const -{ - return b; -} - -/*! - Clears data in the packet. This is useful for reusing one writable packet. - For example - \code - QPacketProtocol protocol(...); - - QPacket packet; - - packet << "Hello world!" << 123; - protocol.send(packet); - - packet.clear(); - packet << "Goodbyte world!" << 789; - protocol.send(packet); - \endcode - */ -void QPacket::clear() -{ - QBuffer::OpenMode oldMode = buf->openMode(); - buf->close(); - b.clear(); - buf->setBuffer(&b); // reset QBuffer internals with new size of b. - buf->open(oldMode); -} - -/*! - \class QPacketAutoSend - \internal - - \internal - */ -QPacketAutoSend::QPacketAutoSend(QPacketProtocol *_p) - : QPacket(), p(_p) -{ -} - -QPacketAutoSend::~QPacketAutoSend() -{ - if (!b.isEmpty()) - p->send(*this); -} - -#include <qpacketprotocol.moc> diff --git a/tools/qmlprofiler/qqmldebugclient.cpp b/tools/qmlprofiler/qqmldebugclient.cpp deleted file mode 100644 index f87d4b0a7c..0000000000 --- a/tools/qmlprofiler/qqmldebugclient.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmldebugclient.h" -#include "qpacketprotocol.h" - -#include <QtCore/qdebug.h> -#include <QtCore/qstringlist.h> -#include <QtNetwork/qnetworkproxy.h> - -const int protocolVersion = 1; -const QString serverId = QLatin1String("QDeclarativeDebugServer"); -const QString clientId = QLatin1String("QDeclarativeDebugClient"); - -class QQmlDebugClientPrivate -{ -public: - QQmlDebugClientPrivate(); - - QString name; - QQmlDebugConnection *connection; -}; - -class QQmlDebugConnectionPrivate : public QObject -{ - Q_OBJECT -public: - QQmlDebugConnectionPrivate(QQmlDebugConnection *c); - QQmlDebugConnection *q; - QPacketProtocol *protocol; - QIODevice *device; - - bool gotHello; - QHash <QString, float> serverPlugins; - QHash<QString, QQmlDebugClient *> plugins; - - void advertisePlugins(); - void connectDeviceSignals(); - -public Q_SLOTS: - void connected(); - void readyRead(); - void deviceAboutToClose(); -}; - -QQmlDebugConnectionPrivate::QQmlDebugConnectionPrivate(QQmlDebugConnection *c) - : QObject(c), q(c), protocol(0), device(0), gotHello(false) -{ - protocol = new QPacketProtocol(q, this); - QObject::connect(c, SIGNAL(connected()), this, SLOT(connected())); - QObject::connect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); -} - -void QQmlDebugConnectionPrivate::advertisePlugins() -{ - if (!q->isConnected()) - return; - - QPacket pack; - pack << serverId << 1 << plugins.keys(); - protocol->send(pack); - q->flush(); -} - -void QQmlDebugConnectionPrivate::connected() -{ - QPacket pack; - pack << serverId << 0 << protocolVersion << plugins.keys(); - protocol->send(pack); - q->flush(); -} - -void QQmlDebugConnectionPrivate::readyRead() -{ - if (!gotHello) { - QPacket pack = protocol->read(); - QString name; - - pack >> name; - - bool validHello = false; - if (name == clientId) { - int op = -1; - pack >> op; - if (op == 0) { - int version = -1; - pack >> version; - if (version == protocolVersion) { - QStringList pluginNames; - QList<float> pluginVersions; - pack >> pluginNames; - if (!pack.isEmpty()) - pack >> pluginVersions; - - const int pluginNamesSize = pluginNames.size(); - const int pluginVersionsSize = pluginVersions.size(); - for (int i = 0; i < pluginNamesSize; ++i) { - float pluginVersion = 1.0; - if (i < pluginVersionsSize) - pluginVersion = pluginVersions.at(i); - serverPlugins.insert(pluginNames.at(i), pluginVersion); - } - - validHello = true; - } - } - } - - if (!validHello) { - qWarning("QQmlDebugConnection: Invalid hello message"); - QObject::disconnect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); - return; - } - gotHello = true; - - QHash<QString, QQmlDebugClient *>::Iterator iter = plugins.begin(); - for (; iter != plugins.end(); ++iter) { - QQmlDebugClient::State newState = QQmlDebugClient::Unavailable; - if (serverPlugins.contains(iter.key())) - newState = QQmlDebugClient::Enabled; - iter.value()->stateChanged(newState); - } - } - - while (protocol->packetsAvailable()) { - QPacket pack = protocol->read(); - QString name; - pack >> name; - - if (name == clientId) { - int op = -1; - pack >> op; - - if (op == 1) { - // Service Discovery - QHash<QString, float> oldServerPlugins = serverPlugins; - serverPlugins.clear(); - - QStringList pluginNames; - QList<float> pluginVersions; - pack >> pluginNames; - if (!pack.isEmpty()) - pack >> pluginVersions; - - const int pluginNamesSize = pluginNames.size(); - const int pluginVersionsSize = pluginVersions.size(); - for (int i = 0; i < pluginNamesSize; ++i) { - float pluginVersion = 1.0; - if (i < pluginVersionsSize) - pluginVersion = pluginVersions.at(i); - serverPlugins.insert(pluginNames.at(i), pluginVersion); - } - - QHash<QString, QQmlDebugClient *>::Iterator iter = plugins.begin(); - for (; iter != plugins.end(); ++iter) { - const QString pluginName = iter.key(); - QQmlDebugClient::State newSate = QQmlDebugClient::Unavailable; - if (serverPlugins.contains(pluginName)) - newSate = QQmlDebugClient::Enabled; - - if (oldServerPlugins.contains(pluginName) - != serverPlugins.contains(pluginName)) { - iter.value()->stateChanged(newSate); - } - } - } else { - qWarning() << "QQmlDebugConnection: Unknown control message id" << op; - } - } else { - QByteArray message; - pack >> message; - - QHash<QString, QQmlDebugClient *>::Iterator iter = - plugins.find(name); - if (iter == plugins.end()) { - qWarning() << "QQmlDebugConnection: Message received for missing plugin" << name; - } else { - (*iter)->messageReceived(message); - } - } - } -} - -void QQmlDebugConnectionPrivate::deviceAboutToClose() -{ - // This is nasty syntax but we want to emit our own aboutToClose signal (by calling QIODevice::close()) - // without calling the underlying device close fn as that would cause an infinite loop - q->QIODevice::close(); -} - -QQmlDebugConnection::QQmlDebugConnection(QObject *parent) - : QIODevice(parent), d(new QQmlDebugConnectionPrivate(this)) -{ -} - -QQmlDebugConnection::~QQmlDebugConnection() -{ - QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin(); - for (; iter != d->plugins.end(); ++iter) { - iter.value()->d->connection = 0; - iter.value()->stateChanged(QQmlDebugClient::NotConnected); - } -} - -bool QQmlDebugConnection::isConnected() const -{ - return state() == QAbstractSocket::ConnectedState; -} - -qint64 QQmlDebugConnection::readData(char *data, qint64 maxSize) -{ - return d->device->read(data, maxSize); -} - -qint64 QQmlDebugConnection::writeData(const char *data, qint64 maxSize) -{ - return d->device->write(data, maxSize); -} - -qint64 QQmlDebugConnection::bytesAvailable() const -{ - return d->device->bytesAvailable(); -} - -bool QQmlDebugConnection::isSequential() const -{ - return true; -} - -void QQmlDebugConnection::close() -{ - if (isOpen()) { - QIODevice::close(); - d->device->close(); - emit stateChanged(QAbstractSocket::UnconnectedState); - - QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin(); - for (; iter != d->plugins.end(); ++iter) { - iter.value()->stateChanged(QQmlDebugClient::NotConnected); - } - } -} - -bool QQmlDebugConnection::waitForConnected(int msecs) -{ - QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); - if (socket) - return socket->waitForConnected(msecs); - return false; -} - -QAbstractSocket::SocketState QQmlDebugConnection::state() const -{ - QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); - if (socket) - return socket->state(); - - return QAbstractSocket::UnconnectedState; -} - -void QQmlDebugConnection::flush() -{ - QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); - if (socket) { - socket->flush(); - return; - } -} - -void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port) -{ - QTcpSocket *socket = new QTcpSocket(d); -#ifndef QT_NO_NETWORKPROXY - socket->setProxy(QNetworkProxy::NoProxy); -#endif - d->device = socket; - d->connectDeviceSignals(); - d->gotHello = false; - connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SIGNAL(stateChanged(QAbstractSocket::SocketState))); - connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))); - connect(socket, SIGNAL(connected()), this, SIGNAL(connected())); - socket->connectToHost(hostName, port); - QIODevice::open(ReadWrite | Unbuffered); -} - -void QQmlDebugConnectionPrivate::connectDeviceSignals() -{ - connect(device, SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64))); - connect(device, SIGNAL(readyRead()), q, SIGNAL(readyRead())); - connect(device, SIGNAL(aboutToClose()), this, SLOT(deviceAboutToClose())); -} - -// - -QQmlDebugClientPrivate::QQmlDebugClientPrivate() - : connection(0) -{ -} - -QQmlDebugClient::QQmlDebugClient(const QString &name, - QQmlDebugConnection *parent) - : QObject(parent), - d(new QQmlDebugClientPrivate) -{ - d->name = name; - d->connection = parent; - - if (!d->connection) - return; - - if (d->connection->d->plugins.contains(name)) { - qWarning() << "QQmlDebugClient: Conflicting plugin name" << name; - d->connection = 0; - } else { - d->connection->d->plugins.insert(name, this); - d->connection->d->advertisePlugins(); - } -} - -QQmlDebugClient::~QQmlDebugClient() -{ - if (d->connection && d->connection->d) { - d->connection->d->plugins.remove(d->name); - d->connection->d->advertisePlugins(); - } - delete d; -} - -QString QQmlDebugClient::name() const -{ - return d->name; -} - -float QQmlDebugClient::serviceVersion() const -{ - if (d->connection->d->serverPlugins.contains(d->name)) - return d->connection->d->serverPlugins.value(d->name); - return -1; -} - -QQmlDebugClient::State QQmlDebugClient::state() const -{ - if (!d->connection - || !d->connection->isConnected() - || !d->connection->d->gotHello) - return NotConnected; - - if (d->connection->d->serverPlugins.contains(d->name)) - return Enabled; - - return Unavailable; -} - -void QQmlDebugClient::sendMessage(const QByteArray &message) -{ - if (state() != Enabled) - return; - - QPacket pack; - pack << d->name << message; - d->connection->d->protocol->send(pack); - d->connection->flush(); -} - -void QQmlDebugClient::stateChanged(State) -{ -} - -void QQmlDebugClient::messageReceived(const QByteArray &) -{ -} - -#include <qqmldebugclient.moc> |