• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <brillo/dbus/exported_object_manager.h>
6 
7 #include <vector>
8 
9 #include <brillo/dbus/async_event_sequencer.h>
10 #include <dbus/object_manager.h>
11 
12 using brillo::dbus_utils::AsyncEventSequencer;
13 
14 namespace brillo {
15 
16 namespace dbus_utils {
17 
ExportedObjectManager(scoped_refptr<dbus::Bus> bus,const dbus::ObjectPath & path)18 ExportedObjectManager::ExportedObjectManager(scoped_refptr<dbus::Bus> bus,
19                                              const dbus::ObjectPath& path)
20     : bus_(bus), dbus_object_(nullptr, bus, path) {
21 }
22 
RegisterAsync(const AsyncEventSequencer::CompletionAction & completion_callback)23 void ExportedObjectManager::RegisterAsync(
24     const AsyncEventSequencer::CompletionAction& completion_callback) {
25   VLOG(1) << "Registering object manager";
26   bus_->AssertOnOriginThread();
27   DBusInterface* itf =
28       dbus_object_.AddOrGetInterface(dbus::kObjectManagerInterface);
29   itf->AddSimpleMethodHandler(dbus::kObjectManagerGetManagedObjects,
30                               base::Unretained(this),
31                               &ExportedObjectManager::HandleGetManagedObjects);
32 
33   signal_itf_added_ = itf->RegisterSignalOfType<SignalInterfacesAdded>(
34       dbus::kObjectManagerInterfacesAdded);
35   signal_itf_removed_ = itf->RegisterSignalOfType<SignalInterfacesRemoved>(
36       dbus::kObjectManagerInterfacesRemoved);
37   dbus_object_.RegisterAsync(completion_callback);
38 }
39 
ClaimInterface(const dbus::ObjectPath & path,const std::string & interface_name,const ExportedPropertySet::PropertyWriter & property_writer)40 void ExportedObjectManager::ClaimInterface(
41     const dbus::ObjectPath& path,
42     const std::string& interface_name,
43     const ExportedPropertySet::PropertyWriter& property_writer) {
44   bus_->AssertOnOriginThread();
45   // We're sending signals that look like:
46   //   org.freedesktop.DBus.ObjectManager.InterfacesAdded (
47   //       OBJPATH object_path,
48   //       DICT<STRING,DICT<STRING,VARIANT>> interfaces_and_properties);
49   VariantDictionary property_dict;
50   property_writer.Run(&property_dict);
51   std::map<std::string, VariantDictionary> interfaces_and_properties{
52       {interface_name, property_dict}
53   };
54   signal_itf_added_.lock()->Send(path, interfaces_and_properties);
55   registered_objects_[path][interface_name] = property_writer;
56 }
57 
ReleaseInterface(const dbus::ObjectPath & path,const std::string & interface_name)58 void ExportedObjectManager::ReleaseInterface(
59     const dbus::ObjectPath& path,
60     const std::string& interface_name) {
61   bus_->AssertOnOriginThread();
62   auto interfaces_for_path_itr = registered_objects_.find(path);
63   CHECK(interfaces_for_path_itr != registered_objects_.end())
64       << "Attempting to signal interface removal for path " << path.value()
65       << " which was never registered.";
66   auto& interfaces_for_path = interfaces_for_path_itr->second;
67   auto property_for_interface_itr = interfaces_for_path.find(interface_name);
68   CHECK(property_for_interface_itr != interfaces_for_path.end())
69       << "Attempted to remove interface " << interface_name << " from "
70       << path.value() << ", but this interface was never registered.";
71   interfaces_for_path.erase(interface_name);
72   if (interfaces_for_path.empty())
73     registered_objects_.erase(path);
74 
75   // We're sending signals that look like:
76   //   org.freedesktop.DBus.ObjectManager.InterfacesRemoved (
77   //       OBJPATH object_path, ARRAY<STRING> interfaces);
78   signal_itf_removed_.lock()->Send(path,
79                                    std::vector<std::string>{interface_name});
80 }
81 
82 ExportedObjectManager::ObjectMap
HandleGetManagedObjects()83 ExportedObjectManager::HandleGetManagedObjects() {
84   // Implements the GetManagedObjects method:
85   //
86   // org.freedesktop.DBus.ObjectManager.GetManagedObjects (
87   //     out DICT<OBJPATH,
88   //              DICT<STRING,
89   //                   DICT<STRING,VARIANT>>> )
90   bus_->AssertOnOriginThread();
91   ExportedObjectManager::ObjectMap objects;
92   for (const auto path_pair : registered_objects_) {
93     std::map<std::string, VariantDictionary>& interfaces =
94         objects[path_pair.first];
95     const InterfaceProperties& interface2properties = path_pair.second;
96     for (const auto interface : interface2properties) {
97       interface.second.Run(&interfaces[interface.first]);
98     }
99   }
100   return objects;
101 }
102 
103 }  // namespace dbus_utils
104 
105 }  // namespace brillo
106