summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dbus/dbus.pro6
-rw-r--r--src/dbus/qdbusconnection.cpp52
-rw-r--r--src/dbus/qdbusconnection.h16
-rw-r--r--src/dbus/qdbusconnection_p.h13
-rw-r--r--src/dbus/qdbusintegrator.cpp18
-rw-r--r--src/dbus/qdbusinternalfilters.cpp8
-rw-r--r--src/dbus/qdbusvirtualobject.cpp97
-rw-r--r--src/dbus/qdbusvirtualobject.h81
8 files changed, 282 insertions, 9 deletions
diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro
index c91c2f6ad7..8669bb003a 100644
--- a/src/dbus/dbus.pro
+++ b/src/dbus/dbus.pro
@@ -52,7 +52,8 @@ PUB_HEADERS = qdbusargument.h \
qdbusmetatype.h \
qdbuspendingcall.h \
qdbuspendingreply.h \
- qdbuscontext.h
+ qdbuscontext.h \
+ qdbusvirtualobject.h
HEADERS += $$PUB_HEADERS \
qdbusconnection_p.h \
qdbusmessage_p.h \
@@ -95,4 +96,5 @@ SOURCES += qdbusconnection.cpp \
qdbuspendingreply.cpp \
qdbus_symbols.cpp \
qdbusservicewatcher.cpp \
- qdbusunixfiledescriptor.cpp
+ qdbusunixfiledescriptor.cpp \
+ qdbusvirtualobject.cpp
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 9656903846..a55ff14fcf 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -222,6 +222,18 @@ void QDBusConnectionManager::setConnection(const QString &name, QDBusConnectionP
*/
/*!
+ \internal
+ \since 4.8
+ \enum QDBusConnection::VirtualObjectRegisterOption
+ Specifies the options for registering virtual objects with the connection. The possible values are:
+
+ \value SingleNode register a virtual object to handle one path only
+ \value SubPath register a virtual object so that it handles all sub paths
+
+ \sa registerVirtualObject(), QDBusVirtualObject
+*/
+
+/*!
\enum QDBusConnection::UnregisterMode
The mode for unregistering an object path:
@@ -801,9 +813,21 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis
// this node exists
// consider it free if there's no object here and the user is not trying to
// replace the object sub-tree
- if ((options & ExportChildObjects && !node->children.isEmpty()) || node->obj)
+ if (node->obj)
return false;
+ if (options & QDBusConnectionPrivate::VirtualObject) {
+ // technically the check for children needs to go even deeper
+ if (options & SubPath) {
+ foreach (const QDBusConnectionPrivate::ObjectTreeNode &child, node->children) {
+ if (child.obj)
+ return false;
+ }
+ }
+ } else {
+ if ((options & ExportChildObjects && !node->children.isEmpty()))
+ return false;
+ }
// we can add the object here
node->obj = object;
node->flags = options;
@@ -813,6 +837,13 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis
return true;
}
+ // if a virtual object occupies this path, return false
+ if (node->obj && (node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath)) {
+ qDebug("Cannot register object at %s because QDBusVirtualObject handles all sub-paths.",
+ qPrintable(path));
+ return false;
+ }
+
// find the position where we'd insert the node
QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it =
qLowerBound(node->children.begin(), node->children.end(), pathComponents.at(i));
@@ -841,6 +872,21 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis
}
/*!
+ \internal
+ \since 4.8
+ Registers a QDBusTreeNode for a path. It can handle a path including all child paths, thus
+ handling multiple DBus nodes.
+
+ To unregister a QDBusTreeNode use the unregisterObject() function with its path.
+*/
+bool QDBusConnection::registerVirtualObject(const QString &path, QDBusVirtualObject *treeNode,
+ VirtualObjectRegisterOption options)
+{
+ int opts = options | QDBusConnectionPrivate::VirtualObject;
+ return registerObject(path, (QObject*) treeNode, (RegisterOptions) opts);
+}
+
+/*!
Unregisters an object that was registered with the registerObject() at the object path given by
\a path and, if \a mode is QDBusConnection::UnregisterTree, all of its sub-objects too.
@@ -905,6 +951,8 @@ QObject *QDBusConnection::objectRegisteredAt(const QString &path) const
while (node) {
if (pathComponents.count() == i)
return node->obj;
+ if ((node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath))
+ return node->obj;
QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator it =
qLowerBound(node->children.constBegin(), node->children.constEnd(), pathComponents.at(i));
@@ -917,6 +965,8 @@ QObject *QDBusConnection::objectRegisteredAt(const QString &path) const
return 0;
}
+
+
/*!
Returns a QDBusConnectionInterface object that represents the
D-Bus server interface on this connection.
diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h
index 4bdd055f52..8b126af77e 100644
--- a/src/dbus/qdbusconnection.h
+++ b/src/dbus/qdbusconnection.h
@@ -69,6 +69,7 @@ class QDBusError;
class QDBusMessage;
class QDBusPendingCall;
class QDBusConnectionInterface;
+class QDBusVirtualObject;
class QObject;
class QDBusConnectionPrivate;
@@ -104,8 +105,8 @@ public:
// Qt 4.2 had a misspelling here
ExportAllSignal = ExportAllSignals,
#endif
-
ExportChildObjects = 0x1000
+ // Reserved = 0xff000000
};
enum UnregisterMode {
UnregisterNode,
@@ -113,6 +114,15 @@ public:
};
Q_DECLARE_FLAGS(RegisterOptions, RegisterOption)
+ enum VirtualObjectRegisterOption {
+ SingleNode = 0x0,
+ SubPath = 0x1
+ // Reserved = 0xff000000
+ };
+#ifndef Q_QDOC
+ Q_DECLARE_FLAGS(VirtualObjectRegisterOptions, VirtualObjectRegisterOption)
+#endif
+
enum ConnectionCapability {
UnixFileDescriptorPassing = 0x0001
};
@@ -163,6 +173,9 @@ public:
void unregisterObject(const QString &path, UnregisterMode mode = UnregisterNode);
QObject *objectRegisteredAt(const QString &path) const;
+ bool registerVirtualObject(const QString &path, QDBusVirtualObject *object,
+ VirtualObjectRegisterOption options = SingleNode);
+
bool registerService(const QString &serviceName);
bool unregisterService(const QString &serviceName);
@@ -192,6 +205,7 @@ private:
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusConnection::RegisterOptions)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusConnection::VirtualObjectRegisterOptions)
QT_END_NAMESPACE
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index 12bcb21d9f..d481cf16ba 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -129,6 +129,11 @@ public:
QByteArray matchRule;
};
+ enum TreeNodeType {
+ Object = 0x0,
+ VirtualObject = 0x01000000
+ };
+
struct ObjectTreeNode
{
typedef QVector<ObjectTreeNode> DataList;
@@ -143,8 +148,12 @@ public:
{ return QStringRef(&name) < other; }
QString name;
- QObject* obj;
+ union {
+ QObject *obj;
+ QDBusVirtualObject *treeNode;
+ };
int flags;
+
DataList children;
};
@@ -333,7 +342,7 @@ extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name);
extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo);
// in qdbusinternalfilters.cpp
-extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node);
+extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node, const QString &path);
extern QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node,
const QDBusMessage &msg);
extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node,
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index f3f3d0b8b2..2cde07ea47 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -57,6 +57,7 @@
#include "qdbusabstractadaptor.h"
#include "qdbusabstractadaptor_p.h"
#include "qdbusutil_p.h"
+#include "qdbusvirtualobject.h"
#include "qdbusmessage_p.h"
#include "qdbuscontext_p.h"
#include "qdbuspendingcall_p.h"
@@ -442,7 +443,11 @@ static bool findObject(const QDBusConnectionPrivate::ObjectTreeNode *root,
// walk the object tree
const QDBusConnectionPrivate::ObjectTreeNode *node = root;
- while (start < length && node && !(node->flags & QDBusConnection::ExportChildObjects)) {
+ while (start < length && node) {
+ if (node->flags & QDBusConnection::ExportChildObjects)
+ break;
+ if ((node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath))
+ break;
int end = fullpath.indexOf(QLatin1Char('/'), start);
end = (end == -1 ? length : end);
QStringRef pathComponent(&fullpath, start, end - start);
@@ -1328,7 +1333,7 @@ bool QDBusConnectionPrivate::activateInternalFilters(const ObjectTreeNode &node,
if (interface.isEmpty() || interface == QLatin1String(DBUS_INTERFACE_INTROSPECTABLE)) {
if (msg.member() == QLatin1String("Introspect") && msg.signature().isEmpty()) {
//qDebug() << "QDBusConnectionPrivate::activateInternalFilters introspect" << msg.d_ptr->msg;
- QDBusMessage reply = msg.createReply(qDBusIntrospectObject(node));
+ QDBusMessage reply = msg.createReply(qDBusIntrospectObject(node, msg.path()));
send(reply);
return true;
}
@@ -1375,6 +1380,15 @@ void QDBusConnectionPrivate::activateObject(ObjectTreeNode &node, const QDBusMes
// object may be null
+ if (node.flags & QDBusConnectionPrivate::VirtualObject) {
+ if (node.treeNode->handleMessage(msg, q(this))) {
+ return;
+ } else {
+ if (activateInternalFilters(node, msg))
+ return;
+ }
+ }
+
if (pathStartPos != msg.path().length()) {
node.flags &= ~QDBusConnection::ExportAllSignals;
node.obj = findChildObject(&node, msg.path(), pathStartPos);
diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp
index 2b142a72b8..b874a64644 100644
--- a/src/dbus/qdbusinternalfilters.cpp
+++ b/src/dbus/qdbusinternalfilters.cpp
@@ -56,6 +56,7 @@
#include "qdbusmetatype_p.h"
#include "qdbusmessage_p.h"
#include "qdbusutil_p.h"
+#include "qdbusvirtualobject.h"
#ifndef QT_NO_DBUS
@@ -108,7 +109,7 @@ static QString generateSubObjectXml(QObject *object)
// declared as extern in qdbusconnection_p.h
-QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node)
+QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node, const QString &path)
{
// object may be null
@@ -155,6 +156,11 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node
}
}
+ // is it a virtual node that handles introspection itself?
+ if (node.flags & QDBusConnectionPrivate::VirtualObject) {
+ xml_data += node.treeNode->introspect(path);
+ }
+
xml_data += QLatin1String( propertiesInterfaceXml );
}
diff --git a/src/dbus/qdbusvirtualobject.cpp b/src/dbus/qdbusvirtualobject.cpp
new file mode 100644
index 0000000000..992ccbf229
--- /dev/null
+++ b/src/dbus/qdbusvirtualobject.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDBus module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdbusvirtualobject.h"
+
+#ifndef QT_NO_DBUS
+
+QT_BEGIN_NAMESPACE
+
+QDBusVirtualObject::QDBusVirtualObject(QObject *parent) :
+ QObject(parent)
+{
+}
+
+QDBusVirtualObject::~QDBusVirtualObject()
+{
+}
+
+QT_END_NAMESPACE
+
+
+/*!
+ \internal
+ \class QDBusVirtualObject
+ \inmodule QtDBus
+ \since 4.8
+
+ \brief The QDBusVirtualObject class is used to handle several DBus paths with one class.
+*/
+
+/*!
+ \internal
+ \fn bool QDBusVirtualObject::handleMessage(const QDBusMessage &message, const QDBusConnection &connection) = 0
+
+ This function needs to handle all messages to the path of the
+ virtual object, when the SubPath option is specified.
+ The service, path, interface and methos are all part of the message.
+ Must return true when the message is handled, otherwise false (will generate dbus error message).
+*/
+
+
+/*!
+ \internal
+ \fn QString QDBusVirtualObject::introspect(const QString &path) const
+
+ This function needs to handle the introspection of the
+ virtual object. It must return xml of the form:
+
+ \code
+<interface name="com.trolltech.QtDBus.MyObject" >
+ <property access="readwrite" type="i" name="prop1" />
+</interface>
+ \endcode
+
+ If you pass the SubPath option, this introspection has to include all child nodes.
+ Otherwise QDBus handles the introspection of the child nodes.
+*/
+
+#endif // QT_NO_DBUS
diff --git a/src/dbus/qdbusvirtualobject.h b/src/dbus/qdbusvirtualobject.h
new file mode 100644
index 0000000000..be323de720
--- /dev/null
+++ b/src/dbus/qdbusvirtualobject.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDBus module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDBUSTREENODE_H
+#define QDBUSTREENODE_H
+
+#include <QtDBus/qdbusmacros.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qobject.h>
+
+#ifndef QT_NO_DBUS
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(DBus)
+
+class QDBusMessage;
+class QDBusConnection;
+
+class QDBusVirtualObjectPrivate;
+class Q_DBUS_EXPORT QDBusVirtualObject : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QDBusVirtualObject(QObject *parent = 0);
+ virtual ~QDBusVirtualObject();
+
+ virtual QString introspect(const QString &path) const = 0;
+ virtual bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) = 0;
+
+private:
+ Q_DECLARE_PRIVATE(QDBusVirtualObject)
+ Q_DISABLE_COPY(QDBusVirtualObject)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_DBUS
+#endif