// 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.

// DBusObject is a special helper class that simplifies the implementation of
// D-Bus objects in C++. It provides an easy way to define interfaces with
// methods and properties and offloads a lot of work to register the object and
// all of its interfaces, to marshal method calls (by converting D-Bus method
// parameters to native C++ types and invoking native method handlers), etc.

// The basic usage pattern of this class is as follows:
/*
class MyDbusObject {
 public:
  MyDbusObject(ExportedObjectManager* object_manager,
               const scoped_refptr<dbus::Bus>& bus)
      : dbus_object_(object_manager, bus,
                     dbus::ObjectPath("/org/chromium/my_obj")) {}

  void Init(const AsyncEventSequencer::CompletionAction& callback) {
    DBusInterface* my_interface =
        dbus_object_.AddOrGetInterface("org.chromium.MyInterface");
    my_interface->AddSimpleMethodHandler("Method1", this,
                                         &MyDbusObject::Method1);
    my_interface->AddSimpleMethodHandlerWithError("Method2", this,
                                                  &MyDbusObject::Method2);
    my_interface->AddMethodHandler("Method3", this, &MyDbusObject::Method3);
    my_interface->AddProperty("Property1", &prop1_);
    my_interface->AddProperty("Property2", &prop2_);
    prop1_.SetValue("prop1_value");
    prop2_.SetValue(50);
    // Register the object by exporting its methods and properties and
    // exposing them to D-Bus clients.
    dbus_object_.RegisterAsync(callback);
  }

 private:
  DBusObject dbus_object_;

  // Make sure the properties outlive the DBusObject they are registered with.
  brillo::dbus_utils::ExportedProperty<std::string> prop1_;
  brillo::dbus_utils::ExportedProperty<int> prop2_;
  int Method1() { return 5; }
  bool Method2(brillo::ErrorPtr* error, const std::string& message);
  void Method3(std::unique_ptr<DBusMethodResponse<int_32>> response,
               const std::string& message) {
    if (message.empty()) {
       response->ReplyWithError(FROM_HERE,
                                brillo::errors::dbus::kDomain,
                                DBUS_ERROR_INVALID_ARGS,
                                "Message string cannot be empty");
       return;
    }
    int32_t message_len = message.length();
    response->Return(message_len);
  }

  DISALLOW_COPY_AND_ASSIGN(MyDbusObject);
};
*/

#ifndef LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_H_
#define LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_H_

#include <map>
#include <memory>
#include <string>
#include <utility>

#include <base/bind.h>
#include <base/callback_helpers.h>
#include <base/macros.h>
#include <base/memory/weak_ptr.h>
#include <brillo/brillo_export.h>
#include <brillo/dbus/async_event_sequencer.h>
#include <brillo/dbus/dbus_object_internal_impl.h>
#include <brillo/dbus/dbus_signal.h>
#include <brillo/dbus/exported_property_set.h>
#include <brillo/errors/error.h>
#include <dbus/bus.h>
#include <dbus/exported_object.h>
#include <dbus/message.h>
#include <dbus/object_path.h>

namespace brillo {
namespace dbus_utils {

class ExportedObjectManager;
class ExportedPropertyBase;
class DBusObject;

// This is an implementation proxy class for a D-Bus interface of an object.
// The important functionality for the users is the ability to add D-Bus method
// handlers and define D-Bus object properties. This is achieved by using one
// of the overload of AddSimpleMethodHandler()/AddMethodHandler() and
// AddProperty() respectively.
// There are three overloads for DBusInterface::AddSimpleMethodHandler() and
// AddMethodHandler() each:
//  1. That takes a handler as base::Callback
//  2. That takes a static function
//  3. That takes a class instance pointer and a class member function
// The signature of the handler for AddSimpleMethodHandler must be one of:
//    R(Args... args)                     [IN only]
//    void(Args... args)                  [IN/OUT]
// The signature of the handler for AddSimpleMethodHandlerWithError must be:
//    bool(ErrorPtr* error, Args... args) [IN/OUT]
// The signature of the handler for AddSimpleMethodHandlerWithErrorAndMessage:
//    bool(ErrorPtr* error, dbus::Message* msg, Args... args) [IN/OUT]
// The signature of the handler for AddMethodHandler must be:
//    void(std::unique_ptr<DBusMethodResponse<T...>> response,
//         Args... args) [IN]
// The signature of the handler for AddMethodHandlerWithMessage must be:
//    void(std::unique_ptr<DBusMethodResponse<T...>> response,
//         dbus::Message* msg, Args... args) [IN]
// There is also an AddRawMethodHandler() call that lets provide a custom
// handler that can parse its own input parameter and construct a custom
// response.
// The signature of the handler for AddRawMethodHandler must be:
//    void(dbus::MethodCall* method_call, ResponseSender sender)
class BRILLO_EXPORT DBusInterface final {
 public:
  DBusInterface(DBusObject* dbus_object, const std::string& interface_name);

