forked from qt-creator/qt-creator
Added some support for QML debugging over USB. Fixed some issues with -qmljsdebugger option.
Not fully working over USB yet, there are some handshaking issues that need to be addressed. WLAN might be improved due to the -qmljsdebugger fixes, but not tested.
This commit is contained in:
committed by
Kai Koehne
parent
ed79c97d83
commit
48fef07a08
@@ -45,12 +45,14 @@
|
|||||||
|
|
||||||
#include <QtCore/qdebug.h>
|
#include <QtCore/qdebug.h>
|
||||||
#include <QtCore/qstringlist.h>
|
#include <QtCore/qstringlist.h>
|
||||||
|
#include <symbiandevicemanager.h>
|
||||||
|
|
||||||
namespace QmlJsDebugClient {
|
namespace QmlJsDebugClient {
|
||||||
|
|
||||||
const int protocolVersion = 1;
|
const int protocolVersion = 1;
|
||||||
const QString serverId = QLatin1String("QDeclarativeDebugServer");
|
const QString serverId = QLatin1String("QDeclarativeDebugServer");
|
||||||
const QString clientId = QLatin1String("QDeclarativeDebugClient");
|
const QString clientId = QLatin1String("QDeclarativeDebugClient");
|
||||||
|
static const uchar KQmlOstProtocolId = 0x94;
|
||||||
|
|
||||||
class QDeclarativeDebugClientPrivate
|
class QDeclarativeDebugClientPrivate
|
||||||
{
|
{
|
||||||
@@ -69,20 +71,23 @@ public:
|
|||||||
QDeclarativeDebugConnectionPrivate(QDeclarativeDebugConnection *c);
|
QDeclarativeDebugConnectionPrivate(QDeclarativeDebugConnection *c);
|
||||||
QDeclarativeDebugConnection *q;
|
QDeclarativeDebugConnection *q;
|
||||||
QPacketProtocol *protocol;
|
QPacketProtocol *protocol;
|
||||||
|
QIODevice *device; // Currently either a QTcpSocket or a SymbianUtils::OstChannel
|
||||||
|
|
||||||
bool gotHello;
|
bool gotHello;
|
||||||
QStringList serverPlugins;
|
QStringList serverPlugins;
|
||||||
QHash<QString, QDeclarativeDebugClient *> plugins;
|
QHash<QString, QDeclarativeDebugClient *> plugins;
|
||||||
|
|
||||||
void advertisePlugins();
|
void advertisePlugins();
|
||||||
|
void connectDeviceSignals();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void connected();
|
void connected();
|
||||||
void readyRead();
|
void readyRead();
|
||||||
|
void deviceAboutToClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
QDeclarativeDebugConnectionPrivate::QDeclarativeDebugConnectionPrivate(QDeclarativeDebugConnection *c)
|
QDeclarativeDebugConnectionPrivate::QDeclarativeDebugConnectionPrivate(QDeclarativeDebugConnection *c)
|
||||||
: QObject(c), q(c), protocol(0), gotHello(false)
|
: QObject(c), q(c), protocol(0), gotHello(false), device(0)
|
||||||
{
|
{
|
||||||
protocol = new QPacketProtocol(q, this);
|
protocol = new QPacketProtocol(q, this);
|
||||||
QObject::connect(c, SIGNAL(connected()), this, SLOT(connected()));
|
QObject::connect(c, SIGNAL(connected()), this, SLOT(connected()));
|
||||||
@@ -190,8 +195,15 @@ void QDeclarativeDebugConnectionPrivate::readyRead()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QDeclarativeDebugConnectionPrivate::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();
|
||||||
|
}
|
||||||
|
|
||||||
QDeclarativeDebugConnection::QDeclarativeDebugConnection(QObject *parent)
|
QDeclarativeDebugConnection::QDeclarativeDebugConnection(QObject *parent)
|
||||||
: QTcpSocket(parent), d(new QDeclarativeDebugConnectionPrivate(this))
|
: QIODevice(parent), d(new QDeclarativeDebugConnectionPrivate(this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,9 +218,112 @@ QDeclarativeDebugConnection::~QDeclarativeDebugConnection()
|
|||||||
|
|
||||||
bool QDeclarativeDebugConnection::isConnected() const
|
bool QDeclarativeDebugConnection::isConnected() const
|
||||||
{
|
{
|
||||||
return state() == ConnectedState;
|
return state() == QAbstractSocket::ConnectedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qint64 QDeclarativeDebugConnection::readData(char *data, qint64 maxSize)
|
||||||
|
{
|
||||||
|
return d->device->read(data, maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QDeclarativeDebugConnection::writeData(const char *data, qint64 maxSize)
|
||||||
|
{
|
||||||
|
return d->device->write(data, maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QDeclarativeDebugConnection::bytesAvailable() const
|
||||||
|
{
|
||||||
|
return d->device->bytesAvailable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QDeclarativeDebugConnection::isSequential() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QDeclarativeDebugConnection::close()
|
||||||
|
{
|
||||||
|
if (isOpen()) {
|
||||||
|
QIODevice::close();
|
||||||
|
d->device->close();
|
||||||
|
emit stateChanged(QAbstractSocket::UnconnectedState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For ease of refactoring we use QAbstractSocket's states even if we're actually using a OstChannel underneath
|
||||||
|
// since serial ports have a subset of the socket states afaics
|
||||||
|
QAbstractSocket::SocketState QDeclarativeDebugConnection::state() const
|
||||||
|
{
|
||||||
|
QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device);
|
||||||
|
if (socket)
|
||||||
|
return socket->state();
|
||||||
|
|
||||||
|
SymbianUtils::OstChannel *ost = qobject_cast<SymbianUtils::OstChannel*>(d->device);
|
||||||
|
if (ost) {
|
||||||
|
//TODO we need some handshaking here
|
||||||
|
/*
|
||||||
|
if (ost->hasReceivedData())
|
||||||
|
return QAbstractSocket::ConnectedState;
|
||||||
|
else if (ost->isOpen())
|
||||||
|
return QAbstractSocket::ConnectingState;
|
||||||
|
*/
|
||||||
|
if (ost->isOpen()) return QAbstractSocket::ConnectedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QAbstractSocket::UnconnectedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QDeclarativeDebugConnection::flush()
|
||||||
|
{
|
||||||
|
QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device);
|
||||||
|
if (socket) {
|
||||||
|
socket->flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbianUtils::OstChannel *ost = qobject_cast<SymbianUtils::OstChannel*>(d->device);
|
||||||
|
if (ost) {
|
||||||
|
ost->flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QDeclarativeDebugConnection::connectToHost(const QString &hostName, quint16 port)
|
||||||
|
{
|
||||||
|
QTcpSocket *socket = new QTcpSocket(d);
|
||||||
|
d->device = socket;
|
||||||
|
d->connectDeviceSignals();
|
||||||
|
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 QDeclarativeDebugConnection::connectToOst(const QString &port)
|
||||||
|
{
|
||||||
|
SymbianUtils::OstChannel *ost = SymbianUtils::SymbianDeviceManager::instance()->getOstChannel(port, KQmlOstProtocolId);
|
||||||
|
if (ost) {
|
||||||
|
ost->setParent(d);
|
||||||
|
d->device = ost;
|
||||||
|
d->connectDeviceSignals();
|
||||||
|
QIODevice::open(ReadWrite | Unbuffered);
|
||||||
|
emit stateChanged(QAbstractSocket::ConnectedState);
|
||||||
|
emit connected();
|
||||||
|
} else {
|
||||||
|
emit error(QAbstractSocket::HostNotFoundError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QDeclarativeDebugConnectionPrivate::connectDeviceSignals()
|
||||||
|
{
|
||||||
|
connect(device, SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64)));
|
||||||
|
connect(device, SIGNAL(readyRead()), q, SIGNAL(readyRead()));
|
||||||
|
connect(device, SIGNAL(aboutToClose()), this, SLOT(deviceAboutToClose()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
QDeclarativeDebugClientPrivate::QDeclarativeDebugClientPrivate()
|
QDeclarativeDebugClientPrivate::QDeclarativeDebugClientPrivate()
|
||||||
: connection(0)
|
: connection(0)
|
||||||
{
|
{
|
||||||
|
@@ -49,7 +49,7 @@ QT_BEGIN_HEADER
|
|||||||
namespace QmlJsDebugClient {
|
namespace QmlJsDebugClient {
|
||||||
|
|
||||||
class QDeclarativeDebugConnectionPrivate;
|
class QDeclarativeDebugConnectionPrivate;
|
||||||
class QDeclarativeDebugConnection : public QTcpSocket
|
class QDeclarativeDebugConnection : public QIODevice
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DISABLE_COPY(QDeclarativeDebugConnection)
|
Q_DISABLE_COPY(QDeclarativeDebugConnection)
|
||||||
@@ -57,7 +57,25 @@ public:
|
|||||||
QDeclarativeDebugConnection(QObject * = 0);
|
QDeclarativeDebugConnection(QObject * = 0);
|
||||||
~QDeclarativeDebugConnection();
|
~QDeclarativeDebugConnection();
|
||||||
|
|
||||||
|
void connectToHost(const QString &hostName, quint16 port);
|
||||||
|
void connectToOst(const QString &port);
|
||||||
|
|
||||||
|
qint64 bytesAvailable() const;
|
||||||
bool isConnected() const;
|
bool isConnected() const;
|
||||||
|
QAbstractSocket::SocketState state() const;
|
||||||
|
void flush();
|
||||||
|
bool isSequential() const;
|
||||||
|
void close();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void connected();
|
||||||
|
void stateChanged(QAbstractSocket::SocketState socketState);
|
||||||
|
void error(QAbstractSocket::SocketError socketError);
|
||||||
|
|
||||||
|
private:
|
||||||
|
qint64 readData(char *data, qint64 maxSize);
|
||||||
|
qint64 writeData(const char *data, qint64 maxSize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QDeclarativeDebugConnectionPrivate *d;
|
QDeclarativeDebugConnectionPrivate *d;
|
||||||
friend class QDeclarativeDebugClient;
|
friend class QDeclarativeDebugClient;
|
||||||
|
@@ -100,7 +100,7 @@ void QmlAdapter::closeConnection()
|
|||||||
d->m_connectionTimer.stop();
|
d->m_connectionTimer.stop();
|
||||||
} else {
|
} else {
|
||||||
if (d->m_conn) {
|
if (d->m_conn) {
|
||||||
d->m_conn->disconnectFromHost();
|
d->m_conn->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,11 +127,23 @@ void QmlAdapter::connectToViewer()
|
|||||||
|| (d->m_conn && d->m_conn->state() != QAbstractSocket::UnconnectedState))
|
|| (d->m_conn && d->m_conn->state() != QAbstractSocket::UnconnectedState))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString address = d->m_engine.data()->startParameters().qmlServerAddress;
|
const DebuggerStartParameters ¶meters = d->m_engine.data()->startParameters();
|
||||||
quint16 port = d->m_engine.data()->startParameters().qmlServerPort;
|
if (parameters.communicationChannel == DebuggerStartParameters::CommunicationChannelUsb) {
|
||||||
showConnectionStatusMessage(
|
if (parameters.debugClient == DebuggerStartParameters::DebugClientTrk) {
|
||||||
tr("Connect to debug server %1:%2").arg(address).arg(QString::number(port)));
|
d->m_connectionTimer.stop();
|
||||||
d->m_conn->connectToHost(address, port);
|
showConnectionErrorMessage(tr("QML debugging is not supported when using TRK!"));
|
||||||
|
emit connectionStartupFailed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QString &port = parameters.remoteChannel;
|
||||||
|
showConnectionStatusMessage(tr("Connecting to debug server on %1").arg(port));
|
||||||
|
d->m_conn->connectToOst(port);
|
||||||
|
} else {
|
||||||
|
const QString &address = parameters.qmlServerAddress;
|
||||||
|
quint16 port = parameters.qmlServerPort;
|
||||||
|
showConnectionStatusMessage(tr("Connecting to debug server %1:%2").arg(address).arg(QString::number(port)));
|
||||||
|
d->m_conn->connectToHost(address, port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlAdapter::sendMessage(const QByteArray &msg)
|
void QmlAdapter::sendMessage(const QByteArray &msg)
|
||||||
@@ -147,7 +159,7 @@ void QmlAdapter::sendMessage(const QByteArray &msg)
|
|||||||
void QmlAdapter::connectionErrorOccurred(QAbstractSocket::SocketError socketError)
|
void QmlAdapter::connectionErrorOccurred(QAbstractSocket::SocketError socketError)
|
||||||
{
|
{
|
||||||
showConnectionStatusMessage(tr("Error: (%1) %2", "%1=error code, %2=error message")
|
showConnectionStatusMessage(tr("Error: (%1) %2", "%1=error code, %2=error message")
|
||||||
.arg(d->m_conn->error()).arg(d->m_conn->errorString()));
|
.arg(socketError).arg(d->m_conn->errorString()));
|
||||||
|
|
||||||
// this is only an error if we are already connected and something goes wrong.
|
// this is only an error if we are already connected and something goes wrong.
|
||||||
if (isConnected())
|
if (isConnected())
|
||||||
|
@@ -465,6 +465,13 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR
|
|||||||
sp.serverAddress = activeDeployConf->deviceAddress();
|
sp.serverAddress = activeDeployConf->deviceAddress();
|
||||||
sp.serverPort = activeDeployConf->devicePort().toInt();
|
sp.serverPort = activeDeployConf->devicePort().toInt();
|
||||||
sp.displayName = rc->displayName();
|
sp.displayName = rc->displayName();
|
||||||
|
sp.qmlServerPort = rc->qmlDebugServerPort();
|
||||||
|
// TODO - is this the correct place to put this?
|
||||||
|
if (rc->useQmlDebugger()) {
|
||||||
|
if (sp.processArgs.length())
|
||||||
|
sp.processArgs.prepend(" ");
|
||||||
|
sp.processArgs.prepend(QString("-qmljsdebugger=port:%1").arg(sp.qmlServerPort));
|
||||||
|
}
|
||||||
|
|
||||||
sp.communicationChannel = activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection?
|
sp.communicationChannel = activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection?
|
||||||
Debugger::DebuggerStartParameters::CommunicationChannelTcpIp:
|
Debugger::DebuggerStartParameters::CommunicationChannelTcpIp:
|
||||||
|
Reference in New Issue
Block a user