15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef DBUS_PROPERTY_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DBUS_PROPERTY_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/dbus_export.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// D-Bus objects frequently provide sets of properties accessed via a
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// standard interface of method calls and signals to obtain the current value,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// set a new value and be notified of changes to the value. Unfortunately this
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interface makes heavy use of variants and dictionaries of variants. The
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// classes defined here make dealing with properties in a type-safe manner
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// possible.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Client implementation classes should define a Properties structure, deriving
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the PropertySet class defined here. This structure should contain a
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// member for each property defined as an instance of the Property<> class,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specifying the type to the template. Finally the structure should chain up
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the PropertySet constructor, and then call RegisterProperty() for each
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// property defined to associate them with their string name.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   class ExampleClient {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    public:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     struct Properties : public dbus::PropertySet {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       dbus::Property<std::string> name;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       dbus::Property<uint16> version;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       dbus::Property<dbus::ObjectPath> parent;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       dbus::Property<std::vector<std::string> > children;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       Properties(dbus::ObjectProxy* object_proxy,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                  const PropertyChangedCallback callback)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//           : dbus::PropertySet(object_proxy, "com.example.DBus", callback) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         RegisterProperty("Name", &name);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         RegisterProperty("Version", &version);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         RegisterProperty("Parent", &parent);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         RegisterProperty("Children", &children);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       virtual ~Properties() {}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     };
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Properties structure requires a pointer to the object proxy of the
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// actual object to track, and after construction should have signals
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connected to that object and initial values set by calling ConnectSignals()
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and GetAll(). The structure should not outlive the object proxy, so it
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is recommended that the lifecycle of both be managed together.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example (continued):
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     typedef std::map<std::pair<dbus::ObjectProxy*, Properties*> > Object;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     typedef std::map<dbus::ObjectPath, Object> ObjectMap;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     ObjectMap object_map_;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     dbus::ObjectProxy* GetObjectProxy(const dbus::ObjectPath& object_path) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       return GetObject(object_path).first;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     Properties* GetProperties(const dbus::ObjectPath& object_path) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       return GetObject(object_path).second;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     Object GetObject(const dbus::ObjectPath& object_path) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       ObjectMap::iterator it = object_map_.find(object_path);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       if (it != object_map_.end())
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         return it->second;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       dbus::ObjectProxy* object_proxy = bus->GetObjectProxy(...);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       // connect signals, etc.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       Properties* properties = new Properties(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//           object_proxy,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//           base::Bind(&PropertyChanged,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                      weak_ptr_factory_.GetWeakPtr(),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                      object_path));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       properties->ConnectSignals();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       properties->GetAll();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       Object object = std::make_pair(object_proxy, properties);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       object_map_[object_path] = object;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       return object;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  };
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This now allows code using the client implementation to access properties
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in a type-safe manner, and assuming the PropertyChanged callback is
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// propogated up to observers, be notified of changes. A typical access of
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the current value of the name property would be:
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   ExampleClient::Properties* p = example_client->GetProperties(object_path);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   std::string name = p->name.value();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Normally these values are updated from signals emitted by the remote object,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in case an explicit round-trip is needed to obtain the current value, the
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get() method can be used and indicates whether or not the value update was
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// successful. The updated value can be obtained in the callback using the
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// value() method.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   p->children.Get(base::Bind(&OnGetChildren));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A new value can be set using the Set() method, the callback indicates
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// success only; it is up to the remote object when (and indeed if) it updates
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the property value, and whether it emits a signal or a Get() call is
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// required to obtain it.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   p->version.Set(20, base::Bind(&OnSetVersion))
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace dbus {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// D-Bus Properties interface constants, declared here rather than
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in property.cc because template methods use them.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPropertiesInterface[] = "org.freedesktop.DBus.Properties";
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPropertiesGetAll[] = "GetAll";
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPropertiesGet[] = "Get";
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPropertiesSet[] = "Set";
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPropertiesChanged[] = "PropertiesChanged";
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PropertySet;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PropertyBase is an abstract base-class consisting of the parts of
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the Property<> template that are not type-specific, such as the
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// associated PropertySet, property name, and the type-unsafe parts
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// used by PropertySet.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PropertyBase {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PropertyBase() : property_set_(NULL) {}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the |property_set| and property |name| so that method
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calls may be made from this class. This method is called by
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PropertySet::RegisterProperty() passing |this| for |property_set| so
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there should be no need to call it directly. If you do beware that
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no ownership or reference to |property_set| is taken so that object
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // must outlive this one.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init(PropertySet* property_set, const std::string& name);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves the name of this property, this may be useful in observers
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to avoid specifying the name in more than once place, e.g.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   void Client::PropertyChanged(const dbus::ObjectPath& object_path,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                                const std::string &property_name) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     Properties& properties = GetProperties(object_path);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     if (property_name == properties.version.name()) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       // Handle version property changing
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& name() const { return name_; }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Method used by PropertySet to retrieve the value from a MessageReader,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no knowledge of the contained type is required, this method returns
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // true if its expected type was found, false if not.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementation provided by specialization.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool PopValueFromReader(MessageReader*) = 0;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Method used by PropertySet to append the set value to a MessageWriter,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no knowledge of the contained type is required.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementation provided by specialization.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AppendSetValueToWriter(MessageWriter* writer) = 0;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Method used by test and stub implementations of dbus::PropertySet::Set
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to replace the property value with the set value without using a
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dbus::MessageReader.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReplaceValueWithSetValue() = 0;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves the associated property set.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PropertySet* property_set() { return property_set_; }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pointer to the PropertySet instance that this instance is a member of,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no ownership is taken and |property_set_| must outlive this class.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PropertySet* property_set_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Name of the property.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PropertyBase);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PropertySet groups a collection of properties for a remote object
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// together into a single structure, fixing their types and name such
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that calls made through it are type-safe.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Clients always sub-class this to add the properties, and should always
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provide a constructor that chains up to this and then calls
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RegisterProperty() for each property defined.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After creation, client code should call ConnectSignals() and most likely
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetAll() to seed initial values and update as changes occur.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CHROME_DBUS_EXPORT PropertySet {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for changes to cached values of properties, either notified
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // via signal, or as a result of calls to Get() and GetAll(). The |name|
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // argument specifies the name of the property changed.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(const std::string& name)> PropertyChangedCallback;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constructs a property set, where |object_proxy| specifies the proxy for
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the/ remote object that these properties are for, care should be taken to
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ensure that this object does not outlive the lifetime of the proxy;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |interface| specifies the D-Bus interface of these properties, and
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |property_changed_callback| specifies the callback for when properties
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are changed, this may be a NULL callback.
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PropertySet(ObjectProxy* object_proxy, const std::string& interface,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const PropertyChangedCallback& property_changed_callback);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destructor; we don't hold on to any references or memory that needs
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // explicit clean-up, but clang thinks we might.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PropertySet();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Registers a property, generally called from the subclass constructor;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pass the |name| of the property as used in method calls and signals,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and the pointer to the |property| member of the structure. This will
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // call the PropertyBase::Init method.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterProperty(const std::string& name, PropertyBase* property);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connects property change notification signals to the object, generally
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called immediately after the object is created and before calls to other
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // methods. Sub-classes may override to use different D-Bus signals.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ConnectSignals();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Methods connected by ConnectSignals() and called by dbus:: when
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a property is changed. Sub-classes may override if the property
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changed signal provides different arguments.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ChangedReceived(Signal*);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ChangedConnected(const std::string& interface_name,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& signal_name,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bool success);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for Get() method, |success| indicates whether or not the
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // value could be retrived, if true the new value can be obtained by
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calling value() on the property.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(bool success)> GetCallback;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Requests an updated value from the remote object for |property|
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // incurring a round-trip. |callback| will be called when the new
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // value is available. This may not be implemented by some interfaces,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and may be overriden by sub-classes if interfaces use different
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // method calls.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Get(PropertyBase* property, GetCallback callback);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnGet(PropertyBase* property, GetCallback callback,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     Response* response);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Queries the remote object for values of all properties and updates
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initial values. Sub-classes may override to use a different D-Bus
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // method, or if the remote object does not support retrieving all
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // properties, either ignore or obtain each property value individually.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetAll();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnGetAll(Response* response);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for Set() method, |success| indicates whether or not the
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // new property value was accepted by the remote object.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(bool success)> SetCallback;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Requests that the remote object for |property| change the property to
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // its new value. |callback| will be called to indicate the success or
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // failure of the request, however the new value may not be available
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // depending on the remote object. This method may be overridden by
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sub-classes if interfaces use different method calls.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Set(PropertyBase* property, SetCallback callback);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSet(PropertyBase* property, SetCallback callback,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     Response* response);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update properties by reading an array of dictionary entries, each
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // containing a string with the name and a variant with the value, from
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |message_reader|. Returns false if message is in incorrect format.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool UpdatePropertiesFromReader(MessageReader* reader);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates a single property by reading a string with the name and a
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // variant with the value from |message_reader|. Returns false if message
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is in incorrect format, or property type doesn't match.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool UpdatePropertyFromReader(MessageReader* reader);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calls the property changed callback passed to the constructor, used
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by sub-classes that do not call UpdatePropertiesFromReader() or
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UpdatePropertyFromReader(). Takes the |name| of the changed property.
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyPropertyChanged(const std::string& name);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves the object proxy this property set was initialized with,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // provided for sub-classes overriding methods that make D-Bus calls
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and for Property<>. Not permitted with const references to this class.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* object_proxy() { return object_proxy_; }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves the interface of this property set.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& interface() const { return interface_; }
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get a weak pointer to this property set, provided so that sub-classes
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // overriding methods that make D-Bus calls may use the existing (or
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // override) callbacks without providing their own weak pointer factory.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtr<PropertySet> GetWeakPtr() {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return weak_ptr_factory_.GetWeakPtr();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pointer to object proxy for making method calls, no ownership is taken
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so this must outlive this class.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObjectProxy* object_proxy_;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Interface of property, e.g. "org.chromium.ExampleService", this is
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // distinct from the interface of the method call itself which is the
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // general D-Bus Properties interface "org.freedesktop.DBus.Properties".
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string interface_;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback for property changes.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PropertyChangedCallback property_changed_callback_;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map of properties (as PropertyBase*) defined in the structure to
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // names as used in D-Bus method calls and signals. The base pointer
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // restricts property access via this map to type-unsafe and non-specific
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // actions only.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<const std::string, PropertyBase*> PropertiesMap;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PropertiesMap properties_map_;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Weak pointer factory as D-Bus callbacks may last longer than these
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // objects.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<PropertySet> weak_ptr_factory_;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PropertySet);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Property template, this defines the type-specific and type-safe methods
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of properties that can be accessed as members of a PropertySet structure.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Properties provide a cached value that has an initial sensible default
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// until the reply to PropertySet::GetAll() is retrieved and is updated by
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// all calls to that method, PropertySet::Get() and property changed signals
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// also handled by PropertySet. It can be obtained by calling value() on the
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// property.
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is recommended that this cached value be used where necessary, with
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// code using PropertySet::PropertyChangedCallback to be notified of changes,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rather than incurring a round-trip to the remote object for each property
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// access.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Where a round-trip is necessary, the Get() method is provided. And to
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// update the remote object value, the Set() method is also provided; these
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// both simply call methods on PropertySet.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handling of particular D-Bus types is performed via specialization,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// typically the PopValueFromReader() and AppendSetValueToWriter() methods
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will need to be provided, and in rare cases a constructor to provide a
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// default value. Specializations for basic D-Bus types, strings, object
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// paths and arrays are provided for you.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CHROME_DBUS_EXPORT Property : public PropertyBase {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Property() {}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves the cached value.
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const T& value() const { return value_; }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Requests an updated value from the remote object incurring a
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // round-trip. |callback| will be called when the new value is available.
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This may not be implemented by some interfaces.
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Get(dbus::PropertySet::GetCallback callback) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    property_set()->Get(this, callback);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Requests that the remote object change the property value to |value|,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |callback| will be called to indicate the success or failure of the
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request, however the new value may not be available depending on the
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // remote object.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Set(const T& value, dbus::PropertySet::SetCallback callback) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_value_ = value;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    property_set()->Set(this, callback);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Method used by PropertySet to retrieve the value from a MessageReader,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no knowledge of the contained type is required, this method returns
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // true if its expected type was found, false if not.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool PopValueFromReader(MessageReader*);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Method used by PropertySet to append the set value to a MessageWriter,
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no knowledge of the contained type is required.
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementation provided by specialization.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AppendSetValueToWriter(MessageWriter* writer);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Method used by test and stub implementations of dbus::PropertySet::Set
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to replace the property value with the set value without using a
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dbus::MessageReader.
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ReplaceValueWithSetValue() {
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    value_ = set_value_;
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    property_set()->NotifyPropertyChanged(name());
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Method used by test and stub implementations to directly set the
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // value of a property.
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ReplaceValue(const T& value) {
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    value_ = value;
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    property_set()->NotifyPropertyChanged(name());
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Current cached value of the property.
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T value_;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Replacement value of the property.
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T set_value_;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> Property<uint8>::Property();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<uint8>::PopValueFromReader(MessageReader* reader);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<uint8>::AppendSetValueToWriter(MessageWriter* writer);
4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<uint8>;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> Property<bool>::Property();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<bool>::PopValueFromReader(MessageReader* reader);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<bool>::AppendSetValueToWriter(MessageWriter* writer);
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<bool>;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> Property<int16>::Property();
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<int16>::PopValueFromReader(MessageReader* reader);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<int16>::AppendSetValueToWriter(MessageWriter* writer);
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<int16>;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> Property<uint16>::Property();
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<uint16>::PopValueFromReader(MessageReader* reader);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<uint16>::AppendSetValueToWriter(
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter* writer);
4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<uint16>;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> Property<int32>::Property();
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<int32>::PopValueFromReader(MessageReader* reader);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<int32>::AppendSetValueToWriter(MessageWriter* writer);
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<int32>;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> Property<uint32>::Property();
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<uint32>::PopValueFromReader(MessageReader* reader);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<uint32>::AppendSetValueToWriter(
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter* writer);
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<uint32>;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> Property<int64>::Property();
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<int64>::PopValueFromReader(MessageReader* reader);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<int64>::AppendSetValueToWriter(MessageWriter* writer);
4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<int64>;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> Property<uint64>::Property();
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<uint64>::PopValueFromReader(MessageReader* reader);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<uint64>::AppendSetValueToWriter(
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter* writer);
4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<uint64>;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> Property<double>::Property();
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<double>::PopValueFromReader(MessageReader* reader);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<double>::AppendSetValueToWriter(
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter* writer);
4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<double>;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<std::string>::PopValueFromReader(
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader* reader);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<std::string>::AppendSetValueToWriter(
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter* writer);
4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<std::string>;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<ObjectPath>::PopValueFromReader(
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader* reader);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<ObjectPath>::AppendSetValueToWriter(
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter* writer);
4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<ObjectPath>;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<std::vector<std::string> >::PopValueFromReader(
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader* reader);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<std::vector<std::string> >::AppendSetValueToWriter(
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter* writer);
4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<std::vector<std::string> >;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> bool Property<std::vector<ObjectPath> >::PopValueFromReader(
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReader* reader);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> void Property<std::vector<ObjectPath> >::AppendSetValueToWriter(
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWriter* writer);
4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<std::vector<ObjectPath> >;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <> bool Property<std::vector<uint8> >::PopValueFromReader(
483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MessageReader* reader);
484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <> void Property<std::vector<uint8> >::AppendSetValueToWriter(
485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MessageWriter* writer);
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)extern template class Property<std::vector<uint8> >;
487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace dbus
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // DBUS_PROPERTY_H_
491