  // Register sync DBus method handler for |method_name| as base::Callback.
  template<typename R, typename... Args>
  inline void AddSimpleMethodHandler(
      const std::string& method_name,
      const base::Callback<R(Args...)>& handler) {
    Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
        this, method_name, handler);
  }

  // Register sync D-Bus method handler for |method_name| as a static
  // function.
  template<typename R, typename... Args>
  inline void AddSimpleMethodHandler(const std::string& method_name,
                                     R(*handler)(Args...)) {
    Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
        this, method_name, base::Bind(handler));
  }

  // Register sync D-Bus method handler for |method_name| as a class member
  // function.
  template<typename Instance, typename Class, typename R, typename... Args>
  inline void AddSimpleMethodHandler(const std::string& method_name,
                                     Instance instance,
                                     R(Class::*handler)(Args...)) {
    Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Same as above but for const-method of a class.
  template<typename Instance, typename Class, typename R, typename... Args>
  inline void AddSimpleMethodHandler(const std::string& method_name,
                                     Instance instance,
                                     R(Class::*handler)(Args...) const) {
    Handler<SimpleDBusInterfaceMethodHandler<R, Args...>>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Register sync DBus method handler for |method_name| as base::Callback.
  template<typename... Args>
  inline void AddSimpleMethodHandlerWithError(
      const std::string& method_name,
      const base::Callback<bool(ErrorPtr*, Args...)>& handler) {
    Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
        this, method_name, handler);
  }

  // Register sync D-Bus method handler for |method_name| as a static
  // function.
  template<typename... Args>
  inline void AddSimpleMethodHandlerWithError(
      const std::string& method_name,
      bool(*handler)(ErrorPtr*, Args...)) {
    Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
        this, method_name, base::Bind(handler));
  }

  // Register sync D-Bus method handler for |method_name| as a class member
  // function.
  template<typename Instance, typename Class, typename... Args>
  inline void AddSimpleMethodHandlerWithError(
      const std::string& method_name,
      Instance instance,
      bool(Class::*handler)(ErrorPtr*, Args...)) {
    Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Same as above but for const-method of a class.
  template<typename Instance, typename Class, typename... Args>
  inline void AddSimpleMethodHandlerWithError(
      const std::string& method_name,
      Instance instance,
      bool(Class::*handler)(ErrorPtr*, Args...) const) {
    Handler<SimpleDBusInterfaceMethodHandlerWithError<Args...>>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Register sync DBus method handler for |method_name| as base::Callback.
  // Passing the method sender as a first parameter to the callback.
  template <typename... Args>
  inline void AddSimpleMethodHandlerWithErrorAndMessage(
      const std::string& method_name,
      const base::Callback<bool(ErrorPtr*, ::dbus::Message*, Args...)>&
          handler) {
    Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
        this, method_name, handler);
  }

  // Register sync D-Bus method handler for |method_name| as a static
  // function. Passing the method D-Bus message as the second parameter to the
  // callback.
  template <typename... Args>
  inline void AddSimpleMethodHandlerWithErrorAndMessage(
      const std::string& method_name,
      bool (*handler)(ErrorPtr*, ::dbus::Message*, Args...)) {
    Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
        this, method_name, base::Bind(handler));
  }

