You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
4.0 KiB
106 lines
4.0 KiB
// 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
|