// Copyright 2013 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef DBUS_OBJECT_MANAGER_H_ #define DBUS_OBJECT_MANAGER_H_ #include <stdint.h> #include <map> #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "dbus/object_path.h" #include "dbus/property.h" // Newer D-Bus services implement the Object Manager interface to inform other // clients about the objects they export, the properties of those objects, and // notification of changes in the set of available objects: // http://dbus.freedesktop.org/doc/dbus-specification.html // #standard-interfaces-objectmanager // // This interface is very closely tied to the Properties interface, and uses // even more levels of nested dictionaries and variants. In addition to // simplifying implementation, since there tends to be a single object manager // per service, spanning the complete set of objects an interfaces available, // the classes implemented here make dealing with this interface simpler. // // Except where noted, use of this class replaces the need for the code // documented in dbus/property.h // // Client implementation classes should begin by deriving from the // dbus::ObjectManager::Interface class, and defining a Properties structure as // documented in dbus/property.h. // // Example: // class ExampleClient : public dbus::ObjectManager::Interface { // public: // struct Properties : public dbus::PropertySet { // dbus::Property<std::string> name; // dbus::Property<uint16_t> version; // dbus::Property<dbus::ObjectPath> parent; // dbus::Property<std::vector<std::string>> children; // // Properties(dbus::ObjectProxy* object_proxy, // const PropertyChangedCallback callback) // : dbus::PropertySet(object_proxy, kExampleInterface, callback) { // RegisterProperty("Name", &name); // RegisterProperty("Version", &version); // RegisterProperty("Parent", &parent); // RegisterProperty("Children", &children); // } // virtual ~Properties() {} // }; // // The link between the implementation class and the object manager is set up // in the constructor and removed in the destructor; the class should maintain // a pointer to its object manager for use in other methods and establish // itself as the implementation class for its interface. // // Example: // explicit ExampleClient::ExampleClient(dbus::Bus* bus) // : bus_(bus), // weak_ptr_factory_(this) { // object_manager_ = bus_->GetObjectManager(kServiceName, kManagerPath); // object_manager_->RegisterInterface(kInterface, this); // } // // virtual ExampleClient::~ExampleClient() { // object_manager_->UnregisterInterface(kInterface); // } // // This class calls GetManagedObjects() asynchronously after the remote service // becomes available and additionally refreshes managed objects after the // service stops or restarts. // // The object manager interface class has one abstract method that must be // implemented by the class to create Properties structures on demand. As well // as implementing this, you will want to implement a public GetProperties() // method. // // Example: // dbus::PropertySet* CreateProperties(dbus::ObjectProxy* object_proxy, // const std::string& interface_name) // override { // Properties* properties = new Properties( // object_proxy, interface_name, // base::BindRepeating(&PropertyChanged, // weak_ptr_factory_.GetWeakPtr(), // object_path)); // return static_cast<dbus::PropertySet*>(properties); // } // // Properties* GetProperties(const dbus::ObjectPath& object_path) { // return static_cast<Properties*>( // object_manager_->GetProperties(object_path, kInterface)); // } // // Note that unlike classes that only use dbus/property.h there is no need // to connect signals or obtain the initial values of properties. The object // manager class handles that for you. // // PropertyChanged is a method of your own to notify your observers of a change // in your properties, either as a result of a signal from the Properties // interface or from the Object Manager interface. You may also wish to // implement the optional ObjectAdded and ObjectRemoved methods of the class // to likewise notify observers. // // When your class needs an object proxy for a given object path, it may // obtain it from the object manager. Unlike the equivalent method on the bus // this will return NULL if the object is not known. // // object_proxy = object_manager_->GetObjectProxy(object_path); // if (object_proxy) { // ... // } // // There is no need for code using your implementation class to be aware of the // use of object manager behind the scenes, the rules for updating properties // documented in dbus/property.h still apply. namespace dbus { const char kObjectManagerInterface[] = …; const char kObjectManagerGetManagedObjects[] = …; const char kObjectManagerInterfacesAdded[] = …; const char kObjectManagerInterfacesRemoved[] = …; class Bus; class MessageReader; class ObjectProxy; class Response; class Signal; // ObjectManager implements both the D-Bus client components of the D-Bus // Object Manager interface, as internal methods, and a public API for // client classes to utilize. class CHROME_DBUS_EXPORT ObjectManager final : public base::RefCountedThreadSafe<ObjectManager> { … }; } // namespace dbus #endif // DBUS_OBJECT_MANAGER_H_