aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--debian/control3
-rw-r--r--libcontextprovider/context-provide/Makefile.am4
-rw-r--r--libcontextprovider/context-provide/commandwatcher.cpp23
-rw-r--r--libcontextsubscriber/cli/Makefile.am4
-rw-r--r--libcontextsubscriber/cli/commandwatcher.cpp198
-rw-r--r--libcontextsubscriber/cli/commandwatcher.h5
-rw-r--r--libcontextsubscriber/cli/context-listen.cpp11
-rw-r--r--libcontextsubscriber/cli/propertylistener.cpp37
-rw-r--r--libcontextsubscriber/cli/propertylistener.h5
-rwxr-xr-xlibcontextsubscriber/customer-tests/commander/commander_nonexistent.py2
-rwxr-xr-xlibcontextsubscriber/customer-tests/pluginchanging/pluginchanging.py4
-rwxr-xr-xlibcontextsubscriber/customer-tests/subscription/multiprovider2.py2
-rwxr-xr-xlibcontextsubscriber/customer-tests/subscription/subscription.py42
-rw-r--r--libcontextsubscriber/src/contextkitplugin.cpp47
-rw-r--r--libcontextsubscriber/src/propertyhandle.cpp3
-rw-r--r--python/ContextKit/cltool.py2
17 files changed, 226 insertions, 167 deletions
diff --git a/configure.ac b/configure.ac
index c2a14908..d62c6f68 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,6 +19,7 @@ PKG_CHECK_MODULES_SUBST([QtTest], [QtTest])
PKG_CHECK_MODULES_SUBST([QtCore], [QtCore])
PKG_CHECK_MODULES_SUBST([QtDBus], [QtDBus])
PKG_CHECK_MODULES_SUBST([QtXml], [QtXml])
+PKG_CHECK_MODULES_SUBST([QJson], [QJson])
# only for compiling c code
PKG_CHECK_MODULES_SUBST([DBUS], [dbus-1])
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.12.0])
diff --git a/debian/control b/debian/control
index 76418442..5111c070 100644
--- a/debian/control
+++ b/debian/control
@@ -10,6 +10,7 @@ Build-Depends: debhelper (>= 5),
libcdb-dev,
libglib2.0-dev (>= 2.12.0),
libdbus-1-dev,
+ libqjson-dev,
xsltproc,
doxygen
XS-Python-Version: all
@@ -94,7 +95,7 @@ Description: Python bindings for ContextKit APIs
Package: contextkit-utils
Section: utils
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
+Depends: ${shlibs:Depends}, ${misc:Depends}, libqjson
Description: Command line utilities for ContextKit
This package contains the context-provide and context-listen
tools. You can use context-provide to quickly provide context
diff --git a/libcontextprovider/context-provide/Makefile.am b/libcontextprovider/context-provide/Makefile.am
index 87a4a22c..2eca452c 100644
--- a/libcontextprovider/context-provide/Makefile.am
+++ b/libcontextprovider/context-provide/Makefile.am
@@ -4,9 +4,9 @@ context_provide_SOURCES = context-provide.cpp \
commandwatcher.cpp commandwatcher.h propertyproxy.h \
propertyproxy.cpp
-AM_CXXFLAGS = $(QtCore_CFLAGS) $(QtDBus_CFLAGS) \
+AM_CXXFLAGS = $(QtCore_CFLAGS) $(QtDBus_CFLAGS) $(QJson_CFLAGS) \
'-DCONTEXT_LOG_MODULE_NAME="context-provide"'
-LIBS += $(QtCore_LIBS)
+LIBS += $(QtCore_LIBS) $(QJson_LIBS)
# library dependency hack for seamless make
AM_CXXFLAGS += -I$(srcdir)/../src \
diff --git a/libcontextprovider/context-provide/commandwatcher.cpp b/libcontextprovider/context-provide/commandwatcher.cpp
index 23320422..df96a2f2 100644
--- a/libcontextprovider/context-provide/commandwatcher.cpp
+++ b/libcontextprovider/context-provide/commandwatcher.cpp
@@ -38,6 +38,7 @@
#include <QMap>
#include <QDir>
#include <QSet>
+#include <qjson/parser.h>
const QString CommandWatcher::commanderBusName = "org.freedesktop.ContextKit.Commander";
@@ -179,9 +180,9 @@ void CommandWatcher::addCommand(const QStringList& args)
QString keyType = unquote(args.at(0)).toUpper();
const QString keyName = unquote(args.at(1));
- if (keyType != "INT" && keyType != "STRING" &&
+ if (keyType != "ANY" && keyType != "INT" && keyType != "STRING" &&
keyType != "DOUBLE" && keyType != "TRUTH" && keyType != "BOOL") {
- qDebug() << "ERROR: Unknown type (has to be: INT, STRING, DOUBLE, BOOL or TRUTH)";
+ qDebug() << "ERROR: Unknown type (has to be: COMPLEX, INT, STRING, DOUBLE, BOOL or TRUTH)";
return;
}
if (keyType == "BOOL") keyType = "TRUTH";
@@ -332,7 +333,7 @@ void CommandWatcher::dumpCommand(const QStringList &args)
void CommandWatcher::setCommand(const QString& command)
{
const QString keyName = unquote(command.left(command.indexOf('=')).trimmed());
- const QString value = unquote(command.mid(command.indexOf('=')+1).trimmed());
+ QString value = command.mid(command.indexOf('=')+1).trimmed();
if (! types.contains(keyName)) {
qDebug() << "ERROR: key" << keyName << "not known/added";
@@ -343,6 +344,9 @@ void CommandWatcher::setCommand(const QString& command)
const QString keyType = types.value(keyName);
QVariant v;
+ if (keyType != "ANY")
+ value = unquote(value);
+
if (keyType == "INT")
v = QVariant(value.toInt());
else if (keyType == "STRING")
@@ -354,9 +358,20 @@ void CommandWatcher::setCommand(const QString& command)
v = QVariant(true);
else
v = QVariant(false);
+ } else if (keyType == "ANY") {
+ QJson::Parser parser;
+ bool ok;
+
+ v = parser.parse(value.toUtf8(), &ok);
+ if (!ok) {
+ qDebug() << "An error occurred during parsing";
+ return;
+ }
}
- out << "Setting key: " << keyName << " to value: " << v.toString() << endl;
+ QString vstr;
+ QDebug(&vstr) << v;
+ out << "Setting key: " << keyName << " to value: " << vstr << endl;
out.flush();
prop->setValue(v);
}
diff --git a/libcontextsubscriber/cli/Makefile.am b/libcontextsubscriber/cli/Makefile.am
index 21f6b543..acaabdde 100644
--- a/libcontextsubscriber/cli/Makefile.am
+++ b/libcontextsubscriber/cli/Makefile.am
@@ -3,9 +3,9 @@ context_listen_SOURCES = context-listen.cpp \
propertylistener.h propertylistener.cpp commandwatcher.h \
commandwatcher.cpp
-AM_CXXFLAGS = $(QtCore_CFLAGS) $(QtDBus_CFLAGS) \
+AM_CXXFLAGS = $(QtCore_CFLAGS) $(QtDBus_CFLAGS) $(QJson_CFLAGS) \
'-DCONTEXT_LOG_MODULE_NAME="context-listen"'
-LIBS += $(QtCore_LIBS)
+LIBS += $(QtCore_LIBS) $(QJson_LIBS)
# library dependency hack for seamless make in cli/
AM_CXXFLAGS += -I$(srcdir)/../src \
diff --git a/libcontextsubscriber/cli/commandwatcher.cpp b/libcontextsubscriber/cli/commandwatcher.cpp
index aa761c9d..d4ff45d6 100644
--- a/libcontextsubscriber/cli/commandwatcher.cpp
+++ b/libcontextsubscriber/cli/commandwatcher.cpp
@@ -35,7 +35,7 @@
#include <errno.h>
#include <QMap>
-CommandWatcher::CommandWatcher(int commandfd, QMap<QString, ContextProperty*> *properties, QObject *parent) :
+CommandWatcher::CommandWatcher(int commandfd, QMap<QString, PropertyListener*> *properties, QObject *parent) :
QObject(parent), commandfd(commandfd), properties(properties)
{
commandNotifier = new QSocketNotifier(commandfd, QSocketNotifier::Read, this);
@@ -83,7 +83,6 @@ void CommandWatcher::help()
qDebug() << " plugin KEY - get the info()->plugin for a key";
qDebug() << " constructionstring KEY - get the info()->constructionstring for a key";
qDebug() << " providers KEY - get the info()->providers for a key";
- qDebug() << " flush - write FLUSHED to stderr and stdout";
qDebug() << "Any prefix of a command can be used as an abbreviation";
}
@@ -91,128 +90,107 @@ void CommandWatcher::interpret(const QString& command) const
{
QTextStream out(stdout);
QTextStream err(stderr);
- if (command == "") {
- help();
- } else {
- QStringList args = command.split(" ");
- QString commandName = args[0];
- args.pop_front();
-
- if (args.size() == 0 && !QString("flush").startsWith(commandName)) {
- help();
- return;
- }
+ QStringList args = command.split(" ");
+ QString commandName = args[0];
+ args.pop_front();
- if (QString("new").startsWith(commandName)) {
- foreach (QString key, args)
- if (properties->contains(key))
- qDebug() << "key already exists: " << key;
- else {
- properties->insert(key, new ContextProperty(key, QCoreApplication::instance()));
- new PropertyListener(properties->value(key));
- }
- } else if (QString("delete").startsWith(commandName)) {
- foreach (QString key, args)
- if (properties->contains(key))
- delete properties->take(key);
- else
- qDebug() << "no such key:" << key;
- } else if (QString("subscribe").startsWith(commandName)) {
- foreach (QString key, args)
- if (properties->contains(key))
- properties->value(key)->subscribe();
- else
- qDebug() << "no such key:" << key;
- } else if (QString("waitforsubscription").startsWith(commandName)) {
- foreach (QString key, args)
- if (properties->contains(key)) {
- properties->value(key)->waitForSubscription();
- out << "wait finished for " << key << endl;
- } else
- qDebug() << "no such key:" << key;
- } else if (QString("unsubscribe").startsWith(commandName)) {
- foreach (QString key, args)
- if (properties->contains(key))
- properties->value(key)->unsubscribe();
- else
- qDebug() << "no such key:" << key;
- } else if (QString("value").startsWith(commandName)) {
- QString key = args[0];
- if (properties->contains(key)) {
- QVariant value;
- if (args.size() > 1) {
- value = properties->value(key)->value(args[1]);
- } else {
- value = properties->value(key)->value();
- }
- if (value.isNull())
- out << "value is Unknown" << endl;
- else
- out << "value: " << value.typeName() << ":" << value.toString() << endl;
- } else
- qDebug() << "no such key:" << key;
- } else if (QString("key").startsWith(commandName)) {
- QString key = args[0];
- if (properties->contains(key))
- out << "key: " << properties->value(key)->key() << endl;
- else
- qDebug() << "no such key:" << key;
- } else if (QString("ikey").startsWith(commandName)) {
- QString key = args[0];
+ if (QString("new").startsWith(commandName)) {
+ foreach (QString key, args)
if (properties->contains(key))
- out << "ikey: " << properties->value(key)->info()->key() << endl;
+ qDebug() << "key already exists: " << key;
else
- qDebug() << "no such key:" << key;
- } else if (QString("man").startsWith(commandName)) {
- QString key = args[0];
+ properties->insert(key, new PropertyListener(key));
+ } else if (QString("delete").startsWith(commandName)) {
+ foreach (QString key, args)
if (properties->contains(key))
- out << "man: " << properties->value(key)->info()->doc() << endl;
+ delete properties->take(key);
else
qDebug() << "no such key:" << key;
- } else if (QString("type").startsWith(commandName)) {
- QString key = args[0];
+ } else if (QString("subscribe").startsWith(commandName)) {
+ foreach (QString key, args)
if (properties->contains(key))
- out << "type: " << properties->value(key)->info()->type() << endl;
+ properties->value(key)->prop->subscribe();
else
qDebug() << "no such key:" << key;
- } else if (QString("plugin").startsWith(commandName)) {
- QString key = args[0];
+ } else if (QString("waitforsubscription").startsWith(commandName)) {
+ foreach (QString key, args)
if (properties->contains(key)) {
- QList<ContextProviderInfo> providers = properties->value(key)->info()->providers();
- if (providers.size() > 0)
- out << "plugin: " << providers.at(0).plugin << endl;
- else
- out << "no plugin for key:" << key << endl;
+ properties->value(key)->prop->waitForSubscription();
+ out << "wait finished for " << key << endl;
} else
qDebug() << "no such key:" << key;
- } else if (QString("constructionstring").startsWith(commandName)) {
- QString key = args[0];
- if (properties->contains(key)) {
- QList<ContextProviderInfo> providers = properties->value(key)->info()->providers();
- if (providers.size() > 0)
- out << "constructionstring: " << providers.at(0).constructionString << endl;
- else
- out << "no constructionString for key:" << key << endl;
- } else
+ } else if (QString("unsubscribe").startsWith(commandName)) {
+ foreach (QString key, args)
+ if (properties->contains(key))
+ properties->value(key)->prop->unsubscribe();
+ else
qDebug() << "no such key:" << key;
- } else if (QString("providers").startsWith(commandName)) {
- QString key = args[0];
- if (properties->contains(key)) {
- out << "providers: ";
- QList<ContextProviderInfo> providers = properties->value(key)->info()->providers();
+ } else if (QString("value").startsWith(commandName)) {
+ QString key = args[0];
+ QString defaultValue;
+ if (args.size() > 1)
+ defaultValue = args[1];
+ if (properties->contains(key)) {
+ PropertyListener *pl = properties->value(key);
+ out << "value: " << pl->valueToString(defaultValue) << endl;
+ } else
+ qDebug() << "no such key:" << key;
+ } else if (QString("key").startsWith(commandName)) {
+ QString key = args[0];
+ if (properties->contains(key))
+ out << "key: " << properties->value(key)->prop->key() << endl;
+ else
+ qDebug() << "no such key:" << key;
+ } else if (QString("ikey").startsWith(commandName)) {
+ QString key = args[0];
+ if (properties->contains(key))
+ out << "ikey: " << properties->value(key)->prop->info()->key() << endl;
+ else
+ qDebug() << "no such key:" << key;
+ } else if (QString("man").startsWith(commandName)) {
+ QString key = args[0];
+ if (properties->contains(key))
+ out << "man: " << properties->value(key)->prop->info()->doc() << endl;
+ else
+ qDebug() << "no such key:" << key;
+ } else if (QString("type").startsWith(commandName)) {
+ QString key = args[0];
+ if (properties->contains(key))
+ out << "type: " << properties->value(key)->prop->info()->type() << endl;
+ else
+ qDebug() << "no such key:" << key;
+ } else if (QString("plugin").startsWith(commandName)) {
+ QString key = args[0];
+ if (properties->contains(key)) {
+ QList<ContextProviderInfo> providers = properties->value(key)->prop->info()->providers();
+ if (providers.size() > 0)
+ out << "plugin: " << providers.at(0).plugin << endl;
+ else
+ out << "no plugin for key:" << key << endl;
+ } else
+ qDebug() << "no such key:" << key;
+ } else if (QString("constructionstring").startsWith(commandName)) {
+ QString key = args[0];
+ if (properties->contains(key)) {
+ QList<ContextProviderInfo> providers = properties->value(key)->prop->info()->providers();
+ if (providers.size() > 0)
+ out << "constructionstring: " << providers.at(0).constructionString << endl;
+ else
+ out << "no constructionString for key:" << key << endl;
+ } else
+ qDebug() << "no such key:" << key;
+ } else if (QString("providers").startsWith(commandName)) {
+ QString key = args[0];
+ if (properties->contains(key)) {
+ out << "providers: ";
+ QList<ContextProviderInfo> providers = properties->value(key)->prop->info()->providers();
- foreach(ContextProviderInfo info, providers)
- out << info.constructionString << "@" << info.plugin << " ";
+ foreach(ContextProviderInfo info, providers)
+ out << info.constructionString << "@" << info.plugin << " ";
- out << endl;
- } else
- qDebug() << "no such key:" << key;
- } else if (QString("flush").startsWith(commandName)) {
- out << "FLUSHED" << endl;
- out.flush();
- err << "FLUSHED" << endl;
- err.flush();
+ out << endl;
} else
- help();
- }
+ qDebug() << "no such key:" << key;
+ } else
+ help();
}
diff --git a/libcontextsubscriber/cli/commandwatcher.h b/libcontextsubscriber/cli/commandwatcher.h
index 6d283ea1..3eaa55b6 100644
--- a/libcontextsubscriber/cli/commandwatcher.h
+++ b/libcontextsubscriber/cli/commandwatcher.h
@@ -28,18 +28,19 @@ class QTextStream;
class QSocketNotifier;
class ContextProperty;
class QString;
+class PropertyListener;
template <typename K, typename V> class QMap;
class CommandWatcher : public QObject
{
Q_OBJECT
public:
- CommandWatcher(int commandfd, QMap<QString, ContextProperty*> *properties, QObject *parent = 0);
+ CommandWatcher(int commandfd, QMap<QString, PropertyListener*> *properties, QObject *parent = 0);
private:
int commandfd;
QSocketNotifier *commandNotifier;
void interpret(const QString& command) const;
- QMap<QString, ContextProperty*> *properties;
+ QMap<QString, PropertyListener*> *properties;
static void help();
private slots:
diff --git a/libcontextsubscriber/cli/context-listen.cpp b/libcontextsubscriber/cli/context-listen.cpp
index 978fe9ac..b84ee427 100644
--- a/libcontextsubscriber/cli/context-listen.cpp
+++ b/libcontextsubscriber/cli/context-listen.cpp
@@ -45,15 +45,12 @@ int main(int argc, char **argv)
if (args.count() <= 1)
qWarning() << "Started without properties, if you want properties at startup, pass them as arguments";
- QMap<QString, ContextProperty*> properties;
+ QMap<QString, PropertyListener*> properties;
args.pop_front();
- foreach (QString key, args) {
- if (properties[key] == 0) {
- properties[key] = new ContextProperty(key, QCoreApplication::instance());
- new PropertyListener(properties[key]);
- }
- }
+ foreach (QString key, args)
+ if (!properties.contains(key))
+ properties.insert(key, new PropertyListener(key));
new CommandWatcher(STDIN_FILENO, &properties, QCoreApplication::instance());
diff --git a/libcontextsubscriber/cli/propertylistener.cpp b/libcontextsubscriber/cli/propertylistener.cpp
index 3d6a1eb5..740919a6 100644
--- a/libcontextsubscriber/cli/propertylistener.cpp
+++ b/libcontextsubscriber/cli/propertylistener.cpp
@@ -24,22 +24,41 @@
#include "sconnect.h"
#include <QDebug>
#include <QVariant>
+#include <QCoreApplication>
+#include <QDBusArgument>
+#include <qjson/serializer.h>
+#include <qjson/parser.h>
-PropertyListener::PropertyListener(ContextProperty *prop) :
- QObject(prop), prop(prop)
+PropertyListener::PropertyListener(const QString &key):
+ QObject(QCoreApplication::instance()), prop(new ContextProperty(key, this))
{
sconnect(prop, SIGNAL(valueChanged()), this, SLOT(onValueChanged()));
qDebug() << prop->key() << " subscribtion started";
}
-void PropertyListener::onValueChanged()
+QString PropertyListener::valueToString(QString defaultValue) const
{
- QTextStream out(stdout);
- out << prop->key();
- if (prop->value().isNull()) {
- out << " is Unknown";
+ QVariant value;
+ if (!defaultValue.isEmpty()) {
+ bool isOk;
+ QVariant def = QJson::Parser().parse(defaultValue.toUtf8(), &isOk);
+ if (!isOk)
+ qWarning() << "failed to parse default value as json:" << defaultValue;
+ value = prop->value(def);
} else {
- out << " = " << prop->value().typeName() << ":" << prop->value().toString();
+ value = prop->value();
}
- out << endl;
+ QString result;
+ if (value.isNull())
+ return result += "Unknown";
+ result += value.typeName();
+ result += ':';
+ result += QJson::Serializer().serialize(value);
+ return result;
+}
+
+void PropertyListener::onValueChanged()
+{
+ QTextStream out(stdout);
+ out << prop->key() << " = " << valueToString() << endl;
}
diff --git a/libcontextsubscriber/cli/propertylistener.h b/libcontextsubscriber/cli/propertylistener.h
index 8f2fd856..b15594b5 100644
--- a/libcontextsubscriber/cli/propertylistener.h
+++ b/libcontextsubscriber/cli/propertylistener.h
@@ -30,10 +30,11 @@ class PropertyListener : public QObject
{
Q_OBJECT
public:
- PropertyListener(ContextProperty *prop);
+ PropertyListener(const QString &key);
+ QString valueToString(QString defaultValue = QString()) const;
private slots:
void onValueChanged();
-private:
+public:
ContextProperty *prop;
};
diff --git a/libcontextsubscriber/customer-tests/commander/commander_nonexistent.py b/libcontextsubscriber/customer-tests/commander/commander_nonexistent.py
index b702cac7..b10d4a67 100755
--- a/libcontextsubscriber/customer-tests/commander/commander_nonexistent.py
+++ b/libcontextsubscriber/customer-tests/commander/commander_nonexistent.py
@@ -57,7 +57,7 @@ class CommanderNonExistent(unittest.TestCase):
# check the non-existent property
commander.send("add string test.string barfoo")
commander.expect("Added key: test.string")
- self.assert_(listen.expect(wanted("test.string", "QString", "barfoo")),
+ self.assert_(listen.expect(wanted("test.string", "QString", "\"barfoo\"")),
"Non-existent property couldn't be commanded")
# change the type of the non-existent property
diff --git a/libcontextsubscriber/customer-tests/pluginchanging/pluginchanging.py b/libcontextsubscriber/customer-tests/pluginchanging/pluginchanging.py
index f49b5406..a1ee1fbe 100755
--- a/libcontextsubscriber/customer-tests/pluginchanging/pluginchanging.py
+++ b/libcontextsubscriber/customer-tests/pluginchanging/pluginchanging.py
@@ -54,14 +54,14 @@ class Subscription(unittest.TestCase):
#print "now reading"
# Expect value coming from plugin libcontextsubscribertime1
- self.assert_(self.context_client.expect("Test.Time = QString:Time1:"))
+ self.assert_(self.context_client.expect("Test.Time = QString:\"Time1:"))
# Modify the registry so that the key is now provided by libcontextsubscribertime2
os.system('cp time2.context.temp time.context.temp')
os.system('mv time.context.temp time.context')
# Expect value coming from plugin libcontextsubscribertime2
- self.assert_(self.context_client.expect("Test.Time = QString:Time2:"))
+ self.assert_(self.context_client.expect("Test.Time = QString:\"Time2:"))
self.context_client.wait()
if __name__ == "__main__":
diff --git a/libcontextsubscriber/customer-tests/subscription/multiprovider2.py b/libcontextsubscriber/customer-tests/subscription/multiprovider2.py
index 402765f8..34a3c3ae 100755
--- a/libcontextsubscriber/customer-tests/subscription/multiprovider2.py
+++ b/libcontextsubscriber/customer-tests/subscription/multiprovider2.py
@@ -70,7 +70,7 @@ class MultiProvider(unittest.TestCase):
time.sleep(4)
client.send("value test.prop")
- self.assert_(client.expect("\nvalue: int:22\n"))
+ self.assert_(client.expect("^value: int:22$"))
client.wait()
provider_y.wait()
provider_y.wait()
diff --git a/libcontextsubscriber/customer-tests/subscription/subscription.py b/libcontextsubscriber/customer-tests/subscription/subscription.py
index 4bd95ef5..3e941de7 100755
--- a/libcontextsubscriber/customer-tests/subscription/subscription.py
+++ b/libcontextsubscriber/customer-tests/subscription/subscription.py
@@ -69,7 +69,7 @@ class Subscription(unittest.TestCase):
self.assert_(
listen.expect(["^test.double = double:2.5$",
"^test.int = int:1$",
- "^test.string = QString:foobar$",
+ "^test.string = QString:\"foobar\"$",
"^test.truth = bool:true$"]),
"Actual key values pairs do not match expected")
@@ -80,7 +80,7 @@ class Subscription(unittest.TestCase):
listen.expect("^value: int:100$"),
"Value command returned wrong value")
- listen.send("value test.int defaultValue")
+ listen.send("value test.int \"defaultValue\"")
self.assert_(
listen.expect("^value: int:100$"),
"Value command returned wrong value")
@@ -89,12 +89,12 @@ class Subscription(unittest.TestCase):
listen.expect("Unknown") # wait for it
listen.send("value test.int")
self.assert_(
- listen.expect("^value is Unknown$"),
+ listen.expect("^value: Unknown$"),
"Value command returned wrong value")
- listen.send("value test.int defaultValue")
+ listen.send("value test.int \"defaultValue\"")
self.assert_(
- listen.expect("^value: QString:defaultValue$"),
+ listen.expect("^value: QString:\"defaultValue\"$"),
"Value command returned wrong value")
listen.send("key test.int")
@@ -139,7 +139,7 @@ class Subscription(unittest.TestCase):
listen = CLTool("context-listen", "test.double", "test.string", "test.int", "test.truth")
listen.expect(["^test.double = double:2.5$",
"^test.int = int:1$",
- "^test.string = QString:foobar$",
+ "^test.string = QString:\"foobar\"$",
"^test.truth = bool:true$"]) # wait for it
listen.send("ikey test.int")
@@ -171,7 +171,7 @@ class Subscription(unittest.TestCase):
listen = CLTool("context-listen", "test.double", "test.string", "test.int", "test.truth", "test.fake")
listen.expect(["^test.double = double:2.5$",
"^test.int = int:1$",
- "^test.string = QString:foobar$",
+ "^test.string = QString:\"foobar\"$",
"^test.truth = bool:true$"]) # wait for it
# test querying the type of all properties
@@ -210,7 +210,7 @@ class Subscription(unittest.TestCase):
listen = CLTool("context-listen", "test.double", "test.string", "test.int", "test.truth", "test.fake")
listen.expect(["^test.double = double:2.5$",
"^test.int = int:1$",
- "^test.string = QString:foobar$",
+ "^test.string = QString:\"foobar\"$",
"^test.truth = bool:true$"]) # wait for it
# test querying the provider(s)
@@ -256,7 +256,7 @@ class Subscription(unittest.TestCase):
self.assert_(
listen.expect(["^test.double = double:2.5$",
"^test.int = int:1$",
- "^test.string = QString:foobar$",
+ "^test.string = QString:\"foobar\"$",
"^test.truth = bool:true$"]),
"Actual key values pairs do not match expected")
listen.wait()
@@ -295,7 +295,7 @@ class Subscription(unittest.TestCase):
provider.send("unset test.truth")
self.assert_(
- listen.expect("^test.truth is Unknown$"),
+ listen.expect(wantedUnknown("test.truth")),
"setting to unknown didn't work")
provider.send("test.truth = True")
@@ -332,17 +332,17 @@ class Subscription(unittest.TestCase):
listen = CLTool("context-listen", "test.string")
self.assert_(
- listen.expect("^test.string = QString:something$"),
+ listen.expect("^test.string = QString:\"something\"$"),
"setting to 'something' didn't work")
provider.send('test.string = ""')
self.assert_(
- listen.expect("^test.string = QString:$"),
+ listen.expect("^test.string = QString:\"\"$"),
"setting to empty string didn't work")
provider.send('unset test.string')
self.assert_(
- listen.expect("^test.string is Unknown$"),
+ listen.expect(wantedUnknown("test.string")),
"setting to null didn't work")
listen.wait()
@@ -393,16 +393,16 @@ class MultipleSubscribers(unittest.TestCase):
client1_expected = ["^test.double = double:2.5$",
"^test.int = int:1$",
- "^test.string = QString:foobar$",
+ "^test.string = QString:\"foobar\"$",
"^test.truth = bool:true$"]
client2_expected = ["^test.double = double:2.5$",
"^test.int = int:1$"]
client3_expected = ["^test.int = int:1$",
- "^test.string = QString:foobar$",
+ "^test.string = QString:\"foobar\"$",
"^test.truth = bool:true$"]
client4_expected = ["^test.double = double:2.5$",
"^test.int = int:1$",
- "^test.string = QString:foobar$"]
+ "^test.string = QString:\"foobar\"$"]
self.assert_(self.context_client1.expect(client1_expected), "Actual key values pairs do not match expected")
self.assert_(self.context_client2.expect(client2_expected), "Actual key values pairs do not match expected")
@@ -431,16 +431,16 @@ class MultipleSubscribers(unittest.TestCase):
"""
client1_expected = ["^test.double = double:2.5$",
"^test.int = int:1$",
- "^test.string = QString:foobar$",
+ "^test.string = QString:\"foobar\"$",
"^test.truth = bool:true$"]
client2_expected = ["^test.double = double:2.5$",
"^test.int = int:1$"]
client3_expected = ["^test.int = int:1$",
- "^test.string = QString:foobar$",
+ "^test.string = QString:\"foobar\"$",
"^test.truth = bool:true$"]
client4_expected = ["^test.double = double:2.5$",
"^test.int = int:1$",
- "^test.string = QString:foobar$"]
+ "^test.string = QString:\"foobar\"$"]
self.assert_(self.context_client1.expect(client1_expected), "Actual key values pairs do not match expected")
self.assert_(self.context_client2.expect(client2_expected), "Actual key values pairs do not match expected")
@@ -463,8 +463,8 @@ class MultipleSubscribers(unittest.TestCase):
self.assert_(self.context_client3.expect(client3_expected), "Actual key values pairs do not match expected")
self.flexiprovider.send("unset test.truth")
- client1_expected = "^test.truth is Unknown$"
- client3_expected = "^test.truth is Unknown$"
+ client1_expected = wantedUnknown("test.truth")
+ client3_expected = wantedUnknown("test.truth")
self.assert_(self.context_client1.expect(client1_expected), "Actual key values pairs do not match expected")
self.assert_(self.context_client3.expect(client3_expected), "Actual key values pairs do not match expected")
diff --git a/libcontextsubscriber/src/contextkitplugin.cpp b/libcontextsubscriber/src/contextkitplugin.cpp
index ec43638f..4a905177 100644
--- a/libcontextsubscriber/src/contextkitplugin.cpp
+++ b/libcontextsubscriber/src/contextkitplugin.cpp
@@ -263,12 +263,57 @@ void ContextKitPlugin::onDBusValuesChanged(QMap<QString, QVariant> values)
emit valueChanged(key, values[key]);
}
+// QDBus doesn't unmarshall non-basic types inside QVariants (since it cannot
+// know the intention), but leaves them as QDBusArguments. Here we walk the
+// structure and unpack lists and maps.
+static QVariant demarshallValue(const QVariant &v)
+{
+ if (v.userType() != qMetaTypeId<QDBusArgument>())
+ return v;
+ const QDBusArgument &dba = v.value<QDBusArgument>();
+ switch (dba.currentType()) {
+ case QDBusArgument::ArrayType: {
+ QVariantList vl;
+ dba.beginArray();
+ while (!dba.atEnd()) {
+ QVariant v;
+ dba >> v;
+ vl << demarshallValue(v);
+ }
+ dba.endArray();
+ return QVariant(vl);
+ break;
+ }
+ case QDBusArgument::MapType: {
+ dba.beginMap();
+ QVariantMap vm;
+ while (!dba.atEnd()) {
+ QString k;
+ QVariant v;
+ dba.beginMapEntry();
+ dba >> k >> v;
+ dba.endMapEntry();
+ v = demarshallValue(v);
+ vm.insert(k, v);
+ }
+ return QVariant(vm);
+ break;
+ }
+ default:
+ // Shouldn't reach this.
+ contextWarning() << "got something unexpected: QDBusArgument of type"
+ << dba.currentType();
+ return QVariant();
+ break;
+ }
+}
+
static TimedValue createTimedValue(const QList<QVariant> value, quint64 time)
{
if (value.size() == 0)
return TimedValue(QVariant(), time);
else
- return TimedValue(value.at(0), time);
+ return TimedValue(demarshallValue(value.at(0)), time);
}
void ContextKitPlugin::onNewValueChanged(QList<QVariant> value,
diff --git a/libcontextsubscriber/src/propertyhandle.cpp b/libcontextsubscriber/src/propertyhandle.cpp
index 73a88877..fd93988c 100644
--- a/libcontextsubscriber/src/propertyhandle.cpp
+++ b/libcontextsubscriber/src/propertyhandle.cpp
@@ -255,7 +255,8 @@ void PropertyHandle::onValueChanged()
} else if (myType == "DOUBLE") {
checked = (QVariant::Double == newValue.type());
} else if (myType == "INT") {
- checked = (QVariant::Int == newValue.type());
+ checked = (QVariant::ULongLong == newValue.type() ||
+ QVariant::Int == newValue.type());
}
if (!checked) {
diff --git a/python/ContextKit/cltool.py b/python/ContextKit/cltool.py
index 5901ab25..8051aadc 100644
--- a/python/ContextKit/cltool.py
+++ b/python/ContextKit/cltool.py
@@ -208,6 +208,6 @@ def wanted(name, type, value):
def wantedUnknown(name):
"""Construct an expect() regexp expecting an unset context property."""
- return "^%s is Unknown$" % (name)
+ return "^%s = Unknown$" % (name)
__all__ = ['wanted', 'wantedUnknown', 'CLTool']