Home | History | Annotate | Download | only in dbus
      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 
     18 ExportedObjectManager::ExportedObjectManager(scoped_refptr<dbus::Bus> bus,
     19                                              const dbus::ObjectPath& path)
     20     : bus_(bus), dbus_object_(nullptr, bus, path) {
     21 }
     22 
     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 
     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 
     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
     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