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