QDBusServiceWatcher namespace prefix support
This allows a user to efficiently watch for services with a common domain prefix. This is exposed in the API via a wildcard character in the service name. For example creating a watcher on "org.mpris*" will match "org.mpris.foo" "org.mpris.bar" and "org.mpris" itself. It will not match org.mprisasdf. Internally the argument match rules have been expanded from a single QStringList to a struct containing args and arg0namespace. This was done so that we can easily use argpath in match rules in the future. Change-Id: I55882ab603cc6ba478e8c0ea9a6800f6e483a50c Reviewed-by: Kai Uwe Broulik <kde@privat.broulik.de> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
parent
fc88dd52a4
commit
d761c62783
@ -121,6 +121,15 @@ public:
|
||||
QSocketNotifier *write;
|
||||
};
|
||||
|
||||
struct ArgMatchRules {
|
||||
QStringList args;
|
||||
QString arg0namespace;
|
||||
bool operator==(const ArgMatchRules &other) const {
|
||||
return args == other.args &&
|
||||
arg0namespace == other.arg0namespace;
|
||||
}
|
||||
};
|
||||
|
||||
struct SignalHook
|
||||
{
|
||||
inline SignalHook() : obj(0), midx(-1) { }
|
||||
@ -128,7 +137,7 @@ public:
|
||||
QObject* obj;
|
||||
int midx;
|
||||
QVector<int> params;
|
||||
QStringList argumentMatch;
|
||||
ArgMatchRules argumentMatch;
|
||||
QByteArray matchRule;
|
||||
};
|
||||
|
||||
@ -207,12 +216,19 @@ public:
|
||||
QDBusMessage sendWithReplyLocal(const QDBusMessage &message);
|
||||
QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
|
||||
const char *returnMethod, const char *errorMethod,int timeout = -1);
|
||||
|
||||
bool connectSignal(const QString &service, const QString &path, const QString& interface,
|
||||
const QString &name, const QStringList &argumentMatch, const QString &signature,
|
||||
QObject *receiver, const char *slot);
|
||||
bool disconnectSignal(const QString &service, const QString &path, const QString& interface,
|
||||
const QString &name, const QStringList &argumentMatch, const QString &signature,
|
||||
QObject *receiver, const char *slot);
|
||||
bool connectSignal(const QString &service, const QString &path, const QString& interface,
|
||||
const QString &name, const ArgMatchRules &argumentMatch, const QString &signature,
|
||||
QObject *receiver, const char *slot);
|
||||
bool disconnectSignal(const QString &service, const QString &path, const QString& interface,
|
||||
const QString &name, const ArgMatchRules &argumentMatch, const QString &signature,
|
||||
QObject *receiver, const char *slot);
|
||||
void registerObject(const ObjectTreeNode *node);
|
||||
void unregisterObject(const QString &path, QDBusConnection::UnregisterMode mode);
|
||||
void connectRelay(const QString &service,
|
||||
@ -332,7 +348,7 @@ public:
|
||||
static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
|
||||
const QString &service,
|
||||
const QString &path, const QString &interface, const QString &name,
|
||||
const QStringList &argMatch,
|
||||
const ArgMatchRules &argMatch,
|
||||
QObject *receiver, const char *signal, int minMIdx,
|
||||
bool buildSignature);
|
||||
static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *);
|
||||
|
@ -338,7 +338,7 @@ void QDBusConnectionPrivate::_q_newConnection(QDBusConnectionPrivate *newConnect
|
||||
|
||||
static QByteArray buildMatchRule(const QString &service,
|
||||
const QString &objectPath, const QString &interface,
|
||||
const QString &member, const QStringList &argMatch, const QString & /*signature*/)
|
||||
const QString &member, const QDBusConnectionPrivate::ArgMatchRules &argMatch, const QString & /*signature*/)
|
||||
{
|
||||
QString result = QLatin1String("type='signal',");
|
||||
QString keyValue = QLatin1String("%1='%2',");
|
||||
@ -353,11 +353,14 @@ static QByteArray buildMatchRule(const QString &service,
|
||||
result += keyValue.arg(QLatin1String("member"), member);
|
||||
|
||||
// add the argument string-matching now
|
||||
if (!argMatch.isEmpty()) {
|
||||
if (!argMatch.args.isEmpty()) {
|
||||
keyValue = QLatin1String("arg%1='%2',");
|
||||
for (int i = 0; i < argMatch.count(); ++i)
|
||||
if (!argMatch.at(i).isNull())
|
||||
result += keyValue.arg(i).arg(argMatch.at(i));
|
||||
for (int i = 0; i < argMatch.args.count(); ++i)
|
||||
if (!argMatch.args.at(i).isNull())
|
||||
result += keyValue.arg(i).arg(argMatch.args.at(i));
|
||||
}
|
||||
if (!argMatch.arg0namespace.isEmpty()) {
|
||||
result += QStringLiteral("arg0namespace='%1',").arg(argMatch.arg0namespace);
|
||||
}
|
||||
|
||||
result.chop(1); // remove ending comma
|
||||
@ -456,21 +459,26 @@ static QObject *findChildObject(const QDBusConnectionPrivate::ObjectTreeNode *ro
|
||||
return 0;
|
||||
}
|
||||
|
||||
static QStringList matchArgsForService(const QString &service, QDBusServiceWatcher::WatchMode mode)
|
||||
static QDBusConnectionPrivate::ArgMatchRules matchArgsForService(const QString &service, QDBusServiceWatcher::WatchMode mode)
|
||||
{
|
||||
QStringList matchArgs;
|
||||
matchArgs << service;
|
||||
QDBusConnectionPrivate::ArgMatchRules matchArgs;
|
||||
if (service.endsWith(QLatin1Char('*'))) {
|
||||
matchArgs.arg0namespace = service.chopped(1);
|
||||
matchArgs.args << QString();
|
||||
}
|
||||
else
|
||||
matchArgs.args << service;
|
||||
|
||||
switch (mode) {
|
||||
case QDBusServiceWatcher::WatchForOwnerChange:
|
||||
break;
|
||||
|
||||
case QDBusServiceWatcher::WatchForRegistration:
|
||||
matchArgs << QString::fromLatin1("", 0);
|
||||
matchArgs.args << QString::fromLatin1("", 0);
|
||||
break;
|
||||
|
||||
case QDBusServiceWatcher::WatchForUnregistration:
|
||||
matchArgs << QString() << QString::fromLatin1("", 0);
|
||||
matchArgs.args << QString() << QString::fromLatin1("", 0);
|
||||
break;
|
||||
}
|
||||
return matchArgs;
|
||||
@ -1310,7 +1318,7 @@ int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedN
|
||||
bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,
|
||||
const QString &service,
|
||||
const QString &path, const QString &interface, const QString &name,
|
||||
const QStringList &argMatch,
|
||||
const ArgMatchRules &argMatch,
|
||||
QObject *receiver, const char *signal, int minMIdx,
|
||||
bool buildSignature)
|
||||
{
|
||||
@ -1620,14 +1628,14 @@ void QDBusConnectionPrivate::handleSignal(const QString &key, const QDBusMessage
|
||||
continue;
|
||||
if (hook.signature.isEmpty() && !hook.signature.isNull() && !msg.signature().isEmpty())
|
||||
continue;
|
||||
if (!hook.argumentMatch.isEmpty()) {
|
||||
if (!hook.argumentMatch.args.isEmpty()) {
|
||||
const QVariantList arguments = msg.arguments();
|
||||
if (hook.argumentMatch.size() > arguments.size())
|
||||
if (hook.argumentMatch.args.size() > arguments.size())
|
||||
continue;
|
||||
|
||||
bool matched = true;
|
||||
for (int i = 0; i < hook.argumentMatch.size(); ++i) {
|
||||
const QString ¶m = hook.argumentMatch.at(i);
|
||||
for (int i = 0; i < hook.argumentMatch.args.size(); ++i) {
|
||||
const QString ¶m = hook.argumentMatch.args.at(i);
|
||||
if (param.isNull())
|
||||
continue; // don't try to match against this
|
||||
if (param == arguments.at(i).toString())
|
||||
@ -1638,7 +1646,15 @@ void QDBusConnectionPrivate::handleSignal(const QString &key, const QDBusMessage
|
||||
if (!matched)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hook.argumentMatch.arg0namespace.isEmpty()) {
|
||||
const QVariantList arguments = msg.arguments();
|
||||
if (arguments.size() < 1)
|
||||
continue;
|
||||
const QString param = arguments.at(0).toString();
|
||||
if (param != hook.argumentMatch.arg0namespace
|
||||
&& !param.startsWith(hook.argumentMatch.arg0namespace + QLatin1Char('.')))
|
||||
continue;
|
||||
}
|
||||
activateSignal(hook, msg);
|
||||
}
|
||||
}
|
||||
@ -2180,10 +2196,21 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void *
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool QDBusConnectionPrivate::connectSignal(const QString &service,
|
||||
const QString &path, const QString &interface, const QString &name,
|
||||
const QStringList &argumentMatch, const QString &signature,
|
||||
QObject *receiver, const char *slot)
|
||||
{
|
||||
ArgMatchRules rules;
|
||||
rules.args = argumentMatch;
|
||||
return connectSignal(service, path, interface, name, rules, signature, receiver, slot);
|
||||
}
|
||||
|
||||
bool QDBusConnectionPrivate::connectSignal(const QString &service,
|
||||
const QString &path, const QString &interface, const QString &name,
|
||||
const ArgMatchRules &argumentMatch, const QString &signature,
|
||||
QObject *receiver, const char *slot)
|
||||
{
|
||||
// check the slot
|
||||
QDBusConnectionPrivate::SignalHook hook;
|
||||
@ -2241,9 +2268,11 @@ bool QDBusConnectionPrivate::addSignalHook(const QString &key, const SignalHook
|
||||
WatchedServicesHash::mapped_type &data = watchedServices[hook.service];
|
||||
if (++data.refcount == 1) {
|
||||
// we need to watch for this service changing
|
||||
ArgMatchRules rules;
|
||||
rules.args << hook.service;
|
||||
q_dbus_bus_add_match(connection,
|
||||
buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(),
|
||||
QDBusUtil::nameOwnerChanged(), QStringList() << hook.service, QString()),
|
||||
QDBusUtil::nameOwnerChanged(), rules, QString()),
|
||||
NULL);
|
||||
data.owner = getNameOwnerNoCache(hook.service);
|
||||
qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:"
|
||||
@ -2255,9 +2284,19 @@ bool QDBusConnectionPrivate::addSignalHook(const QString &key, const SignalHook
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QDBusConnectionPrivate::disconnectSignal(const QString &service,
|
||||
const QString &path, const QString &interface, const QString &name,
|
||||
const QStringList &argumentMatch, const QString &signature,
|
||||
QObject *receiver, const char *slot)
|
||||
{
|
||||
ArgMatchRules rules;
|
||||
rules.args = argumentMatch;
|
||||
return disconnectSignal(service, path, interface, name, rules, signature, receiver, slot);
|
||||
}
|
||||
|
||||
bool QDBusConnectionPrivate::disconnectSignal(const QString &service,
|
||||
const QString &path, const QString &interface, const QString &name,
|
||||
const QStringList &argumentMatch, const QString &signature,
|
||||
const ArgMatchRules &argumentMatch, const QString &signature,
|
||||
QObject *receiver, const char *slot)
|
||||
{
|
||||
// check the slot
|
||||
@ -2288,7 +2327,7 @@ bool QDBusConnectionPrivate::removeSignalHook(const QString &key, const SignalHo
|
||||
entry.signature == hook.signature &&
|
||||
entry.obj == hook.obj &&
|
||||
entry.midx == hook.midx &&
|
||||
entry.argumentMatch == hook.argumentMatch) {
|
||||
entry.argumentMatch.args == hook.argumentMatch.args) {
|
||||
// no need to compare the parameters if it's the same slot
|
||||
removeSignalHookNoLock(it);
|
||||
return true; // it was there
|
||||
@ -2330,9 +2369,11 @@ QDBusConnectionPrivate::removeSignalHookNoLock(SignalHookHash::Iterator it)
|
||||
if (sit != watchedServices.end()) {
|
||||
if (--sit.value().refcount == 0) {
|
||||
watchedServices.erase(sit);
|
||||
ArgMatchRules rules;
|
||||
rules.args << hook.service;
|
||||
q_dbus_bus_remove_match(connection,
|
||||
buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(),
|
||||
QDBusUtil::nameOwnerChanged(), QStringList() << hook.service, QString()),
|
||||
QDBusUtil::nameOwnerChanged(), rules, QString()),
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
@ -2393,7 +2434,7 @@ void QDBusConnectionPrivate::connectRelay(const QString &service,
|
||||
QByteArray sig;
|
||||
sig.append(QSIGNAL_CODE + '0');
|
||||
sig.append(signal.methodSignature());
|
||||
if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, sig,
|
||||
if (!prepareHook(hook, key, service, path, interface, QString(), ArgMatchRules(), receiver, sig,
|
||||
QDBusAbstractInterface::staticMetaObject.methodCount(), true))
|
||||
return; // don't connect
|
||||
|
||||
@ -2414,7 +2455,7 @@ void QDBusConnectionPrivate::disconnectRelay(const QString &service,
|
||||
QByteArray sig;
|
||||
sig.append(QSIGNAL_CODE + '0');
|
||||
sig.append(signal.methodSignature());
|
||||
if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, sig,
|
||||
if (!prepareHook(hook, key, service, path, interface, QString(), ArgMatchRules(), receiver, sig,
|
||||
QDBusAbstractInterface::staticMetaObject.methodCount(), true))
|
||||
return; // don't disconnect
|
||||
|
||||
@ -2447,7 +2488,7 @@ bool QDBusConnectionPrivate::shouldWatchService(const QString &service)
|
||||
*/
|
||||
void QDBusConnectionPrivate::watchService(const QString &service, QDBusServiceWatcher::WatchMode mode, QObject *obj, const char *member)
|
||||
{
|
||||
QStringList matchArgs = matchArgsForService(service, mode);
|
||||
ArgMatchRules matchArgs = matchArgsForService(service, mode);
|
||||
connectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), QDBusUtil::nameOwnerChanged(),
|
||||
matchArgs, QString(), obj, member);
|
||||
}
|
||||
@ -2462,7 +2503,7 @@ void QDBusConnectionPrivate::watchService(const QString &service, QDBusServiceWa
|
||||
*/
|
||||
void QDBusConnectionPrivate::unwatchService(const QString &service, QDBusServiceWatcher::WatchMode mode, QObject *obj, const char *member)
|
||||
{
|
||||
QStringList matchArgs = matchArgsForService(service, mode);
|
||||
ArgMatchRules matchArgs = matchArgsForService(service, mode);
|
||||
disconnectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), QDBusUtil::nameOwnerChanged(),
|
||||
matchArgs, QString(), obj, member);
|
||||
}
|
||||
|
@ -139,6 +139,17 @@ void QDBusServiceWatcherPrivate::removeService(const QString &service)
|
||||
QDBusConnectionInterface::serviceOwnerChanged() signal because it allows
|
||||
one to receive only the signals for which the class is interested in.
|
||||
|
||||
Ending a service name with the character '*' will match all service names
|
||||
within the specified namespace.
|
||||
|
||||
For example "com.example.backend1*" will match
|
||||
\list
|
||||
\li com.example.backend1
|
||||
\li com.example.backend1.foo
|
||||
\li com.example.backend1.foo.bar
|
||||
\endlist
|
||||
Substrings in the same domain will not be matched, i.e "com.example.backend12".
|
||||
|
||||
\sa QDBusConnection
|
||||
*/
|
||||
|
||||
|
@ -34,22 +34,27 @@
|
||||
class tst_QDBusServiceWatcher: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QString serviceName;
|
||||
int testCounter;
|
||||
public:
|
||||
tst_QDBusServiceWatcher();
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void init();
|
||||
|
||||
void watchForCreation_data();
|
||||
void watchForCreation();
|
||||
void watchForDisappearance_data();
|
||||
void watchForDisappearance();
|
||||
void watchForDisappearanceUniqueConnection();
|
||||
void watchForOwnerChange_data();
|
||||
void watchForOwnerChange();
|
||||
void modeChange_data();
|
||||
void modeChange();
|
||||
void disconnectedConnection();
|
||||
void setConnection_data();
|
||||
void setConnection();
|
||||
|
||||
private:
|
||||
QString generateServiceName();
|
||||
};
|
||||
|
||||
tst_QDBusServiceWatcher::tst_QDBusServiceWatcher()
|
||||
@ -63,18 +68,45 @@ void tst_QDBusServiceWatcher::initTestCase()
|
||||
QVERIFY(con.isConnected());
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::init()
|
||||
QString tst_QDBusServiceWatcher::generateServiceName() {
|
||||
return "com.example.TestService" + QString::number(testCounter++);
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::watchForCreation_data()
|
||||
{
|
||||
// change the service name from test to test
|
||||
serviceName = "com.example.TestService" + QString::number(testCounter++);
|
||||
QTest::addColumn<QString>("watchedName");
|
||||
QTest::addColumn<QString>("registeredName");
|
||||
|
||||
//com.example.TestService5 matches com.example.TestService5
|
||||
QString name = generateServiceName();
|
||||
QTest::newRow("normal") << name << name;
|
||||
|
||||
//com.example* matches com.example.TestService5
|
||||
name = generateServiceName();
|
||||
QTest::newRow("wildcard") << "com.example*" << name;
|
||||
|
||||
//com.example.TestService5* matches com.example.TestService5
|
||||
name = generateServiceName();
|
||||
QTest::newRow("wildcard_exact") << name+"*" << name;
|
||||
|
||||
//com.example.TestService5* matches com.example.TestService5.Foo
|
||||
name = generateServiceName();
|
||||
QTest::newRow("wildcard_subdomain") << name+"*" << name + ".Foo";
|
||||
|
||||
//com.example.TestService5* matches com.example.TestService5.Foo.Bar
|
||||
name = generateServiceName();
|
||||
QTest::newRow("wildcard_subsubdomain") << name+"*" << name + ".Foo.Bar";
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::watchForCreation()
|
||||
{
|
||||
QFETCH(QString, watchedName);
|
||||
QFETCH(QString, registeredName);
|
||||
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration);
|
||||
QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForRegistration);
|
||||
|
||||
QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString)));
|
||||
QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString)));
|
||||
@ -82,18 +114,18 @@ void tst_QDBusServiceWatcher::watchForCreation()
|
||||
QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop()));
|
||||
|
||||
// register a name
|
||||
QVERIFY(con.registerService(serviceName));
|
||||
QVERIFY(con.registerService(registeredName));
|
||||
|
||||
QTestEventLoop::instance().enterLoop(1);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
|
||||
QCOMPARE(spyR.count(), 1);
|
||||
QCOMPARE(spyR.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyR.at(0).at(0).toString(), registeredName);
|
||||
|
||||
QCOMPARE(spyU.count(), 0);
|
||||
|
||||
QCOMPARE(spyO.count(), 1);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
|
||||
QVERIFY(spyO.at(0).at(1).toString().isEmpty());
|
||||
QCOMPARE(spyO.at(0).at(2).toString(), con.baseService());
|
||||
|
||||
@ -102,31 +134,39 @@ void tst_QDBusServiceWatcher::watchForCreation()
|
||||
spyO.clear();
|
||||
|
||||
// unregister it:
|
||||
con.unregisterService(serviceName);
|
||||
con.unregisterService(registeredName);
|
||||
|
||||
// and register again
|
||||
QVERIFY(con.registerService(serviceName));
|
||||
QVERIFY(con.registerService(registeredName));
|
||||
|
||||
QTestEventLoop::instance().enterLoop(1);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
|
||||
QCOMPARE(spyR.count(), 1);
|
||||
QCOMPARE(spyR.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyR.at(0).at(0).toString(), registeredName);
|
||||
|
||||
QCOMPARE(spyU.count(), 0);
|
||||
|
||||
QCOMPARE(spyO.count(), 1);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
|
||||
QVERIFY(spyO.at(0).at(1).toString().isEmpty());
|
||||
QCOMPARE(spyO.at(0).at(2).toString(), con.baseService());
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::watchForDisappearance_data()
|
||||
{
|
||||
tst_QDBusServiceWatcher::watchForCreation_data();
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::watchForDisappearance()
|
||||
{
|
||||
QFETCH(QString, watchedName);
|
||||
QFETCH(QString, registeredName);
|
||||
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForUnregistration);
|
||||
QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForUnregistration);
|
||||
watcher.setObjectName("watcher for disappearance");
|
||||
|
||||
QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString)));
|
||||
@ -135,10 +175,10 @@ void tst_QDBusServiceWatcher::watchForDisappearance()
|
||||
QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop()));
|
||||
|
||||
// register a name
|
||||
QVERIFY(con.registerService(serviceName));
|
||||
QVERIFY(con.registerService(registeredName));
|
||||
|
||||
// unregister it:
|
||||
con.unregisterService(serviceName);
|
||||
con.unregisterService(registeredName);
|
||||
|
||||
QTestEventLoop::instance().enterLoop(1);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
@ -146,10 +186,10 @@ void tst_QDBusServiceWatcher::watchForDisappearance()
|
||||
QCOMPARE(spyR.count(), 0);
|
||||
|
||||
QCOMPARE(spyU.count(), 1);
|
||||
QCOMPARE(spyU.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyU.at(0).at(0).toString(), registeredName);
|
||||
|
||||
QCOMPARE(spyO.count(), 1);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
|
||||
QCOMPARE(spyO.at(0).at(1).toString(), con.baseService());
|
||||
QVERIFY(spyO.at(0).at(2).toString().isEmpty());
|
||||
}
|
||||
@ -188,12 +228,20 @@ void tst_QDBusServiceWatcher::watchForDisappearanceUniqueConnection()
|
||||
QVERIFY(spyO.at(0).at(2).toString().isEmpty());
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::watchForOwnerChange_data()
|
||||
{
|
||||
watchForCreation_data();
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::watchForOwnerChange()
|
||||
{
|
||||
QFETCH(QString, watchedName);
|
||||
QFETCH(QString, registeredName);
|
||||
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForOwnerChange);
|
||||
QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForOwnerChange);
|
||||
|
||||
QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString)));
|
||||
QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString)));
|
||||
@ -201,18 +249,18 @@ void tst_QDBusServiceWatcher::watchForOwnerChange()
|
||||
QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop()));
|
||||
|
||||
// register a name
|
||||
QVERIFY(con.registerService(serviceName));
|
||||
QVERIFY(con.registerService(registeredName));
|
||||
|
||||
QTestEventLoop::instance().enterLoop(1);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
|
||||
QCOMPARE(spyR.count(), 1);
|
||||
QCOMPARE(spyR.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyR.at(0).at(0).toString(), registeredName);
|
||||
|
||||
QCOMPARE(spyU.count(), 0);
|
||||
|
||||
QCOMPARE(spyO.count(), 1);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
|
||||
QVERIFY(spyO.at(0).at(1).toString().isEmpty());
|
||||
QCOMPARE(spyO.at(0).at(2).toString(), con.baseService());
|
||||
|
||||
@ -221,35 +269,43 @@ void tst_QDBusServiceWatcher::watchForOwnerChange()
|
||||
spyO.clear();
|
||||
|
||||
// unregister it:
|
||||
con.unregisterService(serviceName);
|
||||
con.unregisterService(registeredName);
|
||||
|
||||
// and register again
|
||||
QVERIFY(con.registerService(serviceName));
|
||||
QVERIFY(con.registerService(registeredName));
|
||||
|
||||
QTestEventLoop::instance().enterLoop(1);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
|
||||
QCOMPARE(spyR.count(), 1);
|
||||
QCOMPARE(spyR.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyR.at(0).at(0).toString(), registeredName);
|
||||
|
||||
QCOMPARE(spyU.count(), 1);
|
||||
QCOMPARE(spyU.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyU.at(0).at(0).toString(), registeredName);
|
||||
|
||||
QCOMPARE(spyO.count(), 2);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
|
||||
QCOMPARE(spyO.at(0).at(1).toString(), con.baseService());
|
||||
QVERIFY(spyO.at(0).at(2).toString().isEmpty());
|
||||
QCOMPARE(spyO.at(1).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyO.at(1).at(0).toString(), registeredName);
|
||||
QVERIFY(spyO.at(1).at(1).toString().isEmpty());
|
||||
QCOMPARE(spyO.at(1).at(2).toString(), con.baseService());
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::modeChange_data()
|
||||
{
|
||||
watchForCreation_data();
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::modeChange()
|
||||
{
|
||||
QFETCH(QString, watchedName);
|
||||
QFETCH(QString, registeredName);
|
||||
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration);
|
||||
QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForRegistration);
|
||||
|
||||
QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString)));
|
||||
QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString)));
|
||||
@ -257,18 +313,18 @@ void tst_QDBusServiceWatcher::modeChange()
|
||||
QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop()));
|
||||
|
||||
// register a name
|
||||
QVERIFY(con.registerService(serviceName));
|
||||
QVERIFY(con.registerService(registeredName));
|
||||
|
||||
QTestEventLoop::instance().enterLoop(1);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
|
||||
QCOMPARE(spyR.count(), 1);
|
||||
QCOMPARE(spyR.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyR.at(0).at(0).toString(), registeredName);
|
||||
|
||||
QCOMPARE(spyU.count(), 0);
|
||||
|
||||
QCOMPARE(spyO.count(), 1);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
|
||||
QVERIFY(spyO.at(0).at(1).toString().isEmpty());
|
||||
QCOMPARE(spyO.at(0).at(2).toString(), con.baseService());
|
||||
|
||||
@ -279,7 +335,7 @@ void tst_QDBusServiceWatcher::modeChange()
|
||||
watcher.setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
|
||||
|
||||
// unregister it:
|
||||
con.unregisterService(serviceName);
|
||||
con.unregisterService(registeredName);
|
||||
|
||||
QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop()));
|
||||
QTestEventLoop::instance().enterLoop(1);
|
||||
@ -288,10 +344,10 @@ void tst_QDBusServiceWatcher::modeChange()
|
||||
QCOMPARE(spyR.count(), 0);
|
||||
|
||||
QCOMPARE(spyU.count(), 1);
|
||||
QCOMPARE(spyU.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyU.at(0).at(0).toString(), registeredName);
|
||||
|
||||
QCOMPARE(spyO.count(), 1);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), serviceName);
|
||||
QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
|
||||
QCOMPARE(spyO.at(0).at(1).toString(), con.baseService());
|
||||
QVERIFY(spyO.at(0).at(2).toString().isEmpty());
|
||||
}
|
||||
@ -301,7 +357,7 @@ void tst_QDBusServiceWatcher::disconnectedConnection()
|
||||
QDBusConnection con("");
|
||||
QVERIFY(!con.isConnected());
|
||||
|
||||
QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration);
|
||||
QDBusServiceWatcher watcher(generateServiceName(), con, QDBusServiceWatcher::WatchForRegistration);
|
||||
watcher.addWatchedService("com.example.somethingelse");
|
||||
watcher.addWatchedService("org.freedesktop.DBus");
|
||||
|
||||
@ -311,8 +367,15 @@ void tst_QDBusServiceWatcher::disconnectedConnection()
|
||||
watcher.setWatchedServices(QStringList());
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::setConnection_data()
|
||||
{
|
||||
QTest::addColumn<QString>("serviceName");
|
||||
QTest::newRow("normal") << generateServiceName();
|
||||
}
|
||||
|
||||
void tst_QDBusServiceWatcher::setConnection()
|
||||
{
|
||||
QFETCH(QString, serviceName);
|
||||
// begin with a disconnected connection
|
||||
QDBusConnection con("");
|
||||
QVERIFY(!con.isConnected());
|
||||
|
Loading…
x
Reference in New Issue
Block a user