diff options
author | Marja Hassinen <ext-marja.2.hassinen@nokia.com> | 2009-10-27 11:53:11 +0200 |
---|---|---|
committer | Marja Hassinen <ext-marja.2.hassinen@nokia.com> | 2009-10-27 11:53:11 +0200 |
commit | 9c2d4fe23f42d50d5a1efc2bd1efdd606afc359b (patch) | |
tree | ccadf4d037368d9d826b2b78efe026cd46c8a6e9 | |
parent | 43feb629a330f829716001919b6c80f779eb7f65 (diff) |
libcontextprovider, protocol change: Documentation update.
-rw-r--r-- | libcontextprovider/src/property.cpp | 3 | ||||
-rw-r--r-- | libcontextprovider/src/property.h | 2 | ||||
-rw-r--r-- | libcontextprovider/src/propertyadaptor.cpp | 33 | ||||
-rw-r--r-- | libcontextprovider/src/propertyprivate.cpp | 42 | ||||
-rw-r--r-- | libcontextprovider/src/propertyprivate.h | 9 | ||||
-rw-r--r-- | libcontextprovider/src/servicebackend.h | 4 |
6 files changed, 75 insertions, 18 deletions
diff --git a/libcontextprovider/src/property.cpp b/libcontextprovider/src/property.cpp index b1b3f82a..02181fdd 100644 --- a/libcontextprovider/src/property.cpp +++ b/libcontextprovider/src/property.cpp @@ -62,6 +62,9 @@ Property::Property(const QString &k, QObject* parent) init(ServiceBackend::defaultServiceBackend, k); } +/// Initialize the private implementation: find the corresponding +/// PropertyPrivate (create it if it doesn't exist), and connect +/// signals from it. void Property::init(ServiceBackend *serviceBackend, const QString &key) { contextDebug() << F_PROPERTY << "Creating new Property for key:" << key; diff --git a/libcontextprovider/src/property.h b/libcontextprovider/src/property.h index 837aa852..788a270d 100644 --- a/libcontextprovider/src/property.h +++ b/libcontextprovider/src/property.h @@ -53,7 +53,7 @@ public: void unsetValue(); private: - PropertyPrivate *priv; + PropertyPrivate *priv; ///< Private implementation void init(ServiceBackend *serviceBackend, const QString &key); signals: diff --git a/libcontextprovider/src/propertyadaptor.cpp b/libcontextprovider/src/propertyadaptor.cpp index 0d23accf..1751ab7e 100644 --- a/libcontextprovider/src/propertyadaptor.cpp +++ b/libcontextprovider/src/propertyadaptor.cpp @@ -30,6 +30,13 @@ namespace ContextProvider { /*! \class PropertyAdaptor \brief A DBus adaptor for implementing the org.maemo.contextkit.Property + + PropertyAdaptor represents the Property object on D-Bus. It also + keeps track of its clients and sets the PropertyPrivate to + subscribed or unsubscribed accordingly. + + PropertyAdaptor also listens to values sent by other providers on + D-Bus and notifies the PropertyPrivate about them. */ /// Constructor. Creates new adaptor for the given manager with the given @@ -43,6 +50,10 @@ PropertyAdaptor::PropertyAdaptor(PropertyPrivate* propertyPrivate, QDBusConnecti sconnect(propertyPrivate, SIGNAL(valueChanged(const QVariantList&, const quint64&)), this, SIGNAL(ValueChanged(const QVariantList&, const quint64&))); + // The same value can be provided on session and system bus by + // different providers. Unfortunately, each provider needs both a + // system bus connection and a session bus connection to listen to + // other providers. QDBusConnection::sessionBus().connect("", objectPath(), DBUS_INTERFACE, "ValueChanged", this, SLOT(onValueChanged(QVariantList, quint64))); @@ -50,6 +61,7 @@ PropertyAdaptor::PropertyAdaptor(PropertyPrivate* propertyPrivate, QDBusConnecti this, SLOT(onValueChanged(QVariantList, quint64))); } +/// Implementation of the D-Bus method Subscribe void PropertyAdaptor::Subscribe(const QDBusMessage &msg, QVariantList& values, quint64& timestamp) { contextDebug() << "Subscribe called"; @@ -75,6 +87,7 @@ void PropertyAdaptor::Subscribe(const QDBusMessage &msg, QVariantList& values, q Get(values, timestamp); } +/// Implementation of the D-Bus method Unsubscribe void PropertyAdaptor::Unsubscribe(const QDBusMessage &msg) { contextDebug() << "Unsubscribe called"; @@ -94,6 +107,7 @@ void PropertyAdaptor::Unsubscribe(const QDBusMessage &msg) } } +/// Implementation of the D-Bus method Get. void PropertyAdaptor::Get(QVariantList& values, quint64& timestamp) { // Construct the return values @@ -103,15 +117,16 @@ void PropertyAdaptor::Get(QVariantList& values, quint64& timestamp) timestamp = propertyPrivate->timestamp; } +/// Called when a ValueChanged signal is overheard on D-Bus. Command +/// PropertyPrivate to update its overheard value. void PropertyAdaptor::onValueChanged(QVariantList values, quint64 timestamp) { propertyPrivate->updateOverheardValue(values, timestamp); } - -/// Dbus interface slot. The PropertyAdaptor listens for dbus bus names changing -/// to notify the managed Property that a bus name is gone. It does it through -/// Property::busNameIsGone function. +/// Called when a NameOwnerChanged signal is broadcast on D-Bus. If +/// one of our clients has disappeared from D-Bus, update the client +/// list. void PropertyAdaptor::OnServiceOwnerChanged(const QString &name, const QString &oldName, const QString &newName) { @@ -126,6 +141,11 @@ void PropertyAdaptor::OnServiceOwnerChanged(const QString &name, const QString & } } +/// Object path where the corresponding PropertyPrivate object should +/// be registered at. For a core propertiy Property.Name (not starting +/// with /), the path is /org/maemo/contextkit/Property/Name. For a +/// non-core property /com/my/property, the object path is +/// /com/my/property. QString PropertyAdaptor::objectPath() const { if (!propertyPrivate->key.startsWith("/")) @@ -133,11 +153,14 @@ QString PropertyAdaptor::objectPath() const return QString(propertyPrivate->key); } +/// Called when the service is stopped and will disappear from +/// D-Bus. If it appears again, the clients will resubscribe, and it +/// shouldn't be a MultipleSubscribe error. Thus, we need to forget +/// the clients when the service is stopped. void PropertyAdaptor::forgetClients() { clientServiceNames.clear(); propertyPrivate->setUnsubscribed(); } - } // namespace ContextProvider diff --git a/libcontextprovider/src/propertyprivate.cpp b/libcontextprovider/src/propertyprivate.cpp index ad73b81c..48e3ca19 100644 --- a/libcontextprovider/src/propertyprivate.cpp +++ b/libcontextprovider/src/propertyprivate.cpp @@ -29,8 +29,20 @@ namespace ContextProvider { +/*! + \class PropertyPrivate ContextProvider ContextProvider + + \brief The private implementation of Property. + + For each (ServiceBackend*, key) pair there exists only one + PropertyPrivate; multiple Property objects may share it. +*/ + + QHash<QPair<ServiceBackend*,QString>, PropertyPrivate*> PropertyPrivate::propertyPrivateMap; +/// Constructor. Register the PropertyPrivate to its ServiceBackend; +/// this will make the Property object appear on D-Bus. PropertyPrivate::PropertyPrivate(ServiceBackend* serviceBackend, const QString &key, QObject *parent) : QObject(parent), refCount(0), serviceBackend(serviceBackend), key(key), value(QVariant()), timestamp(currentTimestamp()), subscribed(false), @@ -40,10 +52,11 @@ PropertyPrivate::PropertyPrivate(ServiceBackend* serviceBackend, const QString & serviceBackend->addProperty(key, this); } -PropertyPrivate::~PropertyPrivate() -{ -} - +/// Set value for the PropertyPrivate. Results in a valueChanged +/// signal emission, if 1) the value was different than the current +/// value of the PropertyPrivate, or 2) The provider has overheard +/// another provider setting a different value having a more recent +/// time stamp than our last emission. void PropertyPrivate::setValue(const QVariant& v) { contextDebug() << F_PROPERTY << "Setting key:" << key << "to type:" << v.typeName(); @@ -67,9 +80,12 @@ void PropertyPrivate::setValue(const QVariant& v) } } +/// Emit the valueChanged signal and update the emittedValue and +/// emittedTimestamp. (If subscribed is false, no value is emitted.) void PropertyPrivate::emitValue() { - // No difference between intention and emitted value, nothing happens + // No difference between intention and emitted value, nothing + // happens if (emittedTimestamp == timestamp && emittedValue == value && emittedValue.isNull() == value.isNull()) return; @@ -91,6 +107,9 @@ void PropertyPrivate::emitValue() emit valueChanged(values, timestamp); } +/// Set the PropertyPrivate to subscribed state. If it was in the +/// unsubscribed state, the firstSubscriberAppeared signal is +/// emitted. (Property transmits the signal forward.) void PropertyPrivate::setSubscribed() { if (subscribed == false) { @@ -99,6 +118,9 @@ void PropertyPrivate::setSubscribed() } } +/// Set the PropertyPrivate to unsubscribed state. If it was in the +/// subscribed state, the lastSubscriberDisappeared signal is +/// emitted. (Property transmits the signal forward.) void PropertyPrivate::setUnsubscribed() { if (subscribed == true) { @@ -107,6 +129,11 @@ void PropertyPrivate::setUnsubscribed() } } +/// Called by PropertyAdaptor when it has overheard another provider +/// sending a value on D-Bus. Check if the value is different and more +/// recent than the value we've emitted last. If so, emit our value +/// again. This way we ensure that the client gets the correct time +/// stamp for our value. void PropertyPrivate::updateOverheardValue(const QVariantList& v, const quint64& t) { contextDebug() << "Updating overheard value" << v << t; @@ -119,7 +146,7 @@ void PropertyPrivate::updateOverheardValue(const QVariantList& v, const quint64& else { overheardValue = v[0]; } - if (t > emittedTimestamp && overheardValue != emittedValue){ + if (t > emittedTimestamp && overheardValue != emittedValue){ // record that a different and more recent value than the one // emitted has been overheard overheard = true; @@ -129,6 +156,8 @@ void PropertyPrivate::updateOverheardValue(const QVariantList& v, const quint64& } } +/// Compute a unique time stamp for our value. The time stamp is based +/// on monotonic clock and its value is: seconds * 10e9 + nanoseconds. quint64 PropertyPrivate::currentTimestamp() { struct timespec time; @@ -138,6 +167,5 @@ quint64 PropertyPrivate::currentTimestamp() return toReturn; } - } // end namespace diff --git a/libcontextprovider/src/propertyprivate.h b/libcontextprovider/src/propertyprivate.h index 2e5a4ad0..f626f773 100644 --- a/libcontextprovider/src/propertyprivate.h +++ b/libcontextprovider/src/propertyprivate.h @@ -37,7 +37,6 @@ class PropertyPrivate : public QObject public: explicit PropertyPrivate(ServiceBackend* serviceBackend, const QString &key, QObject *parent = 0); - virtual ~PropertyPrivate(); void setValue(const QVariant& v); void updateOverheardValue(const QVariantList&, const quint64&); @@ -53,16 +52,20 @@ private: static quint64 currentTimestamp(); void emitValue(); - int refCount; + int refCount; ///< Number of Property instance sharing this PropertyPrivate ServiceBackend* serviceBackend; ///< Pointer to the serviceBackend taking care of D-Bus related things QString key; ///< Key of this property QVariant value; ///< Current value of the property, set by this provider. QVariant() if null. quint64 timestamp; ///< Time when the value was set - bool subscribed; + + bool subscribed; ///< True if this Property is subscribed to by the clients. QVariant emittedValue; ///< Last value emitted by this provider. quint64 emittedTimestamp; ///< Time when the emittedValue was emitted. bool overheard; ///< True if provider overheard a value over D-Bus (must be different and more recent than emitted) + + /// Map of PropertyPrivate instances static QHash<QPair<ServiceBackend*, QString>, PropertyPrivate*> propertyPrivateMap; + friend class Property; friend class PropertyAdaptor; }; diff --git a/libcontextprovider/src/servicebackend.h b/libcontextprovider/src/servicebackend.h index c69e40b8..1073d3f2 100644 --- a/libcontextprovider/src/servicebackend.h +++ b/libcontextprovider/src/servicebackend.h @@ -70,12 +70,12 @@ public: private: bool registerProperty(const QString& key, PropertyPrivate* property); + int refCount; ///< Number of Service objects using this as their backend + /// Shared or private QDBusConnection used for registering objects /// (and possibly bus names) QDBusConnection connection; - int refCount; ///< Number of Service objects using this as their backend - /// The bus name that should be registered by this ServiceBackend; /// "" if the ServiceBackend shouldn't register any. QString busName; |