| // Copyright 2014 The ChromiumOS Authors |
| // 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 <utility> |
| #include <vector> |
| |
| #include <base/check.h> |
| #include <base/logging.h> |
| #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( |
| 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(std::move(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 |