buffet: Add ExportedObjectManager delegate This makes it easy to export an object manager. We'll use this very soon to implement the ObjectManager interface on the root Buffet object. BUG=chromium:359190 TEST=Unittests Change-Id: I19d2da33b81557431c5787937c49a18e7d7bacb2 Reviewed-on: https://chromium-review.googlesource.com/196387 Reviewed-by: Alex Vakulenko <avakulenko@chromium.org> Commit-Queue: Christopher Wiley <wiley@chromium.org> Tested-by: Christopher Wiley <wiley@chromium.org>
diff --git a/buffet/exported_object_manager.h b/buffet/exported_object_manager.h new file mode 100644 index 0000000..14a0b1a --- /dev/null +++ b/buffet/exported_object_manager.h
@@ -0,0 +1,118 @@ +// Copyright 2014 The Chromium OS 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 EXPORTED_OBJECT_MANAGER_H_ +#define EXPORTED_OBJECT_MANAGER_H_ + +#include <map> +#include <string> + +#include <base/memory/weak_ptr.h> +#include <dbus/bus.h> +#include <dbus/exported_object.h> +#include <dbus/object_path.h> + +#include "buffet/exported_property_set.h" + +namespace buffet { + +namespace dbus_utils { + +// ExportedObjectManager is a delegate that implements the +// org.freedesktop.DBus.ObjectManager interface on behalf of another +// object. It handles sending signals when new interfaces are added. +// +// This class is very similar to the ExportedPropertySet class, except that +// it allows objects to expose an object manager interface rather than the +// properties interface. +// +// Example usage: +// +// class ExampleObjectManager { +// public: +// ExampleObjectManager(dbus::Bus* bus) +// : object_manager_(bus, "/my/objects/path") { } +// +// void Init(const OnInitFinish& cb) { object_manager_.Init(cb); } +// void ClaimInterface(const dbus::ObjectPath& path, +// const std::string& interface_name, +// const PropertyWriter& writer) { +// object_manager_->ClaimInterface(...); +// } +// void ReleaseInterface(const dbus::ObjectPath& path, +// const std::string& interface_name) { +// object_manager_->ReleaseInterface(...); +// } +// +// private: +// ExportedObjectManager object_manager_; +// }; +// +// class MyObjectClaimingAnInterface { +// public: +// MyObjectClaimingAnInterface(ExampleObjectManager* object_manager) +// : object_manager_(object_manager) {} +// +// void OnInitFinish(bool success) { +// if (!success) { /* handle that */ } +// object_manager_->ClaimInterface( +// my_path_, my_interface_, my_properties_.GetWriter()); +// } +// +// private: +// struct Properties : public ExportedPropertySet { +// public: +// /* Lots of interesting properties. */ +// }; +// +// Properties my_properties_; +// ExampleObjectManager* object_manager_; +// }; +class ExportedObjectManager { + public: + // Writes a dictionary of property name to property value variants to writer. + typedef base::Callback<void(dbus::MessageWriter* writer)> PropertyWriter; + typedef base::Callback<void(bool success)> OnInitFinish; + typedef std::map<std::string, PropertyWriter> InterfaceProperties; + + ExportedObjectManager(dbus::Bus* bus, const dbus::ObjectPath& path); + + // Registers methods implementing the ObjectManager interface on the object + // exported on the path given in the constructor. Must be called on the + // origin thread. + void Init(const OnInitFinish& cb); + + // Trigger a signal that |path| has added an interface |interface_name| + // with properties as given by |writer|. + void ClaimInterface(const dbus::ObjectPath& path, + const std::string& interface_name, + const PropertyWriter& writer); + + // Trigger a signal that |path| has removed an interface |interface_name|. + void ReleaseInterface(const dbus::ObjectPath& path, + const std::string& interface_name); + + private: + void HandleGetManagedObjects( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) const; + + // Both |bus_| and |exported_object_| outlive *this. + dbus::Bus* const bus_; + dbus::ExportedObject* const exported_object_; + // Tracks all objects currently known to the ExportedObjectManager. + std::map<dbus::ObjectPath, InterfaceProperties> registered_objects_; + + // We're going to register DBus callbacks that will outlive ourselves. + // These callbacks get scheduled on the origin thread. + base::WeakPtrFactory<ExportedObjectManager> weak_ptr_factory_; + friend class ExportedObjectManagerTest; + DISALLOW_COPY_AND_ASSIGN(ExportedObjectManager); +}; + +} // namespace dbus_utils + +} // namespace buffet + +#endif // EXPORTED_OBJECT_MANAGER_H_