1 // Copyright 2014 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef LIBBRILLO_BRILLO_DBUS_EXPORTED_OBJECT_MANAGER_H_ 6 #define LIBBRILLO_BRILLO_DBUS_EXPORTED_OBJECT_MANAGER_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include <base/callback.h> 13 #include <base/memory/weak_ptr.h> 14 #include <brillo/brillo_export.h> 15 #include <brillo/dbus/dbus_object.h> 16 #include <brillo/dbus/exported_property_set.h> 17 #include <brillo/variant_dictionary.h> 18 #include <dbus/bus.h> 19 #include <dbus/exported_object.h> 20 #include <dbus/message.h> 21 #include <dbus/object_path.h> 22 23 namespace brillo { 24 25 namespace dbus_utils { 26 27 // ExportedObjectManager is a delegate that implements the 28 // org.freedesktop.DBus.ObjectManager interface on behalf of another 29 // object. It handles sending signals when new interfaces are added. 30 // 31 // This class is very similar to the ExportedPropertySet class, except that 32 // it allows objects to expose an object manager interface rather than the 33 // properties interface. 34 // 35 // Example usage: 36 // 37 // class ExampleObjectManager { 38 // public: 39 // ExampleObjectManager(dbus::Bus* bus) 40 // : object_manager_(bus, "/my/objects/path") { } 41 // 42 // void RegisterAsync(const CompletionAction& cb) { 43 // object_manager_.RegisterAsync(cb); 44 // } 45 // void ClaimInterface(const dbus::ObjectPath& path, 46 // const std::string& interface_name, 47 // const ExportedPropertySet::PropertyWriter& writer) { 48 // object_manager_->ClaimInterface(...); 49 // } 50 // void ReleaseInterface(const dbus::ObjectPath& path, 51 // const std::string& interface_name) { 52 // object_manager_->ReleaseInterface(...); 53 // } 54 // 55 // private: 56 // ExportedObjectManager object_manager_; 57 // }; 58 // 59 // class MyObjectClaimingAnInterface { 60 // public: 61 // MyObjectClaimingAnInterface(ExampleObjectManager* object_manager) 62 // : object_manager_(object_manager) {} 63 // 64 // void OnInitFinish(bool success) { 65 // if (!success) { /* handle that */ } 66 // object_manager_->ClaimInterface( 67 // my_path_, my_interface_, my_properties_.GetWriter()); 68 // } 69 // 70 // private: 71 // struct Properties : public ExportedPropertySet { 72 // public: 73 // /* Lots of interesting properties. */ 74 // }; 75 // 76 // Properties my_properties_; 77 // ExampleObjectManager* object_manager_; 78 // }; 79 class BRILLO_EXPORT ExportedObjectManager 80 : public base::SupportsWeakPtr<ExportedObjectManager> { 81 public: 82 using ObjectMap = 83 std::map<dbus::ObjectPath, std::map<std::string, VariantDictionary>>; 84 using InterfaceProperties = 85 std::map<std::string, ExportedPropertySet::PropertyWriter>; 86 87 ExportedObjectManager(scoped_refptr<dbus::Bus> bus, 88 const dbus::ObjectPath& path); 89 virtual ~ExportedObjectManager() = default; 90 91 // Registers methods implementing the ObjectManager interface on the object 92 // exported on the path given in the constructor. Must be called on the 93 // origin thread. 94 virtual void RegisterAsync( 95 const brillo::dbus_utils::AsyncEventSequencer::CompletionAction& 96 completion_callback); 97 98 // Trigger a signal that |path| has added an interface |interface_name| 99 // with properties as given by |writer|. 100 virtual void ClaimInterface( 101 const dbus::ObjectPath& path, 102 const std::string& interface_name, 103 const ExportedPropertySet::PropertyWriter& writer); 104 105 // Trigger a signal that |path| has removed an interface |interface_name|. 106 virtual void ReleaseInterface(const dbus::ObjectPath& path, 107 const std::string& interface_name); 108 109 const scoped_refptr<dbus::Bus>& GetBus() const { return bus_; } 110 111 private: 112 BRILLO_PRIVATE ObjectMap HandleGetManagedObjects(); 113 114 scoped_refptr<dbus::Bus> bus_; 115 brillo::dbus_utils::DBusObject dbus_object_; 116 // Tracks all objects currently known to the ExportedObjectManager. 117 std::map<dbus::ObjectPath, InterfaceProperties> registered_objects_; 118 119 using SignalInterfacesAdded = 120 DBusSignal<dbus::ObjectPath, std::map<std::string, VariantDictionary>>; 121 using SignalInterfacesRemoved = 122 DBusSignal<dbus::ObjectPath, std::vector<std::string>>; 123 124 std::weak_ptr<SignalInterfacesAdded> signal_itf_added_; 125 std::weak_ptr<SignalInterfacesRemoved> signal_itf_removed_; 126 127 friend class ExportedObjectManagerTest; 128 DISALLOW_COPY_AND_ASSIGN(ExportedObjectManager); 129 }; 130 131 } // namespace dbus_utils 132 133 } // namespace brillo 134 135 #endif // LIBBRILLO_BRILLO_DBUS_EXPORTED_OBJECT_MANAGER_H_ 136