Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2164)

Unified Diff: dbus/object_manager.h

Issue 12491014: Support D-Bus Object Manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review comments Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « dbus/mock_object_manager.cc ('k') | dbus/object_manager.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dbus/object_manager.h
diff --git a/dbus/object_manager.h b/dbus/object_manager.h
new file mode 100644
index 0000000000000000000000000000000000000000..42ff9eca65197a8290c2753d0b824869fd512e7e
--- /dev/null
+++ b/dbus/object_manager.h
@@ -0,0 +1,310 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// 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 <map>
+
+#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> 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);
+// }
+//
+// The D-Bus thread manager takes care of issuing the necessary call to
+// GetManagedObjects() after the implementation classes have been set up.
+//
+// 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::Bind(&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[] = "org.freedesktop.DBus.ObjectManager";
+const char kObjectManagerGetManagedObjects[] = "GetManagedObjects";
+const char kObjectManagerInterfacesAdded[] = "InterfacesAdded";
+const char kObjectManagerInterfacesRemoved[] = "InterfacesRemoved";
+
+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
+ : public base::RefCountedThreadSafe<ObjectManager> {
+public:
+ // ObjectManager::Interface must be implemented by any class wishing to have
+ // its remote objects managed by an ObjectManager.
+ class Interface {
+ public:
+ virtual ~Interface() {}
+
+ // Called by ObjectManager to create a Properties structure for the remote
+ // D-Bus object identified by |object_path| and accessibile through
+ // |object_proxy|. The D-Bus interface name |interface_name| is that passed
+ // to RegisterInterface() by the implementation class.
+ //
+ // The implementation class should create and return an instance of its own
+ // subclass of dbus::PropertySet; ObjectManager will then connect signals
+ // and update the properties from its own internal message reader.
+ virtual PropertySet* CreateProperties(
+ ObjectProxy *object_proxy,
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) = 0;
+
+ // Called by ObjectManager to inform the implementation class that an
+ // object has been added with the path |object_path|. The D-Bus interface
+ // name |interface_name| is that passed to RegisterInterface() by the
+ // implementation class.
+ //
+ // If a new object implements multiple interfaces, this method will be
+ // called on each interface implementation with differing values of
+ // |interface_name| as appropriate. An implementation class will only
+ // receive multiple calls if it has registered for multiple interfaces.
+ virtual void ObjectAdded(const ObjectPath& object_path,
+ const std::string& interface_name) { }
+
+ // Called by ObjectManager to inform the implementation class than an
+ // object with the path |object_path| has been removed. Ths D-Bus interface
+ // name |interface_name| is that passed to RegisterInterface() by the
+ // implementation class. Multiple interfaces are handled as with
+ // ObjectAdded().
+ //
+ // This method will be called before the Properties structure and the
+ // ObjectProxy object for the given interface are cleaned up, it is safe
+ // to retrieve them during removal to vary processing.
+ virtual void ObjectRemoved(const ObjectPath& object_path,
+ const std::string& interface_name) { }
satorux1 2013/03/22 01:56:27 Looking at the other patch, ObjectAdded() and Obje
keybuk 2013/03/25 16:00:10 I didn't feel it should be mandatory, it just happ
+ };
+
+ // Client code should use Bus::GetObjectManager() instead of this constructor.
+ ObjectManager(Bus* bus,
+ const std::string& service_name,
+ const ObjectPath& object_path);
+ virtual ~ObjectManager();
+
+ // Register a client implementation class |interface| for the given D-Bus
+ // interface named in |interface_name|. That object's CreateProperties()
+ // method will be used to create instances of dbus::PropertySet* when
+ // required.
+ void RegisterInterface(const std::string& interface_name,
+ Interface* interface);
+
+ // Unregister the implementation class for the D-Bus interface named in
+ // |interface_name|, objects and properties of this interface will be
+ // ignored.
+ void UnregisterInterface(const std::string& interface_name);
+
+ // Returns a list of object paths, in an undefined order, of objects known
+ // to this manager.
+ std::vector<ObjectPath> GetObjects();
+
+ // Returns the list of object paths, in an undefined order, of objects
+ // implementing the interface named in |interface_name| known to this manager.
+ std::vector<ObjectPath> GetObjectsWithInterface(
+ const std::string& interface_name);
+
+ // Returns a ObjectProxy pointer for the given |object_path|. Unlike
+ // the equivalent method on Bus this will return NULL if the object
+ // manager has not been informed of that object's existance.
+ ObjectProxy* GetObjectProxy(const ObjectPath& object_path);
+
+ // Returns a PropertySet* pointer for the given |object_path| and
+ // |interface_name|, or NULL if the object manager has not been informed of
+ // that object's existance or the interface's properties. The caller should
+ // cast the returned pointer to the appropriate type, e.g.:
+ // static_cast<Properties*>(GetProperties(object_path, my_interface));
+ PropertySet* GetProperties(const ObjectPath& object_path,
+ const std::string& interface_name);
+
+ // Instructs the object manager to refresh its list of managed objects;
+ // automatically called by the D-Bus thread manager, there should never be
+ // a need to call this manually.
+ void GetManagedObjects();
satorux1 2013/03/22 01:41:33 The message (list of list of dictionaries) we'll r
+
+ private:
+ friend class base::RefCountedThreadSafe<ObjectManager>;
+
+ // Called by dbus:: in response to the GetManagedObjects() method call.
+ void OnGetManagedObjects(Response* response);
+
+ // Called by dbus:: when an InterfacesAdded signal is received and initially
+ // connected.
+ void InterfacesAddedReceived(Signal* signal);
+ void InterfacesAddedConnected(const std::string& interface_name,
+ const std::string& signal_name,
+ bool success);
+
+ // Called by dbus:: when an InterfacesRemoved signal is received and
+ // initially connected.
+ void InterfacesRemovedReceived(Signal* signal);
+ void InterfacesRemovedConnected(const std::string& interface_name,
+ const std::string& signal_name,
+ bool success);
+
+ // Updates the map entry for the object with path |object_path| using the
+ // D-Bus message in |reader|, which should consist of an dictionary mapping
+ // interface names to properties dictionaries as recieved by both the
+ // GetManagedObjects() method return and the InterfacesAdded() signal.
satorux1 2013/03/22 01:41:33 Likewise, having some example of the input message
+ void UpdateObject(const ObjectPath& object_path, MessageReader* reader);
+
+ // Updates the properties structure of the object with path |object_path|
+ // for the interface named |interface_name| using the D-Bus message in
+ // |reader| which should consist of the properties dictionary for that
+ // interface.
+ //
+ // Called by UpdateObjects() for each interface in the dictionary; this
+ // method takes care of both creating the entry in the ObjectMap and
+ // ObjectProxy if required, as well as the PropertySet instance for that
+ // interface if necessary.
+ void AddInterface(const ObjectPath& object_path,
+ const std::string& interface_name,
+ MessageReader* reader);
+
+ // Removes the properties structure of the object with path |object_path|
+ // for the interfaces named |interface_name|.
+ //
+ // If no further interfaces remain, the entry in the ObjectMap is discarded.
+ void RemoveInterface(const ObjectPath& object_path,
+ const std::string& interface_name);
+
+ Bus* bus_;
satorux1 2013/03/22 01:41:33 Maybe add a comment about the ownership: Bus* bus
+ std::string service_name_;
+ ObjectPath object_path_;
+ ObjectProxy* object_proxy_;
satorux1 2013/03/22 01:41:33 ditto
+
+ // Maps the name of an interface to the implementation class used for
+ // instantiating PropertySet structures for that interface's properties.
+ typedef std::map<std::string, Interface*> InterfaceMap;
+ InterfaceMap interface_map_;
+
+ // Each managed object consists of a ObjectProxy used to make calls
+ // against that object and a collection of D-Bus interface names and their
+ // associated PropertySet structures.
+ struct Object {
+ ObjectProxy* object_proxy;
+
+ // Maps the name of an interface to the specific PropertySet structure
+ // of that interface's properties.
+ typedef std::map<const std::string, PropertySet*> PropertiesMap;
+ PropertiesMap properties_map;
+ };
+
+ // Maps the object path of an object to the Object structure.
+ typedef std::map<const ObjectPath, Object*> ObjectMap;
+ ObjectMap object_map_;
+
+ // Weak pointer factory for generating 'this' pointers that might live longer
+ // than we do.
+ // Note: This should remain the last member so it'll be destroyed and
+ // invalidate its weak pointers before any other members are destroyed.
+ base::WeakPtrFactory<ObjectManager> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ObjectManager);
+};
+
+} // namespace dbus
+
+#endif // DBUS_OBJECT_MANAGER_H_
« no previous file with comments | « dbus/mock_object_manager.cc ('k') | dbus/object_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698