  // Register sync D-Bus method handler for |method_name| as a class member
  // function. Passing the method D-Bus message as the second parameter to the
  // callback.
  template <typename Instance, typename Class, typename... Args>
  inline void AddSimpleMethodHandlerWithErrorAndMessage(
      const std::string& method_name,
      Instance instance,
      bool (Class::*handler)(ErrorPtr*, ::dbus::Message*, Args...)) {
    Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Same as above but for const-method of a class.
  template <typename Instance, typename Class, typename... Args>
  inline void AddSimpleMethodHandlerWithErrorAndMessage(
      const std::string& method_name,
      Instance instance,
      bool (Class::*handler)(ErrorPtr*, ::dbus::Message*, Args...) const) {
    Handler<SimpleDBusInterfaceMethodHandlerWithErrorAndMessage<Args...>>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Register an async DBus method handler for |method_name| as base::Callback.
  template<typename Response, typename... Args>
  inline void AddMethodHandler(
      const std::string& method_name,
      const base::Callback<void(std::unique_ptr<Response>, Args...)>& handler) {
    static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
                  "Response must be DBusMethodResponse<T...>");
    Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
        this, method_name, handler);
  }

  // Register an async D-Bus method handler for |method_name| as a static
  // function.
  template<typename Response, typename... Args>
  inline void AddMethodHandler(
      const std::string& method_name,
      void (*handler)(std::unique_ptr<Response>, Args...)) {
    static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
                  "Response must be DBusMethodResponse<T...>");
    Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
        this, method_name, base::Bind(handler));
  }

  // Register an async D-Bus method handler for |method_name| as a class member
  // function.
  template<typename Response,
           typename Instance,
           typename Class,
           typename... Args>
  inline void AddMethodHandler(
      const std::string& method_name,
      Instance instance,
      void(Class::*handler)(std::unique_ptr<Response>, Args...)) {
    static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
                  "Response must be DBusMethodResponse<T...>");
    Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Same as above but for const-method of a class.
  template<typename Response,
           typename Instance,
           typename Class,
           typename... Args>
  inline void AddMethodHandler(
      const std::string& method_name,
      Instance instance,
      void(Class::*handler)(std::unique_ptr<Response>, Args...) const) {
    static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
                  "Response must be DBusMethodResponse<T...>");
    Handler<DBusInterfaceMethodHandler<Response, Args...>>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Register an async DBus method handler for |method_name| as base::Callback.
  template <typename Response, typename... Args>
  inline void AddMethodHandlerWithMessage(
      const std::string& method_name,
      const base::Callback<void(
          std::unique_ptr<Response>, ::dbus::Message*, Args...)>& handler) {
    static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
                  "Response must be DBusMethodResponse<T...>");
    Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
        this, method_name, handler);
  }

  // Register an async D-Bus method handler for |method_name| as a static
  // function.
  template <typename Response, typename... Args>
  inline void AddMethodHandlerWithMessage(
      const std::string& method_name,
      void (*handler)(std::unique_ptr<Response>, ::dbus::Message*, Args...)) {
    static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
                  "Response must be DBusMethodResponse<T...>");
    Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
        this, method_name, base::Bind(handler));
  }

  // Register an async D-Bus method handler for |method_name| as a class member
  // function.
  template <typename Response,
            typename Instance,
            typename Class,
            typename... Args>
  inline void AddMethodHandlerWithMessage(
      const std::string& method_name,
      Instance instance,
      void (Class::*handler)(std::unique_ptr<Response>,
                             ::dbus::Message*,
                             Args...)) {
    static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
                  "Response must be DBusMethodResponse<T...>");
    Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Same as above but for const-method of a class.
  template <typename Response,
            typename Instance,
            typename Class,
            typename... Args>
  inline void AddMethodHandlerWithMessage(
      const std::string& method_name,
      Instance instance,
      void (Class::*handler)(std::unique_ptr<Response>,
                             ::dbus::Message*,
                             Args...) const) {
    static_assert(std::is_base_of<DBusMethodResponseBase, Response>::value,
                  "Response must be DBusMethodResponse<T...>");
    Handler<DBusInterfaceMethodHandlerWithMessage<Response, Args...>>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Register a raw D-Bus method handler for |method_name| as base::Callback.
  inline void AddRawMethodHandler(
      const std::string& method_name,
      const base::Callback<void(::dbus::MethodCall*, ResponseSender)>&
          handler) {
    Handler<RawDBusInterfaceMethodHandler>::Add(this, method_name, handler);
  }

  // Register a raw D-Bus method handler for |method_name| as a class member
  // function.
  template <typename Instance, typename Class>
  inline void AddRawMethodHandler(const std::string& method_name,
                                  Instance instance,
                                  void (Class::*handler)(::dbus::MethodCall*,
                                                         ResponseSender)) {
    Handler<RawDBusInterfaceMethodHandler>::Add(
        this, method_name, base::Bind(handler, instance));
  }

  // Register a D-Bus property.
  void AddProperty(const std::string& property_name,
                   ExportedPropertyBase* prop_base);

  // Unregisters a D-Bus property.
  void RemoveProperty(const std::string& property_name);

  // Registers a D-Bus signal that has a specified number and types (|Args|) of
  // arguments. Returns a weak pointer to the DBusSignal object which can be
  // used to send the signal on this interface when needed:
  /*
    DBusInterface* itf = dbus_object->AddOrGetInterface("Interface");
    auto signal = itf->RegisterSignal<int, bool>("MySignal");
    ...
    // Send the Interface.MySig(12, true) signal.
    if (signal.lock()->Send(12, true)) { ... }
  */
  // Or if the signal signature is long or complex, you can alias the
  // DBusSignal<Args...> signal type and use RegisterSignalOfType method
  // instead:
  /*
    DBusInterface* itf = dbus_object->AddOrGetInterface("Interface");
    using MySignal = DBusSignal<int, bool>;
    auto signal = itf->RegisterSignalOfType<MySignal>("MySignal");
    ...
    // Send the Interface.MySig(12, true) signal.
    if (signal.lock()->Send(12, true)) { ... }
  */
  // If the signal with the given name was already registered, the existing
  // copy of the signal proxy object is returned as long as the method signature
  // of the original signal matches the current call. If it doesn't, the method
  // aborts.

  // RegisterSignalOfType can be used to create a signal if the type of the
  // complete DBusSignal<Args...> class which is pre-defined/aliased earlier.
  template<typename DBusSignalType>
  inline std::weak_ptr<DBusSignalType> RegisterSignalOfType(
      const std::string& signal_name) {
    auto signal = std::make_shared<DBusSignalType>(
        dbus_object_, interface_name_, signal_name);
    AddSignalImpl(signal_name, signal);
    return signal;
  }

  // For simple signal arguments, you can specify their types directly in
  // RegisterSignal<t1, t2, ...>():
  //  auto signal = itf->RegisterSignal<int>("SignalName");
  // This will create a callback signal object that expects one int argument.
  template<typename... Args>
  inline std::weak_ptr<DBusSignal<Args...>> RegisterSignal(
      const std::string& signal_name) {
    return RegisterSignalOfType<DBusSignal<Args...>>(signal_name);
  }

 private:
  // Helper to create an instance of DBusInterfaceMethodHandlerInterface-derived
  // handler and add it to the method handler map of the interface.
  // This makes the actual AddXXXMethodHandler() methods very light-weight and
  // easier to provide different overloads for various method handler kinds.
  // Using struct here to allow partial specialization on HandlerType while
  // letting the compiler to deduce the type of the callback without explicitly
  // specifying it.
  template<typename HandlerType>
  struct Handler {
    template<typename CallbackType>
    inline static void Add(DBusInterface* self,
                           const std::string& method_name,
                           const CallbackType& callback) {
      std::unique_ptr<DBusInterfaceMethodHandlerInterface> sync_method_handler(
          new HandlerType(callback));
      self->AddHandlerImpl(method_name, std::move(sync_method_handler));
    }
  };
  // A generic D-Bus method handler for the interface. It extracts the method
  // name from |method_call|, looks up a registered handler from |handlers_|
  // map and dispatched the call to that handler.
  void HandleMethodCall(::dbus::MethodCall* method_call, ResponseSender sender);
  // Helper to add a handler for method |method_name| to the |handlers_| map.
  // Not marked BRILLO_PRIVATE because it needs to be called by the inline
  // template functions AddMethodHandler(...)
  void AddHandlerImpl(
      const std::string& method_name,
      std::unique_ptr<DBusInterfaceMethodHandlerInterface> handler);
  // Helper to add a signal object to the |signals_| map.
  // Not marked BRILLO_PRIVATE because it needs to be called by the inline
  // template function RegisterSignalOfType(...)
  void AddSignalImpl(const std::string& signal_name,
                     const std::shared_ptr<DBusSignalBase>& signal);
  // Exports all the methods and properties of this interface and claims the
  // D-Bus interface.
  // object_manager - ExportedObjectManager instance that notifies D-Bus
  //                  listeners of a new interface being claimed.
  // exported_object - instance of D-Bus object the interface is being added to.
  // object_path - D-Bus object path for the object instance.
  // interface_name - name of interface being registered.
  // completion_callback - a callback to be called when the asynchronous
  //                       registration operation is completed.
  BRILLO_PRIVATE void ExportAsync(
      ExportedObjectManager* object_manager,
      ::dbus::Bus* bus,
      ::dbus::ExportedObject* exported_object,
      const ::dbus::ObjectPath& object_path,
      const AsyncEventSequencer::CompletionAction& completion_callback);
  // Exports all the methods and properties of this interface and claims the
  // D-Bus interface synchronously.
  // object_manager - ExportedObjectManager instance that notifies D-Bus
  //                  listeners of a new interface being claimed.
  // exported_object - instance of D-Bus object the interface is being added to.
  // object_path - D-Bus object path for the object instance.
  // interface_name - name of interface being registered.
  BRILLO_PRIVATE void ExportAndBlock(ExportedObjectManager* object_manager,
                                     ::dbus::Bus* bus,
                                     ::dbus::ExportedObject* exported_object,
                                     const ::dbus::ObjectPath& object_path);
  // Releases the D-Bus interface and unexports all the methods asynchronously.
  BRILLO_PRIVATE void UnexportAsync(
      ExportedObjectManager* object_manager,
      ::dbus::ExportedObject* exported_object,
      const ::dbus::ObjectPath& object_path,
      const AsyncEventSequencer::CompletionAction& completion_callback);
  // Releases the D-Bus interface and unexports all the methods synchronously.
  BRILLO_PRIVATE void UnexportAndBlock(ExportedObjectManager* object_manager,
                                       ::dbus::ExportedObject* exported_object,
                                       const ::dbus::ObjectPath& object_path);

  BRILLO_PRIVATE void ClaimInterface(
      base::WeakPtr<ExportedObjectManager> object_manager,
      const ::dbus::ObjectPath& object_path,
      const ExportedPropertySet::PropertyWriter& writer,
      bool all_succeeded);

  // Method registration map.
  std::map<std::string, std::unique_ptr<DBusInterfaceMethodHandlerInterface>>
      handlers_;
  // Signal registration map.
  std::map<std::string, std::shared_ptr<DBusSignalBase>> signals_;

  friend class DBusObject;
  friend class DBusInterfaceTestHelper;
  DBusObject* dbus_object_;
  std::string interface_name_;
  base::ScopedClosureRunner release_interface_cb_;

  base::WeakPtrFactory<DBusInterface> weak_factory_{this};
  DISALLOW_COPY_AND_ASSIGN(DBusInterface);
};

