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