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 #ifndef LIBBRILLO_BRILLO_DBUS_EXPORTED_OBJECT_MANAGER_H_
      6 #define LIBBRILLO_BRILLO_DBUS_EXPORTED_OBJECT_MANAGER_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include <base/callback.h>
     13 #include <base/memory/weak_ptr.h>
     14 #include <brillo/brillo_export.h>
     15 #include <brillo/dbus/dbus_object.h>
     16 #include <brillo/dbus/exported_property_set.h>
     17 #include <brillo/variant_dictionary.h>
     18 #include <dbus/bus.h>
     19 #include <dbus/exported_object.h>
     20 #include <dbus/message.h>
     21 #include <dbus/object_path.h>
     22 
     23 namespace brillo {
     24 
     25 namespace dbus_utils {
     26 
     27 // ExportedObjectManager is a delegate that implements the
     28 // org.freedesktop.DBus.ObjectManager interface on behalf of another
     29 // object. It handles sending signals when new interfaces are added.
     30 //
     31 // This class is very similar to the ExportedPropertySet class, except that
     32 // it allows objects to expose an object manager interface rather than the
     33 // properties interface.
     34 //
     35 //  Example usage:
     36 //
     37 //   class ExampleObjectManager {
     38 //    public:
     39 //     ExampleObjectManager(dbus::Bus* bus)
     40 //         : object_manager_(bus, "/my/objects/path") { }
     41 //
     42 //     void RegisterAsync(const CompletionAction& cb) {
     43 //          object_manager_.RegisterAsync(cb);
     44 //     }
     45 //     void ClaimInterface(const dbus::ObjectPath& path,
     46 //                         const std::string& interface_name,
     47 //                         const ExportedPropertySet::PropertyWriter& writer) {
     48 //       object_manager_->ClaimInterface(...);
     49 //     }
     50 //     void ReleaseInterface(const dbus::ObjectPath& path,
     51 //                           const std::string& interface_name) {
     52 //       object_manager_->ReleaseInterface(...);
     53 //     }
     54 //
     55 //    private:
     56 //     ExportedObjectManager object_manager_;
     57 //   };
     58 //
     59 //   class MyObjectClaimingAnInterface {
     60 //    public:
     61 //     MyObjectClaimingAnInterface(ExampleObjectManager* object_manager)
     62 //       : object_manager_(object_manager) {}
     63 //
     64 //     void OnInitFinish(bool success) {
     65 //       if (!success) { /* handle that */ }
     66 //       object_manager_->ClaimInterface(
     67 //           my_path_, my_interface_, my_properties_.GetWriter());
     68 //     }
     69 //
     70 //    private:
     71 //     struct Properties : public ExportedPropertySet {
     72 //      public:
     73 //       /* Lots of interesting properties. */
     74 //     };
     75 //
     76 //     Properties my_properties_;
     77 //     ExampleObjectManager* object_manager_;
     78 //   };
     79 class BRILLO_EXPORT ExportedObjectManager
     80     : public base::SupportsWeakPtr<ExportedObjectManager> {
     81  public:
     82   using ObjectMap =
     83       std::map<dbus::ObjectPath, std::map<std::string, VariantDictionary>>;
     84   using InterfaceProperties =
     85       std::map<std::string, ExportedPropertySet::PropertyWriter>;
     86 
     87   ExportedObjectManager(scoped_refptr<dbus::Bus> bus,
     88                         const dbus::ObjectPath& path);
     89   virtual ~ExportedObjectManager() = default;
     90 
     91   // Registers methods implementing the ObjectManager interface on the object
     92   // exported on the path given in the constructor. Must be called on the
     93   // origin thread.
     94   virtual void RegisterAsync(
     95       const brillo::dbus_utils::AsyncEventSequencer::CompletionAction&
     96           completion_callback);
     97 
     98   // Trigger a signal that |path| has added an interface |interface_name|
     99   // with properties as given by |writer|.
    100   virtual void ClaimInterface(
    101       const dbus::ObjectPath& path,
    102       const std::string& interface_name,
    103       const ExportedPropertySet::PropertyWriter& writer);
    104 
    105   // Trigger a signal that |path| has removed an interface |interface_name|.
    106   virtual void ReleaseInterface(const dbus::ObjectPath& path,
    107                                 const std::string& interface_name);
    108 
    109   const scoped_refptr<dbus::Bus>& GetBus() const { return bus_; }
    110 
    111  private:
    112   BRILLO_PRIVATE ObjectMap HandleGetManagedObjects();
    113 
    114   scoped_refptr<dbus::Bus> bus_;
    115   brillo::dbus_utils::DBusObject dbus_object_;
    116   // Tracks all objects currently known to the ExportedObjectManager.
    117   std::map<dbus::ObjectPath, InterfaceProperties> registered_objects_;
    118 
    119   using SignalInterfacesAdded =
    120       DBusSignal<dbus::ObjectPath, std::map<std::string, VariantDictionary>>;
    121   using SignalInterfacesRemoved =
    122       DBusSignal<dbus::ObjectPath, std::vector<std::string>>;
    123 
    124   std::weak_ptr<SignalInterfacesAdded> signal_itf_added_;
    125   std::weak_ptr<SignalInterfacesRemoved> signal_itf_removed_;
    126 
    127   friend class ExportedObjectManagerTest;
    128   DISALLOW_COPY_AND_ASSIGN(ExportedObjectManager);
    129 };
    130 
    131 }  // namespace dbus_utils
    132 
    133 }  // namespace brillo
    134 
    135 #endif  // LIBBRILLO_BRILLO_DBUS_EXPORTED_OBJECT_MANAGER_H_
    136