// A D-Bus object implementation class. Manages the interfaces implemented
// by this object.
class BRILLO_EXPORT DBusObject {
 public:
  using PropertyHandlerSetupCallback = base::Callback<void(
      DBusInterface* prop_interface, ExportedPropertySet* property_set)>;

  // object_manager - ExportedObjectManager instance that notifies D-Bus
  //                  listeners of a new interface being claimed and property
  //                  changes on those interfaces.
  // object_path - D-Bus object path for the object instance.
  DBusObject(ExportedObjectManager* object_manager,
             const scoped_refptr<::dbus::Bus>& bus,
             const ::dbus::ObjectPath& object_path);

  // property_handler_setup_callback - To be called when setting up property
  //                                   method handlers. Clients can register
  //                                   their own custom property method handlers
  //                                   (GetAll/Get/Set) by passing in this
  //                                   callback.
  DBusObject(ExportedObjectManager* object_manager,
             const scoped_refptr<::dbus::Bus>& bus,
             const ::dbus::ObjectPath& object_path,
             PropertyHandlerSetupCallback property_handler_setup_callback);

  virtual ~DBusObject();

  // Returns an proxy handler for the interface |interface_name|. If the
  // interface proxy does not exist yet, it will be automatically created.
  DBusInterface* AddOrGetInterface(const std::string& interface_name);

