buffet: Switch buffet::Manager to use DBusObject

Use DBusObject to implement "/org/chromium/Buffet/Manager" object.

BUG=chromium:374864
TEST=USE=buffet P2_TEST_FILTER="buffet::*" FEATURES=test emerge-link platform2

Change-Id: I91141ce76a1dbd4478577f2f7548f99a33241fb5
Reviewed-on: https://chromium-review.googlesource.com/212682
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc
index c6aef06..800cfa0 100644
--- a/buffet/device_registration_info.cc
+++ b/buffet/device_registration_info.cc
@@ -53,7 +53,7 @@
     FILE_PATH_LITERAL("/var/lib/buffet/device_reg_info");
 
 bool GetParamValue(
-    const std::map<std::string, std::shared_ptr<base::Value>>& params,
+    const std::map<std::string, std::unique_ptr<base::Value>>& params,
     const std::string& param_name,
     std::string* param_value) {
   auto p = params.find(param_name);
@@ -335,7 +335,7 @@
 }
 
 std::string DeviceRegistrationInfo::StartRegistration(
-    const std::map<std::string, std::shared_ptr<base::Value>>& params,
+    const std::map<std::string, std::unique_ptr<base::Value>>& params,
     chromeos::ErrorPtr* error) {
   GetParamValue(params, storage_keys::kClientId, &client_id_);
   GetParamValue(params, storage_keys::kClientSecret, &client_secret_);
diff --git a/buffet/device_registration_info.h b/buffet/device_registration_info.h
index df23e36..1985bb6 100644
--- a/buffet/device_registration_info.h
+++ b/buffet/device_registration_info.h
@@ -96,7 +96,7 @@
   // and so on. If a particular key-value pair is omitted, a default value
   // is used when possible. Returns a device claim ID on success.
   std::string StartRegistration(
-    const std::map<std::string, std::shared_ptr<base::Value>>& params,
+    const std::map<std::string, std::unique_ptr<base::Value>>& params,
     chromeos::ErrorPtr* error);
 
   // Finalizes the device registration. If |user_auth_code| is provided, then
diff --git a/buffet/device_registration_info_unittest.cc b/buffet/device_registration_info_unittest.cc
index 553a118..635b539 100644
--- a/buffet/device_registration_info_unittest.cc
+++ b/buffet/device_registration_info_unittest.cc
@@ -325,7 +325,7 @@
   transport_->AddHandler(dev_reg_->GetServiceURL("registrationTickets"),
                          request_type::kPost,
                          base::Bind(create_ticket));
-  std::map<std::string, std::shared_ptr<base::Value>> params;
+  std::map<std::string, std::unique_ptr<base::Value>> params;
   std::string json_resp = dev_reg_->StartRegistration(params, nullptr);
   auto json = std::unique_ptr<base::Value>(base::JSONReader::Read(json_resp));
   EXPECT_NE(nullptr, json.get());
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 6c258ba..749e84a 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -22,112 +22,41 @@
 #include "buffet/dbus_constants.h"
 
 using chromeos::dbus_utils::AsyncEventSequencer;
-using chromeos::dbus_utils::GetBadArgsError;
 using chromeos::dbus_utils::ExportedObjectManager;
-using chromeos::dbus_utils::GetDBusError;
 
 namespace buffet {
 
-Manager::Manager(
-    const base::WeakPtr<ExportedObjectManager>& object_manager)
-    : exported_object_(object_manager->GetBus()->GetExportedObject(
-          dbus::ObjectPath(dbus_constants::kManagerServicePath))),
-      object_manager_(object_manager) { }
+Manager::Manager(const base::WeakPtr<ExportedObjectManager>& object_manager)
+    : dbus_object_(object_manager.get(),
+                   object_manager->GetBus(),
+                   dbus::ObjectPath(dbus_constants::kManagerServicePath)) {}
 
-Manager::~Manager() {
-  object_manager_->ReleaseInterface(
-      dbus::ObjectPath(dbus_constants::kManagerServicePath),
-      dbus_constants::kManagerInterface);
-  // Prevent the properties object from making calls to the exported object.
-  properties_.reset(nullptr);
-  // Unregister ourselves from the Bus.  This prevents the bus from calling
-  // our callbacks in between the Manager's death and the bus unregistering
-  // our exported object on shutdown.  Unretained makes no promises of memory
-  // management.
-  exported_object_->Unregister();
-  exported_object_ = nullptr;
-}
-
-void Manager::Init(const OnInitFinish& cb) {
-  scoped_refptr<AsyncEventSequencer> sequencer(
-      new AsyncEventSequencer());
-  exported_object_->ExportMethod(
-      dbus_constants::kManagerInterface,
-      dbus_constants::kManagerCheckDeviceRegistered,
-      chromeos::dbus_utils::GetExportableDBusMethod(
-          base::Bind(&Manager::HandleCheckDeviceRegistered,
-          base::Unretained(this))),
-      sequencer->GetExportHandler(
-          dbus_constants::kManagerInterface,
-          dbus_constants::kManagerCheckDeviceRegistered,
-          "Failed exporting CheckDeviceRegistered method",
-          true));
-  exported_object_->ExportMethod(
-      dbus_constants::kManagerInterface,
-      dbus_constants::kManagerGetDeviceInfo,
-      chromeos::dbus_utils::GetExportableDBusMethod(
-          base::Bind(&Manager::HandleGetDeviceInfo,
-          base::Unretained(this))),
-      sequencer->GetExportHandler(
-          dbus_constants::kManagerInterface,
-          dbus_constants::kManagerGetDeviceInfo,
-          "Failed exporting GetDeviceInfo method",
-          true));
-  exported_object_->ExportMethod(
-      dbus_constants::kManagerInterface,
-      dbus_constants::kManagerStartRegisterDevice,
-      chromeos::dbus_utils::GetExportableDBusMethod(
-          base::Bind(&Manager::HandleStartRegisterDevice,
-          base::Unretained(this))),
-      sequencer->GetExportHandler(
-          dbus_constants::kManagerInterface,
-          dbus_constants::kManagerStartRegisterDevice,
-          "Failed exporting StartRegisterDevice method",
-          true));
-  exported_object_->ExportMethod(
-      dbus_constants::kManagerInterface,
-      dbus_constants::kManagerFinishRegisterDevice,
-      chromeos::dbus_utils::GetExportableDBusMethod(
-          base::Bind(&Manager::HandleFinishRegisterDevice,
-          base::Unretained(this))),
-      sequencer->GetExportHandler(
-          dbus_constants::kManagerInterface,
-          dbus_constants::kManagerFinishRegisterDevice,
-          "Failed exporting FinishRegisterDevice method",
-          true));
-  exported_object_->ExportMethod(
-      dbus_constants::kManagerInterface,
-      dbus_constants::kManagerUpdateStateMethod,
-      chromeos::dbus_utils::GetExportableDBusMethod(
-          base::Bind(&Manager::HandleUpdateState,
-          base::Unretained(this))),
-      sequencer->GetExportHandler(
-          dbus_constants::kManagerInterface,
-          dbus_constants::kManagerUpdateStateMethod,
-          "Failed exporting UpdateState method",
-          true));
-  exported_object_->ExportMethod(
-      dbus_constants::kManagerInterface, dbus_constants::kManagerTestMethod,
-      chromeos::dbus_utils::GetExportableDBusMethod(
-          base::Bind(&Manager::HandleTestMethod, base::Unretained(this))),
-      sequencer->GetExportHandler(
-          dbus_constants::kManagerInterface, dbus_constants::kManagerTestMethod,
-          "Failed exporting TestMethod method",
-          true));
-  properties_.reset(new Properties(object_manager_->GetBus()));
+void Manager::Init(const AsyncEventSequencer::CompletionAction& cb) {
+  chromeos::dbus_utils::DBusInterface* itf =
+      dbus_object_.AddOrGetInterface(dbus_constants::kManagerInterface);
+  itf->AddMethodHandler(dbus_constants::kManagerCheckDeviceRegistered,
+                        base::Unretained(this),
+                        &Manager::HandleCheckDeviceRegistered);
+  itf->AddMethodHandler(dbus_constants::kManagerGetDeviceInfo,
+                        base::Unretained(this),
+                        &Manager::HandleGetDeviceInfo);
+  itf->AddMethodHandler(dbus_constants::kManagerStartRegisterDevice,
+                        base::Unretained(this),
+                        &Manager::HandleStartRegisterDevice);
+  itf->AddMethodHandler(dbus_constants::kManagerFinishRegisterDevice,
+                        base::Unretained(this),
+                        &Manager::HandleFinishRegisterDevice);
+  itf->AddMethodHandler(dbus_constants::kManagerUpdateStateMethod,
+                        base::Unretained(this),
+                        &Manager::HandleUpdateState);
+  itf->AddMethodHandler(dbus_constants::kManagerTestMethod,
+                        base::Unretained(this),
+                        &Manager::HandleTestMethod);
+  itf->AddProperty("State", &state_);
   // TODO(wiley): Initialize all properties appropriately before claiming
   //              the properties interface.
-  properties_->state_.SetValue("{}");
-  properties_->Init(
-      sequencer->GetHandler("Manager properties export failed.", true));
-  auto claim_interface_task = sequencer->WrapCompletionTask(
-      base::Bind(&ExportedObjectManager::ClaimInterface,
-                 object_manager_->AsWeakPtr(),
-                 dbus::ObjectPath(dbus_constants::kManagerServicePath),
-                 dbus_constants::kManagerInterface,
-                 properties_->GetPropertyWriter(
-                     dbus_constants::kManagerInterface)));
-  sequencer->OnAllTasksCompletedCall({claim_interface_task, cb});
+  state_.SetValue("{}");
+  dbus_object_.RegisterAsync(cb);
   command_manager_ = std::make_shared<CommandManager>();
   command_manager_->Startup();
   device_info_ = std::unique_ptr<DeviceRegistrationInfo>(
@@ -135,177 +64,63 @@
   device_info_->Load();
 }
 
-scoped_ptr<dbus::Response> Manager::HandleCheckDeviceRegistered(
-    dbus::MethodCall* method_call) {
-  // Read the parameters to the method.
-  dbus::MessageReader reader(method_call);
-  if (reader.HasMoreData()) {
-    return GetBadArgsError(method_call,
-                           "Too many parameters to CheckDeviceRegistered");
-  }
-
+std::string Manager::HandleCheckDeviceRegistered(chromeos::ErrorPtr* error) {
   LOG(INFO) << "Received call to Manager.CheckDeviceRegistered()";
-
-  chromeos::ErrorPtr error;
-  bool registered = device_info_->CheckRegistration(&error);
+  std::string device_id;
+  bool registered = device_info_->CheckRegistration(error);
   // If it fails due to any reason other than 'device not registered',
   // treat it as a real error and report it to the caller.
   if (!registered &&
-      !error->HasError(kErrorDomainGCD, "device_not_registered")) {
-    return scoped_ptr<dbus::Response>(
-        GetDBusError(method_call, error.get()).release());
+      !(*error)->HasError(kErrorDomainGCD, "device_not_registered")) {
+    return device_id;
   }
 
-  std::string device_id;
-  if (registered) {
-    device_id = device_info_->GetDeviceId(&error);
-    if (device_id.empty())
-      return scoped_ptr<dbus::Response>(
-          GetDBusError(method_call, error.get()).release());
-  }
-  // Send back our response.
-  scoped_ptr<dbus::Response> response(
-      dbus::Response::FromMethodCall(method_call));
-  dbus::MessageWriter writer(response.get());
-  writer.AppendString(device_id);
-  return response.Pass();
+  error->reset();
+
+  if (registered)
+    device_id = device_info_->GetDeviceId(error);
+
+  return device_id;
 }
 
-scoped_ptr<dbus::Response> Manager::HandleGetDeviceInfo(
-    dbus::MethodCall* method_call) {
-  // Read the parameters to the method.
-  dbus::MessageReader reader(method_call);
-  if (reader.HasMoreData()) {
-    return GetBadArgsError(method_call,
-                           "Too many parameters to GetDeviceInfo");
-  }
-
+std::string Manager::HandleGetDeviceInfo(chromeos::ErrorPtr* error) {
   LOG(INFO) << "Received call to Manager.GetDeviceInfo()";
 
   std::string device_info_str;
-  chromeos::ErrorPtr error;
-  auto device_info = device_info_->GetDeviceInfo(&error);
+  auto device_info = device_info_->GetDeviceInfo(error);
   if (!device_info)
-    return scoped_ptr<dbus::Response>(
-        GetDBusError(method_call, error.get()).release());
+    return device_info_str;
 
   base::JSONWriter::Write(device_info.get(), &device_info_str);
-
-  // Send back our response.
-  scoped_ptr<dbus::Response> response(
-      dbus::Response::FromMethodCall(method_call));
-  dbus::MessageWriter writer(response.get());
-  writer.AppendString(device_info_str);
-  return response.Pass();
+  return device_info_str;
 }
 
-scoped_ptr<dbus::Response> Manager::HandleStartRegisterDevice(
-    dbus::MethodCall* method_call) {
-  // Read the parameters to the method.
-  dbus::MessageReader reader(method_call);
-  if (!reader.HasMoreData()) {
-    return GetBadArgsError(method_call, "No parameters to StartRegisterDevice");
-  }
-
-  dbus::MessageReader array_reader(nullptr);
-  if (!reader.PopArray(&array_reader))
-    return GetBadArgsError(method_call, "Failed to read the parameter array");
-  std::map<std::string, std::shared_ptr<base::Value>> params;
-  while (array_reader.HasMoreData()) {
-    dbus::MessageReader dict_entry_reader(nullptr);
-    if (!array_reader.PopDictEntry(&dict_entry_reader))
-      return GetBadArgsError(method_call, "Failed to get a call parameter");
-    std::string key;
-    if (!dict_entry_reader.PopString(&key))
-      return GetBadArgsError(method_call, "Failed to read parameter key");
-    base::Value* value = dbus::PopDataAsValue(&dict_entry_reader);
-    if (!value)
-      return GetBadArgsError(method_call, "Failed to read parameter value");
-    params.insert(std::make_pair(key, std::shared_ptr<base::Value>(value)));
-  }
-  if (reader.HasMoreData())
-    return GetBadArgsError(method_call,
-                           "Too many parameters to StartRegisterDevice");
-
+std::string Manager::HandleStartRegisterDevice(
+    chromeos::ErrorPtr* error,
+    const std::map<std::string,
+    std::unique_ptr<base::Value>>& params) {
   LOG(INFO) << "Received call to Manager.StartRegisterDevice()";
 
-  chromeos::ErrorPtr error;
-  std::string id = device_info_->StartRegistration(params, &error);
-  if (id.empty())
-    return scoped_ptr<dbus::Response>(
-        GetDBusError(method_call, error.get()).release());
-
-  // Send back our response.
-  scoped_ptr<dbus::Response> response(
-      dbus::Response::FromMethodCall(method_call));
-  dbus::MessageWriter writer(response.get());
-  writer.AppendString(id);
-  return response.Pass();
+  return device_info_->StartRegistration(params, error);
 }
 
-scoped_ptr<dbus::Response> Manager::HandleFinishRegisterDevice(
-  dbus::MethodCall* method_call) {
-  // Read the parameters to the method.
-  dbus::MessageReader reader(method_call);
-  if (!reader.HasMoreData()) {
-    return GetBadArgsError(method_call,
-                           "No parameters to FinishRegisterDevice");
-  }
-  std::string user_auth_code;
-  if (!reader.PopString(&user_auth_code)) {
-    return GetBadArgsError(method_call, "Failed to read UserAuthCode");
-  }
-  if (reader.HasMoreData()) {
-    return GetBadArgsError(method_call,
-                           "Too many parameters to FinishRegisterDevice");
-  }
-
+std::string Manager::HandleFinishRegisterDevice(
+    chromeos::ErrorPtr* error, const std::string& user_auth_code) {
   LOG(INFO) << "Received call to Manager.FinishRegisterDevice()";
-  chromeos::ErrorPtr error;
-  if (!device_info_->FinishRegistration(user_auth_code, &error))
-    return scoped_ptr<dbus::Response>(
-        GetDBusError(method_call, error.get()).release());
+  if (!device_info_->FinishRegistration(user_auth_code, error))
+    return std::string();
 
-  std::string device_id = device_info_->GetDeviceId(&error);
-  if (device_id.empty())
-    return scoped_ptr<dbus::Response>(
-        GetDBusError(method_call, error.get()).release());
-
-  // Send back our response.
-  scoped_ptr<dbus::Response> response(
-    dbus::Response::FromMethodCall(method_call));
-  dbus::MessageWriter writer(response.get());
-  writer.AppendString(device_id);
-  return response.Pass();
+  return device_info_->GetDeviceId(error);
 }
 
-scoped_ptr<dbus::Response> Manager::HandleUpdateState(
-    dbus::MethodCall *method_call) {
-  // Read the parameters to the method.
-  dbus::MessageReader reader(method_call);
-  if (!reader.HasMoreData()) {
-    return GetBadArgsError(method_call, "No parameters to UpdateState");
-  }
-  std::string json_state_fragment;
-  if (!reader.PopString(&json_state_fragment)) {
-    return GetBadArgsError(method_call, "Failed to read json_state_fragment");
-  }
-  if (reader.HasMoreData()) {
-    return GetBadArgsError(method_call, "Too many parameters to UpdateState");
-  }
-
-  LOG(INFO) << "Received call to Manager.UpdateState()";
+void Manager::HandleUpdateState(
+    chromeos::ErrorPtr* error, const std::string& json_state_fragment) {
   // TODO(wiley): Merge json state blobs intelligently.
-  properties_->state_.SetValue(json_state_fragment);
-
-  // Send back our response.
-  return dbus::Response::FromMethodCall(method_call);
+  state_.SetValue(json_state_fragment);
 }
 
-scoped_ptr<dbus::Response> Manager::HandleTestMethod(
-    dbus::MethodCall* method_call) {
-  LOG(INFO) << "Received call to test method.";
-  return scoped_ptr<dbus::Response>();
+void Manager::HandleTestMethod(chromeos::ErrorPtr* error) {
+  LOG(INFO) << "Received call to test method";
 }
 
 }  // namespace buffet
diff --git a/buffet/manager.h b/buffet/manager.h
index 2bb9d5f..73ed8aa 100644
--- a/buffet/manager.h
+++ b/buffet/manager.h
@@ -5,19 +5,17 @@
 #ifndef BUFFET_MANAGER_H_
 #define BUFFET_MANAGER_H_
 
+#include <map>
 #include <memory>
 #include <string>
 
 #include <base/basictypes.h>
-#include <base/memory/scoped_ptr.h>
 #include <base/memory/weak_ptr.h>
 #include <base/values.h>
+#include <chromeos/dbus/dbus_object.h>
+#include <chromeos/error.h>
 #include <chromeos/exported_property_set.h>
-#include <dbus/bus.h>
-#include <dbus/message.h>
-#include <dbus/object_path.h>
 
-#include "buffet/dbus_constants.h"
 #include "buffet/device_registration_info.h"
 
 namespace chromeos {
@@ -33,49 +31,37 @@
 // The Manager is responsible for global state of Buffet.  It exposes
 // interfaces which affect the entire device such as device registration and
 // device state.
-class Manager {
+class Manager final {
  public:
-  typedef base::Callback<void(bool success)> OnInitFinish;
-
-  Manager(const base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager>&
-              object_manager);
-  ~Manager();
-  void Init(const OnInitFinish& cb);
+  explicit Manager(
+      const base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager>&
+          object_manager);
+  void Init(
+      const chromeos::dbus_utils::AsyncEventSequencer::CompletionAction& cb);
 
  private:
-  struct Properties: public chromeos::dbus_utils::ExportedPropertySet {
-   public:
-    chromeos::dbus_utils::ExportedProperty<std::string> state_;
-    explicit Properties(dbus::Bus* bus)
-        : chromeos::dbus_utils::ExportedPropertySet(
-              bus, dbus::ObjectPath(dbus_constants::kManagerServicePath)) {
-      RegisterProperty(dbus_constants::kManagerInterface, "State", &state_);
-    }
-    virtual ~Properties() {}
-  };
+  // DBus properties:
+  chromeos::dbus_utils::ExportedProperty<std::string> state_;
 
+  // DBus methods:
   // Handles calls to org.chromium.Buffet.Manager.CheckDeviceRegistered().
-  scoped_ptr<dbus::Response> HandleCheckDeviceRegistered(
-      dbus::MethodCall* method_call);
+  std::string HandleCheckDeviceRegistered(chromeos::ErrorPtr* error);
   // Handles calls to org.chromium.Buffet.Manager.GetDeviceInfo().
-  scoped_ptr<dbus::Response> HandleGetDeviceInfo(
-      dbus::MethodCall* method_call);
+  std::string HandleGetDeviceInfo(chromeos::ErrorPtr* error);
   // Handles calls to org.chromium.Buffet.Manager.StartRegisterDevice().
-  scoped_ptr<dbus::Response> HandleStartRegisterDevice(
-      dbus::MethodCall* method_call);
+  std::string HandleStartRegisterDevice(chromeos::ErrorPtr* error,
+                                        const std::map<std::string,
+                                        std::unique_ptr<base::Value>>& params);
   // Handles calls to org.chromium.Buffet.Manager.FinishRegisterDevice().
-  scoped_ptr<dbus::Response> HandleFinishRegisterDevice(
-      dbus::MethodCall* method_call);
+  std::string HandleFinishRegisterDevice(chromeos::ErrorPtr* error,
+                                         const std::string& user_auth_code);
   // Handles calls to org.chromium.Buffet.Manager.UpdateState().
-  scoped_ptr<dbus::Response> HandleUpdateState(
-      dbus::MethodCall* method_call);
+  void HandleUpdateState(chromeos::ErrorPtr* error,
+                         const std::string& json_state_fragment);
   // Handles calls to org.chromium.Buffet.Manager.Test()
-  scoped_ptr<::dbus::Response> HandleTestMethod(
-      ::dbus::MethodCall* method_call);
+  void HandleTestMethod(chromeos::ErrorPtr* error);
 
-  dbus::ExportedObject* exported_object_;  // weak; owned by the Bus object.
-  base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager> object_manager_;
-  scoped_ptr<Properties> properties_;
+  chromeos::dbus_utils::DBusObject dbus_object_;
 
   std::shared_ptr<CommandManager> command_manager_;
   std::unique_ptr<DeviceRegistrationInfo> device_info_;