1ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Use of this source code is governed by a BSD-style license that can be 3ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// found in the LICENSE file. 4ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 5ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat#ifndef DBUS_OBJECT_MANAGER_H_ 6ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat#define DBUS_OBJECT_MANAGER_H_ 7ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 80d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <stdint.h> 90d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 10ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat#include <map> 11ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/macros.h" 13ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat#include "base/memory/ref_counted.h" 14ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat#include "base/memory/weak_ptr.h" 15ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat#include "dbus/object_path.h" 16ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat#include "dbus/property.h" 17ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 18ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Newer D-Bus services implement the Object Manager interface to inform other 19ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// clients about the objects they export, the properties of those objects, and 20ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// notification of changes in the set of available objects: 21ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// http://dbus.freedesktop.org/doc/dbus-specification.html 22ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// #standard-interfaces-objectmanager 23ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 24ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// This interface is very closely tied to the Properties interface, and uses 25ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// even more levels of nested dictionaries and variants. In addition to 26ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// simplifying implementation, since there tends to be a single object manager 27ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// per service, spanning the complete set of objects an interfaces available, 28ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// the classes implemented here make dealing with this interface simpler. 29ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 30ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Except where noted, use of this class replaces the need for the code 31ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// documented in dbus/property.h 32ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 33ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Client implementation classes should begin by deriving from the 34ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// dbus::ObjectManager::Interface class, and defining a Properties structure as 35ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// documented in dbus/property.h. 36ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 37ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Example: 38ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// class ExampleClient : public dbus::ObjectManager::Interface { 39ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// public: 40ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// struct Properties : public dbus::PropertySet { 41ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// dbus::Property<std::string> name; 420d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// dbus::Property<uint16_t> version; 43ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// dbus::Property<dbus::ObjectPath> parent; 44ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// dbus::Property<std::vector<std::string> > children; 45ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 46ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Properties(dbus::ObjectProxy* object_proxy, 47ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// const PropertyChangedCallback callback) 48ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// : dbus::PropertySet(object_proxy, kExampleInterface, callback) { 49ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// RegisterProperty("Name", &name); 50ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// RegisterProperty("Version", &version); 51ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// RegisterProperty("Parent", &parent); 52ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// RegisterProperty("Children", &children); 53ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// } 54ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// virtual ~Properties() {} 55ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// }; 56ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 57ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// The link between the implementation class and the object manager is set up 58ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// in the constructor and removed in the destructor; the class should maintain 59ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// a pointer to its object manager for use in other methods and establish 60ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// itself as the implementation class for its interface. 61ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 62ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Example: 63ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// explicit ExampleClient::ExampleClient(dbus::Bus* bus) 64ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// : bus_(bus), 65ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// weak_ptr_factory_(this) { 66ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// object_manager_ = bus_->GetObjectManager(kServiceName, kManagerPath); 67ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// object_manager_->RegisterInterface(kInterface, this); 68ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// } 69ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 70ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// virtual ExampleClient::~ExampleClient() { 71ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// object_manager_->UnregisterInterface(kInterface); 72ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// } 73ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 74ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// The D-Bus thread manager takes care of issuing the necessary call to 75ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// GetManagedObjects() after the implementation classes have been set up. 76ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 77ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// The object manager interface class has one abstract method that must be 78ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// implemented by the class to create Properties structures on demand. As well 79ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// as implementing this, you will want to implement a public GetProperties() 80ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// method. 81ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 82ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Example: 83ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// dbus::PropertySet* CreateProperties(dbus::ObjectProxy* object_proxy, 84ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// const std::string& interface_name) 85ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// override { 86ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Properties* properties = new Properties( 87ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// object_proxy, interface_name, 88ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// base::Bind(&PropertyChanged, 89ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// weak_ptr_factory_.GetWeakPtr(), 90ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// object_path)); 91ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// return static_cast<dbus::PropertySet*>(properties); 92ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// } 93ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 94ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Properties* GetProperties(const dbus::ObjectPath& object_path) { 95ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// return static_cast<Properties*>( 96ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// object_manager_->GetProperties(object_path, kInterface)); 97ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// } 98ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 99ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Note that unlike classes that only use dbus/property.h there is no need 100ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// to connect signals or obtain the initial values of properties. The object 101ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// manager class handles that for you. 102ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 103ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// PropertyChanged is a method of your own to notify your observers of a change 104ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// in your properties, either as a result of a signal from the Properties 105ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// interface or from the Object Manager interface. You may also wish to 106ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// implement the optional ObjectAdded and ObjectRemoved methods of the class 107ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// to likewise notify observers. 108ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 109ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// When your class needs an object proxy for a given object path, it may 110ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// obtain it from the object manager. Unlike the equivalent method on the bus 111ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// this will return NULL if the object is not known. 112ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 113ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// object_proxy = object_manager_->GetObjectProxy(object_path); 114ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// if (object_proxy) { 115ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// ... 116ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// } 117ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// 118ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// There is no need for code using your implementation class to be aware of the 119ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// use of object manager behind the scenes, the rules for updating properties 120ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// documented in dbus/property.h still apply. 121ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 122ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratnamespace dbus { 123ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 124ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratconst char kObjectManagerInterface[] = "org.freedesktop.DBus.ObjectManager"; 125ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratconst char kObjectManagerGetManagedObjects[] = "GetManagedObjects"; 126ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratconst char kObjectManagerInterfacesAdded[] = "InterfacesAdded"; 127ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratconst char kObjectManagerInterfacesRemoved[] = "InterfacesRemoved"; 128ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 129ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratclass Bus; 130ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratclass MessageReader; 131ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratclass ObjectProxy; 132ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratclass Response; 133ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratclass Signal; 134ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 135ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// ObjectManager implements both the D-Bus client components of the D-Bus 136ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// Object Manager interface, as internal methods, and a public API for 137ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat// client classes to utilize. 138ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratclass CHROME_DBUS_EXPORT ObjectManager 139ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat : public base::RefCountedThreadSafe<ObjectManager> { 140ae6a045d2239408e25198ad17e2413bdde105788Daniel Eratpublic: 141ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // ObjectManager::Interface must be implemented by any class wishing to have 142ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // its remote objects managed by an ObjectManager. 143ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat class Interface { 144ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat public: 145ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat virtual ~Interface() {} 146ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 147ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called by ObjectManager to create a Properties structure for the remote 148ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // D-Bus object identified by |object_path| and accessibile through 149ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // |object_proxy|. The D-Bus interface name |interface_name| is that passed 150ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // to RegisterInterface() by the implementation class. 151ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // 152ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // The implementation class should create and return an instance of its own 153ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // subclass of dbus::PropertySet; ObjectManager will then connect signals 154ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // and update the properties from its own internal message reader. 155ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat virtual PropertySet* CreateProperties( 156ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat ObjectProxy *object_proxy, 157ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const dbus::ObjectPath& object_path, 158ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const std::string& interface_name) = 0; 159ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 160ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called by ObjectManager to inform the implementation class that an 161ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // object has been added with the path |object_path|. The D-Bus interface 162ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // name |interface_name| is that passed to RegisterInterface() by the 163ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // implementation class. 164ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // 165ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // If a new object implements multiple interfaces, this method will be 166ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // called on each interface implementation with differing values of 167ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // |interface_name| as appropriate. An implementation class will only 168ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // receive multiple calls if it has registered for multiple interfaces. 16994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez virtual void ObjectAdded(const ObjectPath& /*object_path*/, 17094ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez const std::string& /*interface_name*/) {} 171ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 172ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called by ObjectManager to inform the implementation class than an 173ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // object with the path |object_path| has been removed. Ths D-Bus interface 174ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // name |interface_name| is that passed to RegisterInterface() by the 175ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // implementation class. Multiple interfaces are handled as with 176ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // ObjectAdded(). 177ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // 178ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // This method will be called before the Properties structure and the 179ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // ObjectProxy object for the given interface are cleaned up, it is safe 180ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // to retrieve them during removal to vary processing. 18194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez virtual void ObjectRemoved(const ObjectPath& /*object_path*/, 18294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez const std::string& /*interface_name*/) {} 183ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat }; 184ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 185ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Client code should use Bus::GetObjectManager() instead of this constructor. 186ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat ObjectManager(Bus* bus, 187ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const std::string& service_name, 188ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const ObjectPath& object_path); 189ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 190ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Register a client implementation class |interface| for the given D-Bus 191ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // interface named in |interface_name|. That object's CreateProperties() 192ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // method will be used to create instances of dbus::PropertySet* when 193ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // required. 194ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void RegisterInterface(const std::string& interface_name, 195ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat Interface* interface); 196ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 197ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Unregister the implementation class for the D-Bus interface named in 198ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // |interface_name|, objects and properties of this interface will be 199ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // ignored. 200ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void UnregisterInterface(const std::string& interface_name); 201ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 202ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Returns a list of object paths, in an undefined order, of objects known 203ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // to this manager. 204ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat std::vector<ObjectPath> GetObjects(); 205ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 206ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Returns the list of object paths, in an undefined order, of objects 207ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // implementing the interface named in |interface_name| known to this manager. 208ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat std::vector<ObjectPath> GetObjectsWithInterface( 209ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const std::string& interface_name); 210ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 211ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Returns a ObjectProxy pointer for the given |object_path|. Unlike 212ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // the equivalent method on Bus this will return NULL if the object 213ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // manager has not been informed of that object's existance. 214ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat ObjectProxy* GetObjectProxy(const ObjectPath& object_path); 215ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 216ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Returns a PropertySet* pointer for the given |object_path| and 217ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // |interface_name|, or NULL if the object manager has not been informed of 218ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // that object's existance or the interface's properties. The caller should 219ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // cast the returned pointer to the appropriate type, e.g.: 220ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // static_cast<Properties*>(GetProperties(object_path, my_interface)); 221ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat PropertySet* GetProperties(const ObjectPath& object_path, 222ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const std::string& interface_name); 223ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 224ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Instructs the object manager to refresh its list of managed objects; 225ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // automatically called by the D-Bus thread manager, there should never be 226ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // a need to call this manually. 227ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void GetManagedObjects(); 228ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 229ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Cleans up any match rules and filter functions added by this ObjectManager. 230ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // The Bus object will take care of this so you don't have to do it manually. 231ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // 232ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // BLOCKING CALL. 233ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void CleanUp(); 234ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 235ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat protected: 236ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat virtual ~ObjectManager(); 237ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 238ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat private: 239ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat friend class base::RefCountedThreadSafe<ObjectManager>; 240ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 241ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Connects the InterfacesAdded and InterfacesRemoved signals and calls 242ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // GetManagedObjects. Called from OnSetupMatchRuleAndFilterComplete. 243ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void InitializeObjects(); 244ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 245ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called from the constructor to add a match rule for PropertiesChanged 246ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // signals on the DBus thread and set up a corresponding filter function. 247ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat bool SetupMatchRuleAndFilter(); 248ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 249ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called on the origin thread once the match rule and filter have been set 250ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // up. |success| is false, if an error occurred during set up; it's true 251ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // otherwise. 252ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void OnSetupMatchRuleAndFilterComplete(bool success); 253ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 254ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called by dbus:: when a message is received. This is used to filter 255ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // PropertiesChanged signals from the correct sender and relay the event to 256ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // the correct PropertySet. 257ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat static DBusHandlerResult HandleMessageThunk(DBusConnection* connection, 258ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat DBusMessage* raw_message, 259ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void* user_data); 260ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat DBusHandlerResult HandleMessage(DBusConnection* connection, 261ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat DBusMessage* raw_message); 262ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 263ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called when a PropertiesChanged signal is received from the sender. 264ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // This method notifies the relevant PropertySet that it should update its 265ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // properties based on the received signal. Called from HandleMessage. 266ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void NotifyPropertiesChanged(const dbus::ObjectPath object_path, 267ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat Signal* signal); 268ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void NotifyPropertiesChangedHelper(const dbus::ObjectPath object_path, 269ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat Signal* signal); 270ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 271ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called by dbus:: in response to the GetManagedObjects() method call. 272ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void OnGetManagedObjects(Response* response); 273ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 274ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called by dbus:: when an InterfacesAdded signal is received and initially 275ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // connected. 276ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void InterfacesAddedReceived(Signal* signal); 277ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void InterfacesAddedConnected(const std::string& interface_name, 278ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const std::string& signal_name, 279ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat bool success); 280ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 281ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called by dbus:: when an InterfacesRemoved signal is received and 282ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // initially connected. 283ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void InterfacesRemovedReceived(Signal* signal); 284ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void InterfacesRemovedConnected(const std::string& interface_name, 285ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const std::string& signal_name, 286ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat bool success); 287ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 288ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Updates the map entry for the object with path |object_path| using the 289ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // D-Bus message in |reader|, which should consist of an dictionary mapping 290ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // interface names to properties dictionaries as recieved by both the 291ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // GetManagedObjects() method return and the InterfacesAdded() signal. 292ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void UpdateObject(const ObjectPath& object_path, MessageReader* reader); 293ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 294ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Updates the properties structure of the object with path |object_path| 295ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // for the interface named |interface_name| using the D-Bus message in 296ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // |reader| which should consist of the properties dictionary for that 297ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // interface. 298ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // 299ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Called by UpdateObjects() for each interface in the dictionary; this 300ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // method takes care of both creating the entry in the ObjectMap and 301ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // ObjectProxy if required, as well as the PropertySet instance for that 302ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // interface if necessary. 303ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void AddInterface(const ObjectPath& object_path, 304ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const std::string& interface_name, 305ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat MessageReader* reader); 306ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 307ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Removes the properties structure of the object with path |object_path| 308ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // for the interfaces named |interface_name|. 309ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // 310ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // If no further interfaces remain, the entry in the ObjectMap is discarded. 311ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void RemoveInterface(const ObjectPath& object_path, 312ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const std::string& interface_name); 313ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 314ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Removes all objects and interfaces from the object manager when 315ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // |old_owner| is not the empty string and/or re-requests the set of managed 316ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // objects when |new_owner| is not the empty string. 317ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat void NameOwnerChanged(const std::string& old_owner, 318ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat const std::string& new_owner); 319ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 320ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat Bus* bus_; 321ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat std::string service_name_; 322ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat std::string service_name_owner_; 323ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat std::string match_rule_; 324ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat ObjectPath object_path_; 325ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat ObjectProxy* object_proxy_; 326ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat bool setup_success_; 327ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat bool cleanup_called_; 328ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 329ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Maps the name of an interface to the implementation class used for 330ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // instantiating PropertySet structures for that interface's properties. 331ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat typedef std::map<std::string, Interface*> InterfaceMap; 332ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat InterfaceMap interface_map_; 333ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 334ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Each managed object consists of a ObjectProxy used to make calls 335ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // against that object and a collection of D-Bus interface names and their 336ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // associated PropertySet structures. 337ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat struct Object { 338ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat Object(); 339ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat ~Object(); 340ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 341ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat ObjectProxy* object_proxy; 342ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 343ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Maps the name of an interface to the specific PropertySet structure 344ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // of that interface's properties. 345ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat typedef std::map<const std::string, PropertySet*> PropertiesMap; 346ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat PropertiesMap properties_map; 347ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat }; 348ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 349ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Maps the object path of an object to the Object structure. 350ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat typedef std::map<const ObjectPath, Object*> ObjectMap; 351ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat ObjectMap object_map_; 352ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 353ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Weak pointer factory for generating 'this' pointers that might live longer 354ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // than we do. 355ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // Note: This should remain the last member so it'll be destroyed and 356ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat // invalidate its weak pointers before any other members are destroyed. 357ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat base::WeakPtrFactory<ObjectManager> weak_ptr_factory_; 358ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 359ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat DISALLOW_COPY_AND_ASSIGN(ObjectManager); 360ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat}; 361ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 362ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat} // namespace dbus 363ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat 364ae6a045d2239408e25198ad17e2413bdde105788Daniel Erat#endif // DBUS_OBJECT_MANAGER_H_ 365