summaryrefslogtreecommitdiffstats
path: root/src/declarative/debugger/qdeclarativedebugservice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/debugger/qdeclarativedebugservice.cpp')
-rw-r--r--src/declarative/debugger/qdeclarativedebugservice.cpp137
1 files changed, 106 insertions, 31 deletions
diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp
index 1f2bf4f..b98cd5d 100644
--- a/src/declarative/debugger/qdeclarativedebugservice.cpp
+++ b/src/declarative/debugger/qdeclarativedebugservice.cpp
@@ -54,6 +54,30 @@
QT_BEGIN_NAMESPACE
+/*
+ QDeclarativeDebug Protocol (Version 1):
+
+ handshake:
+ 1. Client sends
+ "QDeclarativeDebugServer" 0 version pluginNames
+ version: an int representing the highest protocol version the client knows
+ pluginNames: plugins available on client side
+ 2. Server sends
+ "QDeclarativeDebugClient" 0 version pluginNames
+ version: an int representing the highest protocol version the client & server know
+ pluginNames: plugins available on server side. plugins both in the client and server message are enabled.
+ client plugin advertisement
+ 1. Client sends
+ "QDeclarativeDebugServer" 1 pluginNames
+ server plugin advertisement
+ 1. Server sends
+ "QDeclarativeDebugClient" 1 pluginNames
+ plugin communication:
+ Everything send with a header different to "QDeclarativeDebugServer" is sent to the appropriate plugin.
+ */
+
+const int protocolVersion = 1;
+
class QDeclarativeDebugServerPrivate;
class QDeclarativeDebugServer : public QObject
{
@@ -82,11 +106,13 @@ class QDeclarativeDebugServerPrivate : public QObjectPrivate
public:
QDeclarativeDebugServerPrivate();
+ void advertisePlugins();
+
int port;
QTcpSocket *connection;
QPacketProtocol *protocol;
QHash<QString, QDeclarativeDebugService *> plugins;
- QStringList enabledPlugins;
+ QStringList clientPlugins;
QTcpServer *tcpServer;
bool gotHello;
};
@@ -106,6 +132,19 @@ QDeclarativeDebugServerPrivate::QDeclarativeDebugServerPrivate()
{
}
+void QDeclarativeDebugServerPrivate::advertisePlugins()
+{
+ if (!connection
+ || connection->state() != QTcpSocket::ConnectedState
+ || !gotHello)
+ return;
+
+ QPacket pack;
+ pack << QString(QLatin1String("QDeclarativeDebugClient")) << 1 << plugins.keys();
+ protocol->send(pack);
+ connection->flush();
+}
+
void QDeclarativeDebugServer::listen()
{
Q_D(QDeclarativeDebugServer);
@@ -144,7 +183,9 @@ void QDeclarativeDebugServer::newConnection()
bool QDeclarativeDebugServer::hasDebuggingClient() const
{
Q_D(const QDeclarativeDebugServer);
- return d->gotHello;
+ return d->connection
+ && (d->connection->state() == QTcpSocket::ConnectedState)
+ && d->gotHello;
}
QDeclarativeDebugServer *QDeclarativeDebugServer::instance()
@@ -178,8 +219,8 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance()
server->waitForConnection();
}
} else {
- qWarning(QString("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". "
- "Format is -qmljsdebugger=port:<port>[,block]").arg(
+ qWarning(QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". "
+ "Format is -qmljsdebugger=port:<port>[,block]").arg(
appD->qmljsDebugArguments).toAscii().constData());
}
}
@@ -202,9 +243,13 @@ void QDeclarativeDebugServer::readyRead()
if (!d->gotHello) {
QPacket hello = d->protocol->read();
- QString name;
- hello >> name >> d->enabledPlugins;
- if (name != QLatin1String("QDeclarativeDebugServer")) {
+
+ QString name;
+ int op;
+ hello >> name >> op;
+
+ if (name != QLatin1String("QDeclarativeDebugServer")
+ || op != 0) {
qWarning("QDeclarativeDebugServer: Invalid hello message");
QObject::disconnect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
d->protocol->deleteLater();
@@ -213,6 +258,23 @@ void QDeclarativeDebugServer::readyRead()
d->connection = 0;
return;
}
+
+ int version;
+ hello >> version >> d->clientPlugins;
+
+ QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin();
+ for (; iter != d->plugins.end(); ++iter) {
+ QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
+ if (d->clientPlugins.contains(iter.key()))
+ newStatus = QDeclarativeDebugService::Enabled;
+ iter.value()->statusChanged(newStatus);
+ }
+
+ QPacket helloAnswer;
+ helloAnswer << QString(QLatin1String("QDeclarativeDebugClient")) << 0 << protocolVersion << d->plugins.keys();
+ d->protocol->send(helloAnswer);
+ d->connection->flush();
+
d->gotHello = true;
qWarning("QDeclarativeDebugServer: Connection established");
}
@@ -226,32 +288,29 @@ void QDeclarativeDebugServer::readyRead()
pack >> name;
if (name == debugServer) {
- int op = -1; QString plugin;
- pack >> op >> plugin;
+ int op = -1;
+ pack >> op;
if (op == 1) {
- // Enable
- if (!d->enabledPlugins.contains(plugin)) {
- d->enabledPlugins.append(plugin);
- QHash<QString, QDeclarativeDebugService *>::Iterator iter =
- d->plugins.find(plugin);
- if (iter != d->plugins.end())
- (*iter)->enabledChanged(true);
- }
-
- } else if (op == 2) {
- // Disable
- if (d->enabledPlugins.contains(plugin)) {
- d->enabledPlugins.removeAll(plugin);
- QHash<QString, QDeclarativeDebugService *>::Iterator iter =
- d->plugins.find(plugin);
- if (iter != d->plugins.end())
- (*iter)->enabledChanged(false);
+ // Service Discovery
+ QStringList oldClientPlugins = d->clientPlugins;
+ pack >> d->clientPlugins;
+
+ QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin();
+ for (; iter != d->plugins.end(); ++iter) {
+ const QString pluginName = iter.key();
+ QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
+ if (d->clientPlugins.contains(pluginName))
+ newStatus = QDeclarativeDebugService::Enabled;
+
+ if (oldClientPlugins.contains(pluginName)
+ != d->clientPlugins.contains(pluginName)) {
+ iter.value()->statusChanged(newStatus);
+ }
}
} else {
qWarning("QDeclarativeDebugServer: Invalid control message %d", op);
}
-
} else {
QByteArray message;
pack >> message;
@@ -287,6 +346,16 @@ QDeclarativeDebugService::QDeclarativeDebugService(const QString &name, QObject
d->server = 0;
} else {
d->server->d_func()->plugins.insert(name, this);
+ d->server->d_func()->advertisePlugins();
+ }
+}
+
+QDeclarativeDebugService::~QDeclarativeDebugService()
+{
+ Q_D(const QDeclarativeDebugService);
+ if (d->server) {
+ d->server->d_func()->plugins.remove(d->name);
+ d->server->d_func()->advertisePlugins();
}
}
@@ -296,10 +365,16 @@ QString QDeclarativeDebugService::name() const
return d->name;
}
-bool QDeclarativeDebugService::isEnabled() const
+QDeclarativeDebugService::Status QDeclarativeDebugService::status() const
{
Q_D(const QDeclarativeDebugService);
- return (d->server && d->server->d_func()->enabledPlugins.contains(d->name));
+ if (!d->server
+ || !d->server->hasDebuggingClient())
+ return NotConnected;
+ if (d->server->d_func()->clientPlugins.contains(d->name))
+ return Enabled;
+
+ return Unavailable;
}
namespace {
@@ -413,7 +488,7 @@ void QDeclarativeDebugService::sendMessage(const QByteArray &message)
{
Q_D(QDeclarativeDebugService);
- if (!d->server || !d->server->d_func()->connection)
+ if (status() != Enabled)
return;
QPacket pack;
@@ -422,7 +497,7 @@ void QDeclarativeDebugService::sendMessage(const QByteArray &message)
d->server->d_func()->connection->flush();
}
-void QDeclarativeDebugService::enabledChanged(bool)
+void QDeclarativeDebugService::statusChanged(Status)
{
}