aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmldebug
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-09-16 16:28:24 +0200
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2015-10-30 19:05:07 +0000
commit79ed2f70f05d30b82c0cec8843f5431cf8224f1c (patch)
tree930374460a204c5e4cae6210528998c53d350c97 /src/qmldebug
parente1db5c660734bd8d43675469ce828944347e739b (diff)
Move QQmlDebugClient into separate static library
Change-Id: Ib3daf9da2cf6798bd022cfcf54d11e565c9cb4ca Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/qmldebug')
-rw-r--r--src/qmldebug/qmldebug.pro14
-rw-r--r--src/qmldebug/qqmldebugclient.cpp118
-rw-r--r--src/qmldebug/qqmldebugclient_p.h83
-rw-r--r--src/qmldebug/qqmldebugclient_p_p.h66
-rw-r--r--src/qmldebug/qqmldebugconnection.cpp409
-rw-r--r--src/qmldebug/qqmldebugconnection_p.h93
6 files changed, 783 insertions, 0 deletions
diff --git a/src/qmldebug/qmldebug.pro b/src/qmldebug/qmldebug.pro
new file mode 100644
index 0000000000..6166e85e82
--- /dev/null
+++ b/src/qmldebug/qmldebug.pro
@@ -0,0 +1,14 @@
+TARGET = QtQmlDebug
+QT = core-private network packetprotocol-private
+CONFIG += static internal_module
+
+load(qt_module)
+
+SOURCES += \
+ qqmldebugclient.cpp \
+ qqmldebugconnection.cpp
+
+HEADERS += \
+ qqmldebugclient_p.h \
+ qqmldebugclient_p_p.h \
+ qqmldebugconnection_p.h
diff --git a/src/qmldebug/qqmldebugclient.cpp b/src/qmldebug/qqmldebugclient.cpp
new file mode 100644
index 0000000000..6f27cede4b
--- /dev/null
+++ b/src/qmldebug/qqmldebugclient.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** 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);
+}
+
+void QQmlDebugClient::stateChanged(QQmlDebugClient::State state)
+{
+ Q_UNUSED(state);
+}
+
+void QQmlDebugClient::messageReceived(const QByteArray &message)
+{
+ Q_UNUSED(message);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmldebugclient_p.h b/src/qmldebug/qqmldebugclient_p.h
new file mode 100644
index 0000000000..997e6879cf
--- /dev/null
+++ b/src/qmldebug/qqmldebugclient_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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_H
+#define QQMLDEBUGCLIENT_P_H
+
+#include <QtCore/qobject.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 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 &name, QQmlDebugConnection *parent);
+ ~QQmlDebugClient();
+
+ QString name() const;
+ float serviceVersion() const;
+ State state() const;
+ void sendMessage(const QByteArray &message);
+
+protected:
+ QQmlDebugClient(QQmlDebugClientPrivate &dd);
+
+private:
+ friend class QQmlDebugConnection;
+
+ virtual void stateChanged(State state);
+ virtual void messageReceived(const QByteArray &message);
+};
+
+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..b4ced0580e
--- /dev/null
+++ b/src/qmldebug/qqmldebugconnection.cpp
@@ -0,0 +1,409 @@
+/****************************************************************************
+**
+** 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 dataStreamVersion;
+ 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), dataStreamVersion(QDataStream::Qt_5_0)
+{
+ handshakeTimer.setSingleShot(true);
+ handshakeTimer.setInterval(3000);
+}
+
+void QQmlDebugConnectionPrivate::advertisePlugins()
+{
+ Q_Q(QQmlDebugConnection);
+ if (!q->isConnected())
+ return;
+
+ QPacket pack;
+ pack << serverId << 1 << plugins.keys();
+ protocol->send(pack);
+ flush();
+}
+
+void QQmlDebugConnection::socketConnected()
+{
+ Q_D(QQmlDebugConnection);
+ QPacket pack;
+ pack << serverId << 0 << protocolVersion << d->plugins.keys() << d->dataStreamVersion;
+ d->protocol->send(pack);
+ d->flush();
+}
+
+void QQmlDebugConnection::socketDisconnected()
+{
+ Q_D(QQmlDebugConnection);
+ d->gotHello = false;
+}
+
+void QQmlDebugConnection::protocolReadyRead()
+{
+ Q_D(QQmlDebugConnection);
+ if (!d->gotHello) {
+ QPacket pack = 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->dataStreamVersion;
+ 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->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);
+}
+
+void QQmlDebugConnection::setDataStreamVersion(int dataStreamVersion)
+{
+ Q_D(QQmlDebugConnection);
+ d->dataStreamVersion = dataStreamVersion;
+}
+
+int QQmlDebugConnection::dataStreamVersion()
+{
+ Q_D(QQmlDebugConnection);
+ return d->dataStreamVersion;
+}
+
+bool QQmlDebugConnection::isConnected() const
+{
+ Q_D(const QQmlDebugConnection);
+ return d->gotHello;
+}
+
+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;
+ pack << name << message;
+ d->protocol->send(pack);
+ 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(disconnected()), this, SLOT(socketDisconnected()));
+ 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);
+}
+
+void QQmlDebugConnection::newConnection()
+{
+ Q_D(QQmlDebugConnection);
+ delete d->device;
+ QLocalSocket *socket = d->server->nextPendingConnection();
+ d->server->close();
+ d->device = socket;
+ d->connectDeviceSignals();
+ 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
diff --git a/src/qmldebug/qqmldebugconnection_p.h b/src/qmldebug/qqmldebugconnection_p.h
new file mode 100644
index 0000000000..b3845b95a0
--- /dev/null
+++ b/src/qmldebug/qqmldebugconnection_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 QQMLDEBUGCONNECTION_P_H
+#define QQMLDEBUGCONNECTION_P_H
+
+#include <QtCore/qobject.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 QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QQmlDebugConnection)
+ Q_DECLARE_PRIVATE(QQmlDebugConnection)
+public:
+ QQmlDebugConnection(QObject *parent = 0);
+ ~QQmlDebugConnection();
+
+ void connectToHost(const QString &hostName, quint16 port);
+ void startLocalServer(const QString &fileName);
+
+ void setDataStreamVersion(int dataStreamVersion);
+ int dataStreamVersion();
+
+ bool isConnected() const;
+ void close();
+ bool waitForConnected(int msecs = 30000);
+
+ 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();
+
+private Q_SLOTS:
+ void newConnection();
+ void socketConnected();
+ void socketDisconnected();
+ void protocolReadyRead();
+ void handshakeTimeout();
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLDEBUGCONNECTION_P_H