  // Finds an interface with the given name. Returns nullptr if there is no
  // interface registered by this name.
  DBusInterface* FindInterface(const std::string& interface_name) const;

  // Removes the previously added proxy handler for the interface
  // |interface_name|.
  void RemoveInterface(const std::string& interface_name);

  // Exports a proxy handler for the interface |interface_name|. If the
  // interface proxy does not exist yet, it will be automatically created.
  void ExportInterfaceAsync(
      const std::string& interface_name,
      const AsyncEventSequencer::CompletionAction& completion_callback);

  // Exports a proxy handler for the interface |interface_name|. If the
  // interface proxy does not exist yet, it will be automatically created. This
  // call is synchronous and will block until all methods of the interface are
  // registered and the interface is claimed.
  void ExportInterfaceAndBlock(const std::string& interface_name);

  // Unexports the interface |interface_name| and unexports all method handlers.
  // In some cases, one may want to export an interface even after it's removed.
  // In that case, they should call this method before removing the interface
  // to make sure it will start with a clean state of method handlers.
  void UnexportInterfaceAsync(
      const std::string& interface_name,
      const AsyncEventSequencer::CompletionAction& completion_callback);

  // Unexports the interface |interface_name| and unexports all method handlers.
  // In some cases, one may want to export an interface even after it's removed.
  // In that case, they should call this method before removing the interface
  // to make sure it will start with a clean state of method handlers.
  // This call is synchronous and will block until the interface is released and
  // all of its methods of are unregistered.
  void UnexportInterfaceAndBlock(const std::string& interface_name);

