QDBusConnection::registorObject with interface
Currently QDBus relies on a key in QMetaClassInfo to understand the DBus interface name. This patch allows QDBus to also use a specified interface name in the registerObject call instead of relying on QMetaClassInfo that might not be there (if the QObject was created in QML or Javascript for example). Change-Id: Ie02b2c67e7deb07f43e35eb166c11833fcbf38f3 Task-number: QTBUG-44074 Reviewed-by: Kevron Rees <kevron.m.rees@intel.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
06ecd74db1
commit
0eec8c86b6
@ -761,6 +761,26 @@ bool QDBusConnection::disconnect(const QString &service, const QString &path, co
|
||||
was registered with QDBusConnection::ExportChildObjects.
|
||||
*/
|
||||
bool QDBusConnection::registerObject(const QString &path, QObject *object, RegisterOptions options)
|
||||
{
|
||||
return registerObject(path, QString(), object, options);
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\since 5.5
|
||||
|
||||
Registers the object \a object at path \a path with interface name \a interface
|
||||
and returns \c true if the registration was successful. The \a options parameter
|
||||
specifies how much of the object \a object will be exposed through
|
||||
D-Bus.
|
||||
|
||||
This function does not replace existing objects: if there is already an object registered at
|
||||
path \a path, this function will return false. Use unregisterObject() to unregister it first.
|
||||
|
||||
You cannot register an object as a child object of an object that
|
||||
was registered with QDBusConnection::ExportChildObjects.
|
||||
*/
|
||||
bool QDBusConnection::registerObject(const QString &path, const QString &interface, QObject *object, RegisterOptions options)
|
||||
{
|
||||
Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), "QDBusConnection::registerObject",
|
||||
"Invalid object path given");
|
||||
@ -793,6 +813,7 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis
|
||||
// we can add the object here
|
||||
node->obj = object;
|
||||
node->flags = options;
|
||||
node->interfaceName = interface;
|
||||
|
||||
d->registerObject(node);
|
||||
//qDebug("REGISTERED FOR %s", path.toLocal8Bit().constData());
|
||||
|
@ -161,6 +161,8 @@ public:
|
||||
|
||||
bool registerObject(const QString &path, QObject *object,
|
||||
RegisterOptions options = ExportAdaptors);
|
||||
bool registerObject(const QString &path, const QString &interface, QObject *object,
|
||||
RegisterOptions options = ExportAdaptors);
|
||||
void unregisterObject(const QString &path, UnregisterMode mode = UnregisterNode);
|
||||
QObject *objectRegisteredAt(const QString &path) const;
|
||||
|
||||
|
@ -152,6 +152,7 @@ public:
|
||||
{ return obj || !children.isEmpty(); }
|
||||
|
||||
QString name;
|
||||
QString interfaceName;
|
||||
union {
|
||||
QObject *obj;
|
||||
QDBusVirtualObject *treeNode;
|
||||
|
@ -1481,8 +1481,12 @@ void QDBusConnectionPrivate::activateObject(ObjectTreeNode &node, const QDBusMes
|
||||
if (node.flags & (QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportNonScriptableSlots) ||
|
||||
node.flags & (QDBusConnection::ExportScriptableInvokables|QDBusConnection::ExportNonScriptableInvokables)) {
|
||||
bool interfaceFound = true;
|
||||
if (!msg.interface().isEmpty())
|
||||
interfaceFound = qDBusInterfaceInObject(node.obj, msg.interface());
|
||||
if (!msg.interface().isEmpty()) {
|
||||
if (!node.interfaceName.isEmpty())
|
||||
interfaceFound = msg.interface() == node.interfaceName;
|
||||
else
|
||||
interfaceFound = qDBusInterfaceInObject(node.obj, msg.interface());
|
||||
}
|
||||
|
||||
if (interfaceFound) {
|
||||
if (!activateCall(node.obj, node.flags, msg))
|
||||
|
@ -134,7 +134,7 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node
|
||||
// create XML for the object itself
|
||||
const QMetaObject *mo = node.obj->metaObject();
|
||||
for ( ; mo != &QObject::staticMetaObject; mo = mo->superClass())
|
||||
xml_data += qDBusGenerateMetaObjectXml(QString(), mo, mo->superClass(),
|
||||
xml_data += qDBusGenerateMetaObjectXml(node.interfaceName, mo, mo->superClass(),
|
||||
node.flags);
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,27 @@ void MyObject::method(const QDBusMessage &msg)
|
||||
//qDebug() << msg;
|
||||
}
|
||||
|
||||
class MyObjectWithoutInterface: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
void method(const QDBusMessage &msg);
|
||||
|
||||
public:
|
||||
static QString path;
|
||||
static QString interface;
|
||||
int callCount;
|
||||
MyObjectWithoutInterface(QObject *parent = 0) : QObject(parent), callCount(0) {}
|
||||
};
|
||||
|
||||
void MyObjectWithoutInterface::method(const QDBusMessage &msg)
|
||||
{
|
||||
path = msg.path();
|
||||
interface = msg.interface();
|
||||
++callCount;
|
||||
//qDebug() << msg;
|
||||
}
|
||||
|
||||
class tst_QDBusConnection: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -87,6 +108,8 @@ private slots:
|
||||
|
||||
void registerObject_data();
|
||||
void registerObject();
|
||||
void registerObjectWithInterface_data();
|
||||
void registerObjectWithInterface();
|
||||
void registerObjectPeer_data();
|
||||
void registerObjectPeer();
|
||||
void registerObject2();
|
||||
@ -112,6 +135,7 @@ private slots:
|
||||
public:
|
||||
QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
|
||||
bool callMethod(const QDBusConnection &conn, const QString &path);
|
||||
bool callMethod(const QDBusConnection &conn, const QString &path, const QString &interface);
|
||||
bool callMethodPeer(const QDBusConnection &conn, const QString &path);
|
||||
};
|
||||
|
||||
@ -379,6 +403,40 @@ void tst_QDBusConnection::registerObject()
|
||||
QVERIFY(!callMethod(con, path));
|
||||
}
|
||||
|
||||
void tst_QDBusConnection::registerObjectWithInterface_data()
|
||||
{
|
||||
QTest::addColumn<QString>("path");
|
||||
QTest::addColumn<QString>("interface");
|
||||
|
||||
QTest::newRow("/") << "/" << "org.foo";
|
||||
QTest::newRow("/p1") << "/p1" << "org.foo";
|
||||
QTest::newRow("/p2") << "/p2" << "org.foo";
|
||||
QTest::newRow("/p1/q") << "/p1/q" << "org.foo";
|
||||
QTest::newRow("/p1/q/r") << "/p1/q/r" << "org.foo";
|
||||
|
||||
}
|
||||
|
||||
void tst_QDBusConnection::registerObjectWithInterface()
|
||||
{
|
||||
QFETCH(QString, path);
|
||||
QFETCH(QString, interface);
|
||||
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
{
|
||||
// register one object at root:
|
||||
MyObjectWithoutInterface obj;
|
||||
QVERIFY(con.registerObject(path, interface, &obj, QDBusConnection::ExportAllSlots));
|
||||
QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
|
||||
QVERIFY(callMethod(con, path, interface));
|
||||
QCOMPARE(obj.path, path);
|
||||
QCOMPARE(obj.interface, interface);
|
||||
}
|
||||
// make sure it's gone
|
||||
QVERIFY(!callMethod(con, path, interface));
|
||||
}
|
||||
|
||||
class MyServer : public QDBusServer
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -844,6 +902,16 @@ bool tst_QDBusConnection::callMethod(const QDBusConnection &conn, const QString
|
||||
return (MyObject::path == path);
|
||||
}
|
||||
|
||||
bool tst_QDBusConnection::callMethod(const QDBusConnection &conn, const QString &path, const QString &interface)
|
||||
{
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(conn.baseService(), path, interface, "method");
|
||||
QDBusMessage reply = conn.call(msg, QDBus::Block/*WithGui*/);
|
||||
if (reply.type() != QDBusMessage::ReplyMessage)
|
||||
return false;
|
||||
QTest::qCompare(MyObjectWithoutInterface::path, path, "MyObjectWithoutInterface::path", "path", __FILE__, __LINE__);
|
||||
return (MyObjectWithoutInterface::path == path) && MyObjectWithoutInterface::interface == interface;
|
||||
}
|
||||
|
||||
bool tst_QDBusConnection::callMethodPeer(const QDBusConnection &conn, const QString &path)
|
||||
{
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall("", path, "", "method");
|
||||
@ -1307,6 +1375,8 @@ void tst_QDBusConnection::callVirtualObjectLocal()
|
||||
}
|
||||
|
||||
QString MyObject::path;
|
||||
QString MyObjectWithoutInterface::path;
|
||||
QString MyObjectWithoutInterface::interface;
|
||||
QTEST_MAIN(tst_QDBusConnection)
|
||||
|
||||
#include "tst_qdbusconnection.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user