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 // DBusObject is a special helper class that simplifies the implementation of
      6 // D-Bus objects in C++. It provides an easy way to define interfaces with
      7 // methods and properties and offloads a lot of work to register the object and
      8 // all of its interfaces, to marshal method calls (by converting D-Bus method
      9 // parameters to native C++ types and invoking native method handlers), etc.
     10 
     11 // The basic usage pattern of this class is as follows:
     12 /*
     13 class MyDbusObject {
     14  public:
     15   MyDbusObject(ExportedObjectManager* object_manager,
     16                const scoped_refptr<dbus::Bus>& bus)
     17       : dbus_object_(object_manager, bus,
     18                      dbus::ObjectPath("/org/chromium/my_obj")) {}
     19 
     20   void Init(const AsyncEventSequencer::CompletionAction& callback) {
     21     DBusInterface* my_interface =
     22         dbus_object_.AddOrGetInterface("org.chromium.MyInterface");
     23     my_interface->AddSimpleMethodHandler("Method1", this,
     24                                          &MyDbusObject::Method1);
     25     my_interface->AddSimpleMethodHandlerWithError("Method2", this,
     26                                                   &MyDbusObject::Method2);
     27     my_interface->AddMethodHandler("Method3", this, &MyDbusObject::Method3);
     28     my_interface->AddProperty("Property1", &prop1_);
     29     my_interface->AddProperty("Property2", &prop2_);
     30     prop1_.SetValue("prop1_value");
     31     prop2_.SetValue(50);
     32     // Register the object by exporting its methods and properties and
     33     // exposing them to D-Bus clients.
     34     dbus_object_.RegisterAsync(callback);
     35   }
     36 
     37  private:
     38   DBusObject dbus_object_;
     39 
     40   // Make sure the properties outlive the DBusObject they are registered with.
     41   brillo::dbus_utils::ExportedProperty<std::string> prop1_;
     42   brillo::dbus_utils::ExportedProperty<int> prop2_;
     43   int Method1() { return 5; }
     44   bool Method2(brillo::ErrorPtr* error, const std::string& message);
     45   void Method3(std::unique_ptr<DBusMethodResponse<int_32>> response,
     46                const std::string& message) {
     47     if (message.empty()) {
     48        response->ReplyWithError(brillo::errors::dbus::kDomain,
     49                                 DBUS_ERROR_INVALID_ARGS,
     50                                 "Message string cannot be empty");
     51        return;
     52     }
     53     int32_t message_len = message.length();
     54     response->Return(message_len);
     55   }
     56 
     57   DISALLOW_COPY_AND_ASSIGN(MyDbusObject);
     58 };
     59 */
     60 
     61 #ifndef LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_H_
     62 #define LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_H_
     63 
     64 #include <map>
     65 #include <string>
     66 
     67 #include <base/bind.h>
     68 #include <base/callback_helpers.h>
     69 #include <base/macros.h>
     70 #include <base/memory/weak_ptr.h>
     71 #include <brillo/brillo_export.h>
     72 #include <brillo/dbus/async_event_sequencer.h>
     73 #include <brillo/dbus/dbus_object_internal_impl.h>
     74 #include <brillo/dbus/dbus_signal.h>
     75 #include <brillo/dbus/exported_property_set.h>
     76 #include <brillo/errors/error.h>
     77 #include <dbus/bus.h>
     78 #include <dbus/exported_object.h>
     79 #include <dbus/message.h>
     80 #include <dbus/object_path.h>
     81 
     82 namespace brillo {
     83 namespace dbus_utils {
     84 
     85 class ExportedObjectManager;
     86 class ExportedPropertyBase;
     87 class DBusObject;
     88 
     89 // This is an implementation proxy class for a D-Bus interface of an object.
     90 // The important functionality for the users is the ability to add D-Bus method
     91 // handlers and define D-Bus object properties. This is achieved by using one
     92 // of the overload of AddSimpleMethodHandler()/AddMethodHandler() and
     93 // AddProperty() respectively.
     94 // There are three overloads for DBusInterface::AddSimpleMethodHandler() and
     95 // AddMethodHandler() each:
     96 //  1. That takes a handler as base::Callback
     97 //  2. That takes a static function
     98 //  3. That takes a class instance pointer and a class member function
     99 // The signature of the handler for AddSimpleMethodHandler must be one of:
    100 //    R(Args... args)                     [IN only]
    101 //    void(Args... args)                  [IN/OUT]
    102 // The signature of the handler for AddSimpleMethodHandlerWithError must be:
    103 //    bool(ErrorPtr* error, Args... args) [IN/OUT]
    104 // The signature of the handler for AddSimpleMethodHandlerWithErrorAndMessage:
    105 //    bool(ErrorPtr* error, dbus::Message* msg, Args... args) [IN/OUT]
    106 // The signature of the handler for AddMethodHandler must be:
    107 //    void(std::unique_ptr<DBusMethodResponse<T...>> response,
    108 //         Args... args) [IN]
    109 // The signature of the handler for AddMethodHandlerWithMessage must be:
    110 //    void(std::unique_ptr<DBusMethodResponse<T...>> response,
    111 //         dbus::Message* msg, Args... args) [IN]
    112 // There is also an AddRawMethodHandler() call that lets provide a custom
    113 // handler that can parse its own input parameter and construct a custom
    114 // response.
    115 // The signature of the handler for AddRawMethodHandler must be:
    116 //    void(dbus::MethodCall* method_call, ResponseSender sender)
    117 class BRILLO_EXPORT DBusInterface final {
    118  public:
    119   DBusInterface(DBusObject* dbus_object, const std::string& interface_name);
    120 
    121   // Register sync DBus method handler for |method_name| as base::Callback.
    122   template<typename R, typename... Args>
    123   inline void AddSimpleMethodHandler(
    124       const std::string& method_name,
    125       const base::Callback<R(Args...)>& handler) {
    126     Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
    127         this, method_name, handler);
    128   }
    129 
    130   // Register sync D-Bus method handler for |method_name| as a static
    131   // function.
    132   template<typename R, typename... Args>
    133   inline void AddSimpleMethodHandler(const std::string& method_name,
    134                                      R(*handler)(Args...)) {
    135     Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
    136         this, method_name, base::Bind(handler));
    137   }
    138 
    139   // Register sync D-Bus method handler for |method_name| as a class member
    140   // function.
    141   template<typename Instance, typename Class, typename R, typename... Args>
    142   inline void AddSimpleMethodHandler(const std::string& method_name,
    143                                      Instance instance,
    144                                      R(Class::*handler)(Args...)) {
    145     Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
    146         this, method_name, base::Bind(handler, instance));
    147   }
    148 
    149   // Same as above but for const-method of a class.
    150   template<typename Instance, typename Class, typename R, typename... Args>
    151   inline void AddSimpleMethodHandler(const std::string& method_name,
    152                                      Instance instance,
    153                                      R(Class::*handler)(Args...) const) {
    154     Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
    155         this, method_name, base::Bind(handler, instance));
    156   }
    157 
    158   // Register sync DBus method handler for |method_name| as base::Callback.
    159   template<typename... Args>
    160   inline void AddSimpleMethodHandlerWithError(
    161       const std::string& method_name,
    162       const base::Callback<bool(ErrorPtr*, Args...)>& handler) {
    163     Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
    164         this, method_name, handler);
    165   }
    166 
    167   // Register sync D-Bus method handler for |method_name| as a static
    168   // function.
    169   template<typename... Args>
    170   inline void AddSimpleMethodHandlerWithError(
    171       const std::string& method_name,
    172       bool(*handler)(ErrorPtr*, Args...)) {
    173     Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
    174         this, method_name, base::Bind(handler));
    175   }
    176 
    177   // Register sync D-Bus method handler for |method_name| as a class member
    178   // function.
    179   template<typename Instance, typename Class, typename... Args>
    180   inline void AddSimpleMethodHandlerWithError(
    181       const std::string& method_name,
    182       Instance instance,
    183       bool(Class::*handler)(ErrorPtr*, Args...)) {
    184     Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
    185         this, method_name, base::Bind(handler, instance));
    186   }
    187 
    188   // Same as above but for const-method of a class.
    189   template<typename Instance, typename Class, typename... Args>
    190   inline void AddSimpleMethodHandlerWithError(
    191       const std::string& method_name,
    192       Instance instance,
    193       bool(Class::*handler)(ErrorPtr*, Args...) const) {
    194     Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
    195         this, method_name, base::Bind(handler, instance));
    196   }
    197 
    198   // Register sync DBus method handler for |method_name| as base::Callback.
    199   // Passing the method sender as a first parameter to the callback.
    200   template<typename... Args>
    201   inline void AddSimpleMethodHandlerWithErrorAndMessage(
    202       const std::string& method_name,
    203       const base::Callback<bool(ErrorPtr*, dbus::Message*, Args...)>&
    204           handler) {
    205     Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
    206         this, method_name, handler);
    207   }
    208 
    209   // Register sync D-Bus method handler for |method_name| as a static
    210   // function. Passing the method D-Bus message as the second parameter to the
    211   // callback.
    212   template<typename... Args>
    213   inline void AddSimpleMethodHandlerWithErrorAndMessage(
    214       const std::string& method_name,
    215       bool(*handler)(ErrorPtr*, dbus::Message*, Args...)) {
    216     Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
    217         this, method_name, base::Bind(handler));
    218   }
    219 
    220   // Register sync D-Bus method handler for |method_name| as a class member
    221   // function. Passing the method D-Bus message as the second parameter to the
    222   // callback.
    223   template<typename Instance, typename Class, typename... Args>
    224   inline void AddSimpleMethodHandlerWithErrorAndMessage(
    225       const std::string& method_name,
    226       Instance instance,
    227       bool(Class::*handler)(ErrorPtr*, dbus::Message*, Args...)) {
    228     Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
    229         this, method_name, base::Bind(handler, instance));
    230   }
    231 
    232   // Same as above but for const-method of a class.
    233   template<typename Instance, typename Class, typename... Args>
    234   inline void AddSimpleMethodHandlerWithErrorAndMessage(
    235       const std::string& method_name,
    236       Instance instance,
    237       bool(Class::*handler)(ErrorPtr*, dbus::Message*, Args...) const) {
    238     Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
    239         this, method_name, base::Bind(handler, instance));
    240   }
    241 
    242   // Register an async DBus method handler for |method_name| as base::Callback.
    243   template<typename Response, typename... Args>
    244   inline void AddMethodHandler(
    245       const std::string& method_name,
    246       const base::Callback<void(std::unique_ptr<Response>, Args...)>& handler) {
    247     static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
    248                   "Response must be DBusMethodResponse<T...>");
    249     Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
    250         this, method_name, handler);
    251   }
    252 
    253   // Register an async D-Bus method handler for |method_name| as a static
    254   // function.
    255   template<typename Response, typename... Args>
    256   inline void AddMethodHandler(
    257       const std::string& method_name,
    258       void (*handler)(std::unique_ptr<Response>, Args...)) {
    259     static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
    260                   "Response must be DBusMethodResponse<T...>");
    261     Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
    262         this, method_name, base::Bind(handler));
    263   }
    264 
    265   // Register an async D-Bus method handler for |method_name| as a class member
    266   // function.
    267   template<typename Response,
    268            typename Instance,
    269            typename Class,
    270            typename... Args>
    271   inline void AddMethodHandler(
    272       const std::string& method_name,
    273       Instance instance,
    274       void(Class::*handler)(std::unique_ptr<Response>, Args...)) {
    275     static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
    276                   "Response must be DBusMethodResponse<T...>");
    277     Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
    278         this, method_name, base::Bind(handler, instance));
    279   }
    280 
    281   // Same as above but for const-method of a class.
    282   template<typename Response,
    283            typename Instance,
    284            typename Class,
    285            typename... Args>
    286   inline void AddMethodHandler(
    287       const std::string& method_name,
    288       Instance instance,
    289       void(Class::*handler)(std::unique_ptr<Response>, Args...) const) {
    290     static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
    291                   "Response must be DBusMethodResponse<T...>");
    292     Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
    293         this, method_name, base::Bind(handler, instance));
    294   }
    295 
    296   // Register an async DBus method handler for |method_name| as base::Callback.
    297   template<typename Response, typename... Args>
    298   inline void AddMethodHandlerWithMessage(
    299       const std::string& method_name,
    300       const base::Callback<void(std::unique_ptr<Response>, dbus::Message*,
    301                                 Args...)>& handler) {
    302     static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
    303                   "Response must be DBusMethodResponse<T...>");
    304     Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
    305         this, method_name, handler);
    306   }
    307 
    308   // Register an async D-Bus method handler for |method_name| as a static
    309   // function.
    310   template<typename Response, typename... Args>
    311   inline void AddMethodHandlerWithMessage(
    312       const std::string& method_name,
    313       void (*handler)(std::unique_ptr<Response>, dbus::Message*, Args...)) {
    314     static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
    315                   "Response must be DBusMethodResponse<T...>");
    316     Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
    317         this, method_name, base::Bind(handler));
    318   }
    319 
    320   // Register an async D-Bus method handler for |method_name| as a class member
    321   // function.
    322   template<typename Response,
    323            typename Instance,
    324            typename Class,
    325            typename... Args>
    326   inline void AddMethodHandlerWithMessage(
    327       const std::string& method_name,
    328       Instance instance,
    329       void(Class::*handler)(std::unique_ptr<Response>,
    330                             dbus::Message*, Args...)) {
    331     static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
    332                   "Response must be DBusMethodResponse<T...>");
    333     Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
    334         this, method_name, base::Bind(handler, instance));
    335   }
    336 
    337   // Same as above but for const-method of a class.
    338   template<typename Response,
    339            typename Instance,
    340            typename Class,
    341            typename... Args>
    342   inline void AddMethodHandlerWithMessage(
    343       const std::string& method_name,
    344       Instance instance,
    345       void(Class::*handler)(std::unique_ptr<Response>, dbus::Message*,
    346                             Args...) const) {
    347     static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
    348                   "Response must be DBusMethodResponse<T...>");
    349     Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
    350         this, method_name, base::Bind(handler, instance));
    351   }
    352 
    353   // Register a raw D-Bus method handler for |method_name| as base::Callback.
    354   inline void AddRawMethodHandler(
    355       const std::string& method_name,
    356       const base::Callback<void(dbus::MethodCall*, ResponseSender)>& handler) {
    357     Handler<RawDBusInterfaceMethodHandler>::Add(this, method_name, handler);
    358   }
    359 
    360   // Register a raw D-Bus method handler for |method_name| as a class member
    361   // function.
    362   template<typename Instance, typename Class>
    363   inline void AddRawMethodHandler(
    364       const std::string& method_name,
    365       Instance instance,
    366       void(Class::*handler)(dbus::MethodCall*, ResponseSender)) {
    367     Handler<RawDBusInterfaceMethodHandler>::Add(
    368         this, method_name, base::Bind(handler, instance));
    369   }
    370 
    371   // Register a D-Bus property.
    372   void AddProperty(const std::string& property_name,
    373                    ExportedPropertyBase* prop_base);
    374 
    375   // Registers a D-Bus signal that has a specified number and types (|Args|) of
    376   // arguments. Returns a weak pointer to the DBusSignal object which can be
    377   // used to send the signal on this interface when needed:
    378   /*
    379     DBusInterface* itf = dbus_object->AddOrGetInterface("Interface");
    380     auto signal = itf->RegisterSignal<int, bool>("MySignal");
    381     ...
    382     // Send the Interface.MySig(12, true) signal.
    383     if (signal.lock()->Send(12, true)) { ... }
    384   */
    385   // Or if the signal signature is long or complex, you can alias the
    386   // DBusSignal<Args...> signal type and use RegisterSignalOfType method
    387   // instead:
    388   /*
    389     DBusInterface* itf = dbus_object->AddOrGetInterface("Interface");
    390     using MySignal = DBusSignal<int, bool>;
    391     auto signal = itf->RegisterSignalOfType<MySignal>("MySignal");
    392     ...
    393     // Send the Interface.MySig(12, true) signal.
    394     if (signal.lock()->Send(12, true)) { ... }
    395   */
    396   // If the signal with the given name was already registered, the existing
    397   // copy of the signal proxy object is returned as long as the method signature
    398   // of the original signal matches the current call. If it doesn't, the method
    399   // aborts.
    400 
    401   // RegisterSignalOfType can be used to create a signal if the type of the
    402   // complete DBusSignal<Args...> class which is pre-defined/aliased earlier.
    403   template<typename DBusSignalType>
    404   inline std::weak_ptr<DBusSignalType> RegisterSignalOfType(
    405       const std::string& signal_name) {
    406     auto signal = std::make_shared<DBusSignalType>(
    407         dbus_object_, interface_name_, signal_name);
    408     AddSignalImpl(signal_name, signal);
    409     return signal;
    410   }
    411 
    412   // For simple signal arguments, you can specify their types directly in
    413   // RegisterSignal<t1, t2, ...>():
    414   //  auto signal = itf->RegisterSignal<int>("SignalName");
    415   // This will create a callback signal object that expects one int argument.
    416   template<typename... Args>
    417   inline std::weak_ptr<DBusSignal<Args...>> RegisterSignal(
    418       const std::string& signal_name) {
    419     return RegisterSignalOfType<DBusSignal<Args...>>(signal_name);
    420   }
    421 
    422  private:
    423   // Helper to create an instance of DBusInterfaceMethodHandlerInterface-derived
    424   // handler and add it to the method handler map of the interface.
    425   // This makes the actual AddXXXMethodHandler() methods very light-weight and
    426   // easier to provide different overloads for various method handler kinds.
    427   // Using struct here to allow partial specialization on HandlerType while
    428   // letting the compiler to deduce the type of the callback without explicitly
    429   // specifying it.
    430   template<typename HandlerType>
    431   struct Handler {
    432     template<typename CallbackType>
    433     inline static void Add(DBusInterface* self,
    434                            const std::string& method_name,
    435                            const CallbackType& callback) {
    436       std::unique_ptr<DBusInterfaceMethodHandlerInterface> sync_method_handler(
    437           new HandlerType(callback));
    438       self->AddHandlerImpl(method_name, std::move(sync_method_handler));
    439     }
    440   };
    441   // A generic D-Bus method handler for the interface. It extracts the method
    442   // name from |method_call|, looks up a registered handler from |handlers_|
    443   // map and dispatched the call to that handler.
    444   void HandleMethodCall(dbus::MethodCall* method_call, ResponseSender sender);
    445   // Helper to add a handler for method |method_name| to the |handlers_| map.
    446   // Not marked BRILLO_PRIVATE because it needs to be called by the inline
    447   // template functions AddMethodHandler(...)
    448   void AddHandlerImpl(
    449       const std::string& method_name,
    450       std::unique_ptr<DBusInterfaceMethodHandlerInterface> handler);
    451   // Helper to add a signal object to the |signals_| map.
    452   // Not marked BRILLO_PRIVATE because it needs to be called by the inline
    453   // template function RegisterSignalOfType(...)
    454   void AddSignalImpl(const std::string& signal_name,
    455                      const std::shared_ptr<DBusSignalBase>& signal);
    456   // Exports all the methods and properties of this interface and claims the
    457   // D-Bus interface.
    458   // object_manager - ExportedObjectManager instance that notifies D-Bus
    459   //                  listeners of a new interface being claimed.
    460   // exported_object - instance of D-Bus object the interface is being added to.
    461   // object_path - D-Bus object path for the object instance.
    462   // interface_name - name of interface being registered.
    463   // completion_callback - a callback to be called when the asynchronous
    464   //                       registration operation is completed.
    465   BRILLO_PRIVATE void ExportAsync(
    466       ExportedObjectManager* object_manager,
    467       dbus::Bus* bus,
    468       dbus::ExportedObject* exported_object,
    469       const dbus::ObjectPath& object_path,
    470       const AsyncEventSequencer::CompletionAction& completion_callback);
    471   // Exports all the methods and properties of this interface and claims the
    472   // D-Bus interface synchronously.
    473   // object_manager - ExportedObjectManager instance that notifies D-Bus
    474   //                  listeners of a new interface being claimed.
    475   // exported_object - instance of D-Bus object the interface is being added to.
    476   // object_path - D-Bus object path for the object instance.
    477   // interface_name - name of interface being registered.
    478   BRILLO_PRIVATE void ExportAndBlock(
    479       ExportedObjectManager* object_manager,
    480       dbus::Bus* bus,
    481       dbus::ExportedObject* exported_object,
    482       const dbus::ObjectPath& object_path);
    483 
    484   BRILLO_PRIVATE void ClaimInterface(
    485       base::WeakPtr<ExportedObjectManager> object_manager,
    486       const dbus::ObjectPath& object_path,
    487       const ExportedPropertySet::PropertyWriter& writer,
    488       bool all_succeeded);
    489 
    490   // Method registration map.
    491   std::map<std::string, std::unique_ptr<DBusInterfaceMethodHandlerInterface>>
    492       handlers_;
    493   // Signal registration map.
    494   std::map<std::string, std::shared_ptr<DBusSignalBase>> signals_;
    495 
    496   friend class DBusObject;
    497   friend class DBusInterfaceTestHelper;
    498   DBusObject* dbus_object_;
    499   std::string interface_name_;
    500   base::ScopedClosureRunner release_interface_cb_;
    501 
    502   base::WeakPtrFactory<DBusInterface> weak_factory_{this};
    503   DISALLOW_COPY_AND_ASSIGN(DBusInterface);
    504 };
    505 
    506 // A D-Bus object implementation class. Manages the interfaces implemented
    507 // by this object.
    508 class BRILLO_EXPORT DBusObject {
    509  public:
    510   // object_manager - ExportedObjectManager instance that notifies D-Bus
    511   //                  listeners of a new interface being claimed and property
    512   //                  changes on those interfaces.
    513   // object_path - D-Bus object path for the object instance.
    514   DBusObject(ExportedObjectManager* object_manager,
    515              const scoped_refptr<dbus::Bus>& bus,
    516              const dbus::ObjectPath& object_path);
    517   virtual ~DBusObject();
    518 
    519   // Returns an proxy handler for the interface |interface_name|. If the
    520   // interface proxy does not exist yet, it will be automatically created.
    521   DBusInterface* AddOrGetInterface(const std::string& interface_name);
    522 
    523   // Finds an interface with the given name. Returns nullptr if there is no
    524   // interface registered by this name.
    525   DBusInterface* FindInterface(const std::string& interface_name) const;
    526 
    527   // Registers the object instance with D-Bus. This is an asynchronous call
    528   // that will call |completion_callback| when the object and all of its
    529   // interfaces are registered.
    530   virtual void RegisterAsync(
    531       const AsyncEventSequencer::CompletionAction& completion_callback);
    532 
    533   // Registers the object instance with D-Bus. This is call is synchronous and
    534   // will block until the object and all of its interfaces are registered.
    535   virtual void RegisterAndBlock();
    536 
    537   // Unregister the object instance with D-Bus.  This will unregister the
    538   // |exported_object_| and its path from the bus.  The destruction of
    539   // |exported_object_| will be deferred in an async task posted by the bus.
    540   // It is guarantee that upon return from this call a new DBusObject with the
    541   // same object path can be created/registered.
    542   virtual void UnregisterAsync();
    543 
    544   // Returns the ExportedObjectManager proxy, if any. If DBusObject has been
    545   // constructed without an object manager, this method returns an empty
    546   // smart pointer (containing nullptr).
    547   const base::WeakPtr<ExportedObjectManager>& GetObjectManager() const {
    548     return object_manager_;
    549   }
    550 
    551   // Sends a signal from the exported D-Bus object.
    552   bool SendSignal(dbus::Signal* signal);
    553 
    554   // Returns the reference to dbus::Bus this object is associated with.
    555   scoped_refptr<dbus::Bus> GetBus() { return bus_; }
    556 
    557  private:
    558   // A map of all the interfaces added to this object.
    559   std::map<std::string, std::unique_ptr<DBusInterface>> interfaces_;
    560   // Exported property set for properties registered with the interfaces
    561   // implemented by this D-Bus object.
    562   ExportedPropertySet property_set_;
    563   // Delegate object implementing org.freedesktop.DBus.ObjectManager interface.
    564   base::WeakPtr<ExportedObjectManager> object_manager_;
    565   // D-Bus bus object.
    566   scoped_refptr<dbus::Bus> bus_;
    567   // D-Bus object path for this object.
    568   dbus::ObjectPath object_path_;
    569   // D-Bus object instance once this object is successfully exported.
    570   dbus::ExportedObject* exported_object_ = nullptr;  // weak; owned by |bus_|.
    571 
    572   friend class DBusInterface;
    573   DISALLOW_COPY_AND_ASSIGN(DBusObject);
    574 };
    575 
    576 }  // namespace dbus_utils
    577 }  // namespace brillo
    578 
    579 #endif  // LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_H_
    580