  // Registers the object instance with D-Bus. This is an asynchronous call
  // that will call |completion_callback| when the object and all of its
  // interfaces are registered.
  virtual void RegisterAsync(
      const AsyncEventSequencer::CompletionAction& completion_callback);

  // Registers the object instance with D-Bus. This is call is synchronous and
  // will block until the object and all of its interfaces are registered.
  virtual void RegisterAndBlock();

  // Unregister the object instance with D-Bus.  This will unregister the
  // |exported_object_| and its path from the bus.  The destruction of
  // |exported_object_| will be deferred in an async task posted by the bus.
  // It is guarantee that upon return from this call a new DBusObject with the
  // same object path can be created/registered.
  virtual void UnregisterAsync();

  // Returns the ExportedObjectManager proxy, if any. If DBusObject has been
  // constructed without an object manager, this method returns an empty
  // smart pointer (containing nullptr).
  const base::WeakPtr<ExportedObjectManager>& GetObjectManager() const {
    return object_manager_;
  }

  // Sends a signal from the exported D-Bus object.
  bool SendSignal(::dbus::Signal* signal);

  // Returns the reference to dbus::Bus this object is associated with.
  scoped_refptr<::dbus::Bus> GetBus() { return bus_; }

 private:
  // Add the org.freedesktop.DBus.Properties interface to the object.
  void RegisterPropertiesInterface();

  // A map of all the interfaces added to this object.
  std::map<std::string, std::unique_ptr<DBusInterface>> interfaces_;
  // Exported property set for properties registered with the interfaces
  // implemented by this D-Bus object.
  ExportedPropertySet property_set_;
  // Delegate object implementing org.freedesktop.DBus.ObjectManager interface.
  base::WeakPtr<ExportedObjectManager> object_manager_;
  // D-Bus bus object.
  scoped_refptr<::dbus::Bus> bus_;
  // D-Bus object path for this object.
  ::dbus::ObjectPath object_path_;
  // D-Bus object instance once this object is successfully exported.
  ::dbus::ExportedObject* exported_object_ = nullptr;  // weak; owned by |bus_|.
  // Sets up property method handlers.
  PropertyHandlerSetupCallback property_handler_setup_callback_;

  friend class DBusInterface;
  DISALLOW_COPY_AND_ASSIGN(DBusObject);
};

}  // namespace dbus_utils
}  // namespace brillo

#endif  // LIBBRILLO_BRILLO_DBUS_DBUS_OBJECT_H_
