diff options
Diffstat (limited to 'brillo/dbus/exported_object_manager.cc')
-rw-r--r-- | brillo/dbus/exported_object_manager.cc | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/brillo/dbus/exported_object_manager.cc b/brillo/dbus/exported_object_manager.cc new file mode 100644 index 0000000..61dae68 --- /dev/null +++ b/brillo/dbus/exported_object_manager.cc @@ -0,0 +1,105 @@ +// 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. + +#include <brillo/dbus/exported_object_manager.h> + +#include <vector> + +#include <brillo/dbus/async_event_sequencer.h> +#include <dbus/object_manager.h> + +using brillo::dbus_utils::AsyncEventSequencer; + +namespace brillo { + +namespace dbus_utils { + +ExportedObjectManager::ExportedObjectManager(scoped_refptr<dbus::Bus> bus, + const dbus::ObjectPath& path) + : bus_(bus), dbus_object_(nullptr, bus, path) { +} + +void ExportedObjectManager::RegisterAsync( + const AsyncEventSequencer::CompletionAction& completion_callback) { + VLOG(1) << "Registering object manager"; + bus_->AssertOnOriginThread(); + DBusInterface* itf = + dbus_object_.AddOrGetInterface(dbus::kObjectManagerInterface); + itf->AddSimpleMethodHandler(dbus::kObjectManagerGetManagedObjects, + base::Unretained(this), + &ExportedObjectManager::HandleGetManagedObjects); + + signal_itf_added_ = itf->RegisterSignalOfType<SignalInterfacesAdded>( + dbus::kObjectManagerInterfacesAdded); + signal_itf_removed_ = itf->RegisterSignalOfType<SignalInterfacesRemoved>( + dbus::kObjectManagerInterfacesRemoved); + dbus_object_.RegisterAsync(completion_callback); +} + +void ExportedObjectManager::ClaimInterface( + const dbus::ObjectPath& path, + const std::string& interface_name, + const ExportedPropertySet::PropertyWriter& property_writer) { + bus_->AssertOnOriginThread(); + // We're sending signals that look like: + // org.freedesktop.DBus.ObjectManager.InterfacesAdded ( + // OBJPATH object_path, + // DICT<STRING,DICT<STRING,VARIANT>> interfaces_and_properties); + VariantDictionary property_dict; + property_writer.Run(&property_dict); + std::map<std::string, VariantDictionary> interfaces_and_properties{ + {interface_name, property_dict} + }; + signal_itf_added_.lock()->Send(path, interfaces_and_properties); + registered_objects_[path][interface_name] = property_writer; +} + +void ExportedObjectManager::ReleaseInterface( + const dbus::ObjectPath& path, + const std::string& interface_name) { + bus_->AssertOnOriginThread(); + auto interfaces_for_path_itr = registered_objects_.find(path); + CHECK(interfaces_for_path_itr != registered_objects_.end()) + << "Attempting to signal interface removal for path " << path.value() + << " which was never registered."; + auto& interfaces_for_path = interfaces_for_path_itr->second; + auto property_for_interface_itr = interfaces_for_path.find(interface_name); + CHECK(property_for_interface_itr != interfaces_for_path.end()) + << "Attempted to remove interface " << interface_name << " from " + << path.value() << ", but this interface was never registered."; + interfaces_for_path.erase(interface_name); + if (interfaces_for_path.empty()) + registered_objects_.erase(path); + + // We're sending signals that look like: + // org.freedesktop.DBus.ObjectManager.InterfacesRemoved ( + // OBJPATH object_path, ARRAY<STRING> interfaces); + signal_itf_removed_.lock()->Send(path, + std::vector<std::string>{interface_name}); +} + +ExportedObjectManager::ObjectMap +ExportedObjectManager::HandleGetManagedObjects() { + // Implements the GetManagedObjects method: + // + // org.freedesktop.DBus.ObjectManager.GetManagedObjects ( + // out DICT<OBJPATH, + // DICT<STRING, + // DICT<STRING,VARIANT>>> ) + bus_->AssertOnOriginThread(); + ExportedObjectManager::ObjectMap objects; + for (const auto path_pair : registered_objects_) { + std::map<std::string, VariantDictionary>& interfaces = + objects[path_pair.first]; + const InterfaceProperties& interface2properties = path_pair.second; + for (const auto interface : interface2properties) { + interface.second.Run(&interfaces[interface.first]); + } + } + return objects; +} + +} // namespace dbus_utils + +} // namespace brillo |