buffet: Move commands/dbus_* our of libweave

This code is owned by buffet now.

BUG=brillo:1245
TEST='FEATURES=test emerge-gizmo buffet'

Change-Id: I148336aba06a89167539fdd8d987080ec4cda82d
Reviewed-on: https://chromium-review.googlesource.com/287126
Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
Tested-by: Vitaly Buka <vitalybuka@chromium.org>
Reviewed-by: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/buffet/buffet.gyp b/buffet/buffet.gyp
index d6fb0ad..8d22323 100644
--- a/buffet/buffet.gyp
+++ b/buffet/buffet.gyp
@@ -27,6 +27,9 @@
       'sources': [
         'dbus_bindings/org.chromium.Buffet.Command.xml',
         'dbus_bindings/org.chromium.Buffet.Manager.xml',
+        'dbus_command_dispatcher.cc',
+        'dbus_command_proxy.cc',
+        'dbus_conversion.cc',
         'dbus_constants.cc',
         'manager.cc',
         '../libweave/src/base_api_handler.cc',
@@ -37,9 +40,6 @@
         '../libweave/src/commands/command_instance.cc',
         '../libweave/src/commands/command_manager.cc',
         '../libweave/src/commands/command_queue.cc',
-        '../libweave/src/commands/dbus_command_dispatcher.cc',
-        '../libweave/src/commands/dbus_command_proxy.cc',
-        '../libweave/src/commands/dbus_conversion.cc',
         '../libweave/src/commands/object_schema.cc',
         '../libweave/src/commands/prop_constraints.cc',
         '../libweave/src/commands/prop_types.cc',
@@ -184,6 +184,8 @@
           },
           'includes': ['../common-mk/common_test.gypi'],
           'sources': [
+            'dbus_command_proxy_unittest.cc',
+            'dbus_conversion_unittest.cc',
             '../libweave/src/base_api_handler_unittest.cc',
             '../libweave/src/buffet_config_unittest.cc',
             '../libweave/src/buffet_testrunner.cc',
@@ -193,8 +195,6 @@
             '../libweave/src/commands/command_instance_unittest.cc',
             '../libweave/src/commands/command_manager_unittest.cc',
             '../libweave/src/commands/command_queue_unittest.cc',
-            '../libweave/src/commands/dbus_command_proxy_unittest.cc',
-            '../libweave/src/commands/dbus_conversion_unittest.cc',
             '../libweave/src/commands/mock_command.cc',
             '../libweave/src/commands/object_schema_unittest.cc',
             '../libweave/src/commands/schema_utils_unittest.cc',
diff --git a/buffet/dbus_command_dispatcher.cc b/buffet/dbus_command_dispatcher.cc
new file mode 100644
index 0000000..39e106b
--- /dev/null
+++ b/buffet/dbus_command_dispatcher.cc
@@ -0,0 +1,36 @@
+// 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.
+
+#include "buffet/dbus_command_dispatcher.h"
+
+#include <chromeos/dbus/exported_object_manager.h>
+
+#include "buffet/dbus_command_proxy.h"
+#include "buffet/dbus_constants.h"
+#include "weave/command.h"
+
+using chromeos::dbus_utils::AsyncEventSequencer;
+using chromeos::dbus_utils::ExportedObjectManager;
+
+namespace buffet {
+
+DBusCommandDispacher::DBusCommandDispacher(
+    const base::WeakPtr<ExportedObjectManager>& object_manager,
+    weave::Commands* command_manager)
+    : object_manager_{object_manager} {
+  command_manager->AddOnCommandAddedCallback(base::Bind(
+      &DBusCommandDispacher::OnCommandAdded, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void DBusCommandDispacher::OnCommandAdded(weave::Command* command) {
+  if (!object_manager_)
+    return;
+  std::unique_ptr<DBusCommandProxy> proxy{new DBusCommandProxy(
+      object_manager_.get(), object_manager_->GetBus(), command,
+      buffet::kCommandServicePathPrefix + std::to_string(++next_id_))};
+  proxy->RegisterAsync(AsyncEventSequencer::GetDefaultCompletionAction());
+  command->AddObserver(proxy.release());
+}
+
+}  // namespace buffet
diff --git a/buffet/dbus_command_dispatcher.h b/buffet/dbus_command_dispatcher.h
new file mode 100644
index 0000000..ae8e499
--- /dev/null
+++ b/buffet/dbus_command_dispatcher.h
@@ -0,0 +1,54 @@
+// 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.
+
+#ifndef BUFFET_DBUS_COMMAND_DISPATCHER_H_
+#define BUFFET_DBUS_COMMAND_DISPATCHER_H_
+
+#include <map>
+#include <string>
+
+#include <base/macros.h>
+#include <base/memory/weak_ptr.h>
+
+#include "weave/commands.h"
+
+namespace chromeos {
+namespace dbus_utils {
+class ExportedObjectManager;
+}  // namespace dbus_utils
+}  // namespace chromeos
+
+namespace buffet {
+
+// Implements D-Bus dispatch of commands. When OnCommandAdded is called,
+// DBusCommandDispacher creates an instance of DBusCommandProxy object and
+// advertises it through ExportedObjectManager on D-Bus. Command handling
+// processes can watch the new D-Bus object appear and communicate with it to
+// update the command handling progress. Once command is handled,
+// DBusCommandProxy::Done() is called and the command is removed from the
+// command queue and D-Bus ExportedObjectManager.
+class DBusCommandDispacher final {
+ public:
+  explicit DBusCommandDispacher(
+      const base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager>&
+          object_manager,
+      weave::Commands* command_manager);
+
+ private:
+  void OnCommandAdded(weave::Command* command);
+
+  base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager> object_manager_;
+  int next_id_{0};
+
+  // Default constructor is used in special circumstances such as for testing.
+  DBusCommandDispacher() = default;
+
+  base::WeakPtrFactory<DBusCommandDispacher> weak_ptr_factory_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(DBusCommandDispacher);
+};
+
+}  // namespace buffet
+
+#endif  // BUFFET_DBUS_COMMAND_DISPATCHER_H_
diff --git a/buffet/dbus_command_proxy.cc b/buffet/dbus_command_proxy.cc
new file mode 100644
index 0000000..d53355a
--- /dev/null
+++ b/buffet/dbus_command_proxy.cc
@@ -0,0 +1,103 @@
+// 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.
+
+#include "buffet/dbus_command_proxy.h"
+
+#include <chromeos/dbus/async_event_sequencer.h>
+#include <chromeos/dbus/exported_object_manager.h>
+
+#include "buffet/dbus_conversion.h"
+#include "weave/enum_to_string.h"
+
+using chromeos::dbus_utils::AsyncEventSequencer;
+using chromeos::dbus_utils::ExportedObjectManager;
+
+namespace buffet {
+
+DBusCommandProxy::DBusCommandProxy(ExportedObjectManager* object_manager,
+                                   const scoped_refptr<dbus::Bus>& bus,
+                                   weave::Command* command,
+                                   std::string object_path)
+    : command_{command},
+      dbus_object_{object_manager, bus, dbus::ObjectPath{object_path}} {}
+
+void DBusCommandProxy::RegisterAsync(
+    const AsyncEventSequencer::CompletionAction& completion_callback) {
+  dbus_adaptor_.RegisterWithDBusObject(&dbus_object_);
+
+  // Set the initial property values before registering the DBus object.
+  dbus_adaptor_.SetName(command_->GetName());
+  dbus_adaptor_.SetCategory(command_->GetCategory());
+  dbus_adaptor_.SetId(command_->GetID());
+  dbus_adaptor_.SetStatus(EnumToString(command_->GetStatus()));
+  dbus_adaptor_.SetProgress(
+      DictionaryToDBusVariantDictionary(*command_->GetProgress()));
+  dbus_adaptor_.SetOrigin(EnumToString(command_->GetOrigin()));
+  dbus_adaptor_.SetParameters(
+      DictionaryToDBusVariantDictionary(*command_->GetParameters()));
+  dbus_adaptor_.SetResults(
+      DictionaryToDBusVariantDictionary(*command_->GetResults()));
+
+  // Register the command DBus object and expose its methods and properties.
+  dbus_object_.RegisterAsync(completion_callback);
+}
+
+void DBusCommandProxy::OnResultsChanged() {
+  dbus_adaptor_.SetResults(
+      DictionaryToDBusVariantDictionary(*command_->GetResults()));
+}
+
+void DBusCommandProxy::OnStatusChanged() {
+  dbus_adaptor_.SetStatus(EnumToString(command_->GetStatus()));
+}
+
+void DBusCommandProxy::OnProgressChanged() {
+  dbus_adaptor_.SetProgress(
+      DictionaryToDBusVariantDictionary(*command_->GetProgress()));
+}
+
+void DBusCommandProxy::OnCommandDestroyed() {
+  delete this;
+}
+
+bool DBusCommandProxy::SetProgress(
+    chromeos::ErrorPtr* error,
+    const chromeos::VariantDictionary& progress) {
+  LOG(INFO) << "Received call to Command<" << command_->GetName()
+            << ">::SetProgress()";
+  auto dictionary = DictionaryFromDBusVariantDictionary(progress, error);
+  if (!dictionary)
+    return false;
+  return command_->SetProgress(*dictionary, error);
+}
+
+bool DBusCommandProxy::SetResults(chromeos::ErrorPtr* error,
+                                  const chromeos::VariantDictionary& results) {
+  LOG(INFO) << "Received call to Command<" << command_->GetName()
+            << ">::SetResults()";
+  auto dictionary = DictionaryFromDBusVariantDictionary(results, error);
+  if (!dictionary)
+    return false;
+  return command_->SetResults(*dictionary, error);
+}
+
+void DBusCommandProxy::Abort() {
+  LOG(INFO) << "Received call to Command<" << command_->GetName()
+            << ">::Abort()";
+  command_->Abort();
+}
+
+void DBusCommandProxy::Cancel() {
+  LOG(INFO) << "Received call to Command<" << command_->GetName()
+            << ">::Cancel()";
+  command_->Cancel();
+}
+
+void DBusCommandProxy::Done() {
+  LOG(INFO) << "Received call to Command<" << command_->GetName()
+            << ">::Done()";
+  command_->Done();
+}
+
+}  // namespace buffet
diff --git a/buffet/dbus_command_proxy.h b/buffet/dbus_command_proxy.h
new file mode 100644
index 0000000..86d9c6e
--- /dev/null
+++ b/buffet/dbus_command_proxy.h
@@ -0,0 +1,69 @@
+// 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.
+
+#ifndef BUFFET_DBUS_COMMAND_PROXY_H_
+#define BUFFET_DBUS_COMMAND_PROXY_H_
+
+#include <string>
+
+#include <base/macros.h>
+#include <chromeos/dbus/data_serialization.h>
+#include <chromeos/dbus/dbus_object.h>
+
+#include "buffet/org.chromium.Buffet.Command.h"
+#include "weave/command.h"
+
+namespace chromeos {
+namespace dbus_utils {
+class ExportedObjectManager;
+}  // namespace dbus_utils
+}  // namespace chromeos
+
+namespace buffet {
+
+class DBusCommandProxy : public weave::Command::Observer,
+                         public org::chromium::Buffet::CommandInterface {
+ public:
+  DBusCommandProxy(chromeos::dbus_utils::ExportedObjectManager* object_manager,
+                   const scoped_refptr<dbus::Bus>& bus,
+                   weave::Command* command,
+                   std::string object_path);
+  ~DBusCommandProxy() override = default;
+
+  void RegisterAsync(
+      const chromeos::dbus_utils::AsyncEventSequencer::CompletionAction&
+          completion_callback);
+
+  // CommandProxyInterface implementation/overloads.
+  void OnResultsChanged() override;
+  void OnStatusChanged() override;
+  void OnProgressChanged() override;
+  void OnCommandDestroyed() override;
+
+ private:
+  // Handles calls to org.chromium.Buffet.Command.SetProgress(progress).
+  bool SetProgress(chromeos::ErrorPtr* error,
+                   const chromeos::VariantDictionary& progress) override;
+  // Handles calls to org.chromium.Buffet.Command.SetResults(results).
+  bool SetResults(chromeos::ErrorPtr* error,
+                  const chromeos::VariantDictionary& results) override;
+  // Handles calls to org.chromium.Buffet.Command.Abort().
+  void Abort() override;
+  // Handles calls to org.chromium.Buffet.Command.Cancel().
+  void Cancel() override;
+  // Handles calls to org.chromium.Buffet.Command.Done().
+  void Done() override;
+
+  weave::Command* command_;
+  org::chromium::Buffet::CommandAdaptor dbus_adaptor_{this};
+  chromeos::dbus_utils::DBusObject dbus_object_;
+
+  friend class DBusCommandProxyTest;
+  friend class DBusCommandDispacherTest;
+  DISALLOW_COPY_AND_ASSIGN(DBusCommandProxy);
+};
+
+}  // namespace buffet
+
+#endif  // BUFFET_DBUS_COMMAND_PROXY_H_
diff --git a/buffet/dbus_command_proxy_unittest.cc b/buffet/dbus_command_proxy_unittest.cc
new file mode 100644
index 0000000..93f5d01
--- /dev/null
+++ b/buffet/dbus_command_proxy_unittest.cc
@@ -0,0 +1,206 @@
+// 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.
+
+#include "buffet/dbus_command_proxy.h"
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include <dbus/mock_bus.h>
+#include <dbus/mock_exported_object.h>
+#include <dbus/property.h>
+#include <chromeos/dbus/dbus_object.h>
+#include <chromeos/dbus/dbus_object_test_helpers.h>
+#include <gtest/gtest.h>
+
+#include "buffet/dbus_constants.h"
+#include "weave/command.h"
+#include "weave/enum_to_string.h"
+#include "weave/mock_command.h"
+#include "weave/mock_commands.h"
+#include "weave/unittest_utils.h"
+
+namespace buffet {
+
+using ::testing::AnyNumber;
+using ::testing::Return;
+using ::testing::ReturnRefOfCopy;
+using ::testing::_;
+
+using chromeos::VariantDictionary;
+using chromeos::dbus_utils::AsyncEventSequencer;
+using weave::unittests::CreateDictionaryValue;
+using weave::unittests::IsEqualValue;
+
+namespace {
+
+const char kTestCommandCategoty[] = "test_command_category";
+const char kTestCommandId[] = "cmd_1";
+
+MATCHER_P(EqualToJson, json, "") {
+  auto json_value = CreateDictionaryValue(json);
+  return IsEqualValue(*json_value, arg);
+}
+
+}  // namespace
+
+class DBusCommandProxyTest : public ::testing::Test {
+ public:
+  void SetUp() override {
+    // Set up a mock DBus bus object.
+    dbus::Bus::Options options;
+    options.bus_type = dbus::Bus::SYSTEM;
+    bus_ = new dbus::MockBus(options);
+    // By default, don't worry about threading assertions.
+    EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
+    EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
+
+    EXPECT_CALL(command_, GetID())
+        .WillOnce(ReturnRefOfCopy<std::string>(kTestCommandId));
+    // Use WillRepeatedly becase GetName is used for logging.
+    EXPECT_CALL(command_, GetName())
+        .WillRepeatedly(ReturnRefOfCopy<std::string>("robot.jump"));
+    EXPECT_CALL(command_, GetCategory())
+        .WillOnce(ReturnRefOfCopy<std::string>(kTestCommandCategoty));
+    EXPECT_CALL(command_, GetStatus())
+        .WillOnce(Return(weave::CommandStatus::kQueued));
+    EXPECT_CALL(command_, GetOrigin())
+        .WillOnce(Return(weave::CommandOrigin::kLocal));
+    EXPECT_CALL(command_, MockGetParameters())
+        .WillOnce(ReturnRefOfCopy<std::string>(R"({
+          'height': 53,
+          '_jumpType': '_withKick'
+        })"));
+    EXPECT_CALL(command_, MockGetProgress())
+        .WillOnce(ReturnRefOfCopy<std::string>("{}"));
+    EXPECT_CALL(command_, MockGetResults())
+        .WillOnce(ReturnRefOfCopy<std::string>("{}"));
+
+    // Set up a mock ExportedObject to be used with the DBus command proxy.
+    std::string cmd_path = buffet::kCommandServicePathPrefix;
+    cmd_path += kTestCommandId;
+    const dbus::ObjectPath kCmdObjPath(cmd_path);
+    // Use a mock exported object for the exported object manager.
+    mock_exported_object_command_ =
+        new dbus::MockExportedObject(bus_.get(), kCmdObjPath);
+    EXPECT_CALL(*bus_, GetExportedObject(kCmdObjPath))
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(mock_exported_object_command_.get()));
+    EXPECT_CALL(*mock_exported_object_command_, ExportMethod(_, _, _, _))
+        .Times(AnyNumber());
+
+    proxy_.reset(new DBusCommandProxy(nullptr, bus_, &command_, cmd_path));
+    GetCommandProxy()->RegisterAsync(
+        AsyncEventSequencer::GetDefaultCompletionAction());
+  }
+
+  void TearDown() override {
+    EXPECT_CALL(*mock_exported_object_command_, Unregister()).Times(1);
+    bus_ = nullptr;
+  }
+
+  DBusCommandProxy* GetCommandProxy() const { return proxy_.get(); }
+
+  org::chromium::Buffet::CommandAdaptor* GetCommandAdaptor() const {
+    return &GetCommandProxy()->dbus_adaptor_;
+  }
+
+  org::chromium::Buffet::CommandInterface* GetCommandInterface() const {
+    // DBusCommandProxy also implements CommandInterface.
+    return GetCommandProxy();
+  }
+
+  weave::CommandStatus GetCommandStatus() const {
+    weave::CommandStatus status;
+    EXPECT_TRUE(StringToEnum(GetCommandAdaptor()->GetStatus(), &status));
+    return status;
+  }
+
+  scoped_refptr<dbus::MockExportedObject> mock_exported_object_command_;
+  scoped_refptr<dbus::MockBus> bus_;
+
+  weave::unittests::MockCommand command_;
+  std::unique_ptr<DBusCommandProxy> proxy_;
+};
+
+TEST_F(DBusCommandProxyTest, Init) {
+  VariantDictionary params = {
+      {"height", int32_t{53}}, {"_jumpType", std::string{"_withKick"}},
+  };
+  EXPECT_EQ(weave::CommandStatus::kQueued, GetCommandStatus());
+  EXPECT_EQ(params, GetCommandAdaptor()->GetParameters());
+  EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetProgress());
+  EXPECT_EQ(VariantDictionary{}, GetCommandAdaptor()->GetResults());
+  EXPECT_EQ("robot.jump", GetCommandAdaptor()->GetName());
+  EXPECT_EQ(kTestCommandCategoty, GetCommandAdaptor()->GetCategory());
+  EXPECT_EQ(kTestCommandId, GetCommandAdaptor()->GetId());
+}
+
+TEST_F(DBusCommandProxyTest, OnProgressChanged) {
+  EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
+  EXPECT_CALL(command_, MockGetProgress())
+      .WillOnce(ReturnRefOfCopy<std::string>("{'progress': 10}"));
+  proxy_->OnProgressChanged();
+  EXPECT_EQ((VariantDictionary{{"progress", int32_t{10}}}),
+            GetCommandAdaptor()->GetProgress());
+}
+
+TEST_F(DBusCommandProxyTest, OnResultsChanged) {
+  EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
+  EXPECT_CALL(command_, MockGetResults())
+      .WillOnce(ReturnRefOfCopy<std::string>(
+          "{'foo': 42, 'bar': 'foobar', 'resultList': [1, 2, 3]}"));
+  proxy_->OnResultsChanged();
+
+  EXPECT_EQ((VariantDictionary{{"foo", int32_t{42}},
+                               {"bar", std::string{"foobar"}},
+                               {"resultList", std::vector<int>{1, 2, 3}}}),
+            GetCommandAdaptor()->GetResults());
+}
+
+TEST_F(DBusCommandProxyTest, OnStatusChanged) {
+  EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
+  EXPECT_CALL(command_, GetStatus())
+      .WillOnce(Return(weave::CommandStatus::kInProgress));
+  proxy_->OnStatusChanged();
+  EXPECT_EQ(weave::CommandStatus::kInProgress, GetCommandStatus());
+}
+
+TEST_F(DBusCommandProxyTest, SetProgress) {
+  EXPECT_CALL(command_, SetProgress(EqualToJson("{'progress': 10}"), _))
+      .WillOnce(Return(true));
+  EXPECT_TRUE(
+      GetCommandInterface()->SetProgress(nullptr, {{"progress", int32_t{10}}}));
+}
+
+TEST_F(DBusCommandProxyTest, SetResults) {
+  EXPECT_CALL(
+      command_,
+      SetResults(
+          EqualToJson("{'foo': 42, 'bar': 'foobar', 'resultList': [1, 2, 3]}"),
+          _))
+      .WillOnce(Return(true));
+  EXPECT_TRUE(GetCommandInterface()->SetResults(
+      nullptr, VariantDictionary{{"foo", int32_t{42}},
+                                 {"bar", std::string{"foobar"}},
+                                 {"resultList", std::vector<int>{1, 2, 3}}}));
+}
+
+TEST_F(DBusCommandProxyTest, Abort) {
+  EXPECT_CALL(command_, Abort());
+  GetCommandInterface()->Abort();
+}
+
+TEST_F(DBusCommandProxyTest, Cancel) {
+  EXPECT_CALL(command_, Cancel());
+  GetCommandInterface()->Cancel();
+}
+
+TEST_F(DBusCommandProxyTest, Done) {
+  EXPECT_CALL(command_, Done());
+  GetCommandInterface()->Done();
+}
+
+}  // namespace buffet
diff --git a/buffet/dbus_conversion.cc b/buffet/dbus_conversion.cc
new file mode 100644
index 0000000..51d35f1
--- /dev/null
+++ b/buffet/dbus_conversion.cc
@@ -0,0 +1,246 @@
+// Copyright 2015 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.
+
+#include "buffet/dbus_conversion.h"
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include <chromeos/type_name_undecorate.h>
+
+namespace buffet {
+
+namespace {
+
+// Helpers for JsonToAny().
+template <typename T>
+chromeos::Any ValueToAny(const base::Value& json,
+                         bool (base::Value::*fnc)(T*) const) {
+  T val;
+  CHECK((json.*fnc)(&val));
+  return val;
+}
+
+chromeos::Any ValueToAny(const base::Value& json);
+
+template <typename T>
+chromeos::Any ListToAny(const base::ListValue& list,
+                        bool (base::Value::*fnc)(T*) const) {
+  std::vector<T> result;
+  result.reserve(list.GetSize());
+  for (const base::Value* v : list) {
+    T val;
+    CHECK((v->*fnc)(&val));
+    result.push_back(val);
+  }
+  return result;
+}
+
+chromeos::Any DictListToAny(const base::ListValue& list) {
+  std::vector<chromeos::VariantDictionary> result;
+  result.reserve(list.GetSize());
+  for (const base::Value* v : list) {
+    const base::DictionaryValue* dict = nullptr;
+    CHECK(v->GetAsDictionary(&dict));
+    result.push_back(DictionaryToDBusVariantDictionary(*dict));
+  }
+  return result;
+}
+
+chromeos::Any ListListToAny(const base::ListValue& list) {
+  std::vector<chromeos::Any> result;
+  result.reserve(list.GetSize());
+  for (const base::Value* v : list)
+    result.push_back(ValueToAny(*v));
+  return result;
+}
+
+// Converts a JSON value into an Any so it can be sent over D-Bus using
+// UpdateState D-Bus method from Buffet.
+chromeos::Any ValueToAny(const base::Value& json) {
+  chromeos::Any prop_value;
+  switch (json.GetType()) {
+    case base::Value::TYPE_BOOLEAN:
+      prop_value = ValueToAny<bool>(json, &base::Value::GetAsBoolean);
+      break;
+    case base::Value::TYPE_INTEGER:
+      prop_value = ValueToAny<int>(json, &base::Value::GetAsInteger);
+      break;
+    case base::Value::TYPE_DOUBLE:
+      prop_value = ValueToAny<double>(json, &base::Value::GetAsDouble);
+      break;
+    case base::Value::TYPE_STRING:
+      prop_value = ValueToAny<std::string>(json, &base::Value::GetAsString);
+      break;
+    case base::Value::TYPE_DICTIONARY: {
+      const base::DictionaryValue* dict = nullptr;
+      CHECK(json.GetAsDictionary(&dict));
+      prop_value = DictionaryToDBusVariantDictionary(*dict);
+      break;
+    }
+    case base::Value::TYPE_LIST: {
+      const base::ListValue* list = nullptr;
+      CHECK(json.GetAsList(&list));
+      if (list->empty()) {
+        // We don't know type of objects this list intended for, so we just use
+        // vector<chromeos::Any>.
+        prop_value = ListListToAny(*list);
+        break;
+      }
+      auto type = (*list->begin())->GetType();
+      for (const base::Value* v : *list)
+        CHECK_EQ(v->GetType(), type) << "Unsupported different type elements";
+
+      switch (type) {
+        case base::Value::TYPE_BOOLEAN:
+          prop_value = ListToAny<bool>(*list, &base::Value::GetAsBoolean);
+          break;
+        case base::Value::TYPE_INTEGER:
+          prop_value = ListToAny<int>(*list, &base::Value::GetAsInteger);
+          break;
+        case base::Value::TYPE_DOUBLE:
+          prop_value = ListToAny<double>(*list, &base::Value::GetAsDouble);
+          break;
+        case base::Value::TYPE_STRING:
+          prop_value = ListToAny<std::string>(*list, &base::Value::GetAsString);
+          break;
+        case base::Value::TYPE_DICTIONARY:
+          prop_value = DictListToAny(*list);
+          break;
+        case base::Value::TYPE_LIST:
+          // We can't support Any{vector<vector<>>} as the type is only known
+          // in runtime when we need to instantiate templates in compile time.
+          // We can use Any{vector<Any>} instead.
+          prop_value = ListListToAny(*list);
+          break;
+        default:
+          LOG(FATAL) << "Unsupported JSON value type for list element: "
+                     << (*list->begin())->GetType();
+      }
+      break;
+    }
+    default:
+      LOG(FATAL) << "Unexpected JSON value type: " << json.GetType();
+      break;
+  }
+  return prop_value;
+}
+
+template <typename T>
+std::unique_ptr<base::Value> CreateValue(const T& value,
+                                         chromeos::ErrorPtr* error) {
+  return std::unique_ptr<base::Value>{new base::FundamentalValue{value}};
+}
+
+template <>
+std::unique_ptr<base::Value> CreateValue<std::string>(
+    const std::string& value,
+    chromeos::ErrorPtr* error) {
+  return std::unique_ptr<base::Value>{new base::StringValue{value}};
+}
+
+template <>
+std::unique_ptr<base::Value> CreateValue<chromeos::VariantDictionary>(
+    const chromeos::VariantDictionary& value,
+    chromeos::ErrorPtr* error) {
+  return DictionaryFromDBusVariantDictionary(value, error);
+}
+
+template <typename T>
+std::unique_ptr<base::ListValue> CreateListValue(const std::vector<T>& value,
+                                                 chromeos::ErrorPtr* error) {
+  std::unique_ptr<base::ListValue> list{new base::ListValue};
+
+  for (const T& i : value) {
+    auto item = CreateValue(i, error);
+    if (!item)
+      return nullptr;
+    list->Append(item.release());
+  }
+
+  return list;
+}
+
+// Returns false only in case of error. True can be returned if type is not
+// matched.
+template <typename T>
+bool TryCreateValue(const chromeos::Any& any,
+                    std::unique_ptr<base::Value>* value,
+                    chromeos::ErrorPtr* error) {
+  if (any.IsTypeCompatible<T>()) {
+    *value = CreateValue(any.Get<T>(), error);
+    return *value != nullptr;
+  }
+
+  if (any.IsTypeCompatible<std::vector<T>>()) {
+    *value = CreateListValue(any.Get<std::vector<T>>(), error);
+    return *value != nullptr;
+  }
+
+  return true;  // Not an error, we will try different type.
+}
+
+template <>
+std::unique_ptr<base::Value> CreateValue<chromeos::Any>(
+    const chromeos::Any& any,
+    chromeos::ErrorPtr* error) {
+  std::unique_ptr<base::Value> result;
+  if (!TryCreateValue<bool>(any, &result, error) || result)
+    return result;
+
+  if (!TryCreateValue<int>(any, &result, error) || result)
+    return result;
+
+  if (!TryCreateValue<double>(any, &result, error) || result)
+    return result;
+
+  if (!TryCreateValue<std::string>(any, &result, error) || result)
+    return result;
+
+  if (!TryCreateValue<chromeos::VariantDictionary>(any, &result, error) ||
+      result) {
+    return result;
+  }
+
+  // This will collapse Any{Any{T}} and vector{Any{T}}.
+  if (!TryCreateValue<chromeos::Any>(any, &result, error) || result)
+    return result;
+
+  chromeos::Error::AddToPrintf(
+      error, FROM_HERE, "buffet", "unknown_type", "Type '%s' is not supported.",
+      chromeos::UndecorateTypeName(any.GetType().name()).c_str());
+
+  return nullptr;
+}
+
+}  // namespace
+
+// TODO(vitalybuka): Use in buffet_client.
+chromeos::VariantDictionary DictionaryToDBusVariantDictionary(
+    const base::DictionaryValue& object) {
+  chromeos::VariantDictionary result;
+
+  for (base::DictionaryValue::Iterator it(object); !it.IsAtEnd(); it.Advance())
+    result.emplace(it.key(), ValueToAny(it.value()));
+
+  return result;
+}
+
+std::unique_ptr<base::DictionaryValue> DictionaryFromDBusVariantDictionary(
+    const chromeos::VariantDictionary& object,
+    chromeos::ErrorPtr* error) {
+  std::unique_ptr<base::DictionaryValue> result{new base::DictionaryValue};
+
+  for (const auto& pair : object) {
+    auto value = CreateValue(pair.second, error);
+    if (!value)
+      return nullptr;
+    result->SetWithoutPathExpansion(pair.first, value.release());
+  }
+
+  return result;
+}
+
+}  // namespace buffet
diff --git a/buffet/dbus_conversion.h b/buffet/dbus_conversion.h
new file mode 100644
index 0000000..20c3f58
--- /dev/null
+++ b/buffet/dbus_conversion.h
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+#ifndef BUFFET_DBUS_CONVERSION_H_
+#define BUFFET_DBUS_CONVERSION_H_
+
+#include <base/values.h>
+#include <chromeos/any.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/variant_dictionary.h>
+
+namespace buffet {
+
+// Converts DictionaryValue to D-Bus variant dictionary.
+chromeos::VariantDictionary DictionaryToDBusVariantDictionary(
+    const base::DictionaryValue& object);
+
+// Converts D-Bus variant dictionary to DictionaryValue.
+std::unique_ptr<base::DictionaryValue> DictionaryFromDBusVariantDictionary(
+    const chromeos::VariantDictionary& object,
+    chromeos::ErrorPtr* error);
+
+}  // namespace buffet
+
+#endif  // BUFFET_DBUS_CONVERSION_H_
diff --git a/buffet/dbus_conversion_unittest.cc b/buffet/dbus_conversion_unittest.cc
new file mode 100644
index 0000000..7a00c35
--- /dev/null
+++ b/buffet/dbus_conversion_unittest.cc
@@ -0,0 +1,188 @@
+// Copyright 2015 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.
+
+#include "buffet/dbus_conversion.h"
+
+#include <limits>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/guid.h>
+#include <base/rand_util.h>
+#include <base/values.h>
+#include <chromeos/variant_dictionary.h>
+#include <gtest/gtest.h>
+
+#include "weave/unittest_utils.h"
+
+namespace buffet {
+
+namespace {
+
+using chromeos::Any;
+using chromeos::VariantDictionary;
+using weave::unittests::CreateDictionaryValue;
+using weave::unittests::IsEqualValue;
+
+chromeos::VariantDictionary ToDBus(const base::DictionaryValue& object) {
+  return DictionaryToDBusVariantDictionary(object);
+}
+
+std::unique_ptr<base::DictionaryValue> FromDBus(
+    const chromeos::VariantDictionary& object) {
+  chromeos::ErrorPtr error;
+  auto result = DictionaryFromDBusVariantDictionary(object, &error);
+  EXPECT_TRUE(result || error);
+  return result;
+}
+
+std::unique_ptr<base::Value> CreateRandomValue(int children);
+std::unique_ptr<base::Value> CreateRandomValue(int children,
+                                               base::Value::Type type);
+
+const base::Value::Type kRandomTypes[] = {
+    base::Value::TYPE_BOOLEAN,    base::Value::TYPE_INTEGER,
+    base::Value::TYPE_DOUBLE,     base::Value::TYPE_STRING,
+    base::Value::TYPE_DICTIONARY, base::Value::TYPE_LIST,
+};
+
+const base::Value::Type kRandomTypesWithChildren[] = {
+    base::Value::TYPE_DICTIONARY, base::Value::TYPE_LIST,
+};
+
+base::Value::Type CreateRandomValueType(bool with_children) {
+  if (with_children) {
+    return kRandomTypesWithChildren[base::RandInt(
+        0, arraysize(kRandomTypesWithChildren) - 1)];
+  }
+  return kRandomTypes[base::RandInt(0, arraysize(kRandomTypes) - 1)];
+}
+
+std::unique_ptr<base::DictionaryValue> CreateRandomDictionary(int children) {
+  std::unique_ptr<base::DictionaryValue> result{new base::DictionaryValue};
+
+  while (children > 0) {
+    int sub_children = base::RandInt(1, children);
+    children -= sub_children;
+    result->Set(base::GenerateGUID(),
+                CreateRandomValue(sub_children).release());
+  }
+
+  return result;
+}
+
+std::unique_ptr<base::ListValue> CreateRandomList(int children) {
+  std::unique_ptr<base::ListValue> result{new base::ListValue};
+
+  base::Value::Type type = CreateRandomValueType(children > 0);
+  while (children > 0) {
+    size_t max_children =
+        (type != base::Value::TYPE_DICTIONARY && type != base::Value::TYPE_LIST)
+            ? 1
+            : children;
+    size_t sub_children = base::RandInt(1, max_children);
+    children -= sub_children;
+    result->Append(CreateRandomValue(sub_children, type).release());
+  }
+
+  return result;
+}
+
+std::unique_ptr<base::Value> CreateRandomValue(int children,
+                                               base::Value::Type type) {
+  CHECK_GE(children, 1);
+  switch (type) {
+    case base::Value::TYPE_INTEGER:
+      return std::unique_ptr<base::Value>{new base::FundamentalValue{
+          base::RandInt(std::numeric_limits<int>::min(),
+                        std::numeric_limits<int>::max())}};
+    case base::Value::TYPE_DOUBLE:
+      return std::unique_ptr<base::Value>{
+          new base::FundamentalValue{base::RandDouble()}};
+    case base::Value::TYPE_STRING:
+      return std::unique_ptr<base::Value>{
+          new base::StringValue{base::GenerateGUID()}};
+    case base::Value::TYPE_DICTIONARY:
+      CHECK_GE(children, 1);
+      return CreateRandomDictionary(children - 1);
+    case base::Value::TYPE_LIST:
+      CHECK_GE(children, 1);
+      return CreateRandomList(children - 1);
+    default:
+      return std::unique_ptr<base::Value>{
+          new base::FundamentalValue{base::RandInt(0, 1) != 0}};
+  }
+}
+
+std::unique_ptr<base::Value> CreateRandomValue(int children) {
+  return CreateRandomValue(children, CreateRandomValueType(children > 0));
+}
+
+}  // namespace
+
+TEST(DBusConversionTest, DictionaryToDBusVariantDictionary) {
+  EXPECT_EQ((VariantDictionary{{"bool", true}}),
+            ToDBus(*CreateDictionaryValue("{'bool': true}")));
+  EXPECT_EQ((VariantDictionary{{"int", 5}}),
+            ToDBus(*CreateDictionaryValue("{'int': 5}")));
+  EXPECT_EQ((VariantDictionary{{"double", 6.7}}),
+            ToDBus(*CreateDictionaryValue("{'double': 6.7}")));
+  EXPECT_EQ((VariantDictionary{{"string", std::string{"abc"}}}),
+            ToDBus(*CreateDictionaryValue("{'string': 'abc'}")));
+  EXPECT_EQ((VariantDictionary{{"object", VariantDictionary{{"bool", true}}}}),
+            ToDBus(*CreateDictionaryValue("{'object': {'bool': true}}")));
+  EXPECT_EQ((VariantDictionary{{"emptyList", std::vector<Any>{}}}),
+            ToDBus(*CreateDictionaryValue("{'emptyList': []}")));
+  EXPECT_EQ((VariantDictionary{{"intList", std::vector<int>{5}}}),
+            ToDBus(*CreateDictionaryValue("{'intList': [5]}")));
+  EXPECT_EQ((VariantDictionary{
+                {"intListList", std::vector<Any>{std::vector<int>{5},
+                                                 std::vector<int>{6, 7}}}}),
+            ToDBus(*CreateDictionaryValue("{'intListList': [[5], [6, 7]]}")));
+  EXPECT_EQ((VariantDictionary{{"objList",
+                                std::vector<VariantDictionary>{
+                                    {{"string", std::string{"abc"}}}}}}),
+            ToDBus(*CreateDictionaryValue("{'objList': [{'string': 'abc'}]}")));
+}
+
+TEST(DBusConversionTest, DictionaryFromDBusVariantDictionary) {
+  EXPECT_JSON_EQ("{'bool': true}", *FromDBus({{"bool", true}}));
+  EXPECT_JSON_EQ("{'int': 5}", *FromDBus({{"int", 5}}));
+  EXPECT_JSON_EQ("{'double': 6.7}", *FromDBus({{"double", 6.7}}));
+  EXPECT_JSON_EQ("{'string': 'abc'}",
+                 *FromDBus({{"string", std::string{"abc"}}}));
+  EXPECT_JSON_EQ("{'object': {'bool': true}}",
+                 *FromDBus({{"object", VariantDictionary{{"bool", true}}}}));
+  EXPECT_JSON_EQ("{'emptyList': []}",
+                 *FromDBus({{"emptyList", std::vector<bool>{}}}));
+  EXPECT_JSON_EQ("{'intList': [5]}",
+                 *FromDBus({{"intList", std::vector<int>{5}}}));
+  EXPECT_JSON_EQ(
+      "{'intListList': [[5], [6, 7]]}",
+      *FromDBus({{"intListList", std::vector<Any>{std::vector<int>{5},
+                                                  std::vector<int>{6, 7}}}}));
+  EXPECT_JSON_EQ(
+      "{'objList': [{'string': 'abc'}]}",
+      *FromDBus({{"objList", std::vector<VariantDictionary>{
+                                 {{"string", std::string{"abc"}}}}}}));
+  EXPECT_JSON_EQ("{'int': 5}", *FromDBus({{"int", Any{Any{5}}}}));
+}
+
+TEST(DBusConversionTest, DictionaryFromDBusVariantDictionary_Errors) {
+  EXPECT_FALSE(FromDBus({{"cString", "abc"}}));
+  EXPECT_FALSE(FromDBus({{"float", 1.0f}}));
+  EXPECT_FALSE(FromDBus({{"listList", std::vector<std::vector<int>>{}}}));
+  EXPECT_FALSE(FromDBus({{"any", Any{}}}));
+  EXPECT_FALSE(FromDBus({{"null", nullptr}}));
+}
+
+TEST(DBusConversionTest, DBusRandomDictionaryConversion) {
+  auto dict = CreateRandomDictionary(10000);
+  auto varian_dict = ToDBus(*dict);
+  auto dict_restored = FromDBus(varian_dict);
+  EXPECT_PRED2(IsEqualValue, *dict, *dict_restored);
+}
+
+}  // namespace buffet
diff --git a/buffet/manager.cc b/buffet/manager.cc
index 0b64d5b..85c61c1 100644
--- a/buffet/manager.cc
+++ b/buffet/manager.cc
@@ -23,9 +23,8 @@
 #include <dbus/object_path.h>
 #include <dbus/values_util.h>
 
-// TODO(vitalybuka): Will be moved into buffet soon.
-#include "libweave/src/commands/dbus_command_dispatcher.h"
-#include "libweave/src/commands/dbus_conversion.h"
+#include "buffet/dbus_command_dispatcher.h"
+#include "buffet/dbus_conversion.h"
 #include "weave/enum_to_string.h"
 
 using chromeos::dbus_utils::AsyncEventSequencer;
@@ -58,7 +57,7 @@
   device_ = weave::Device::Create();
   device_->Start(options, &dbus_object_, sequencer);
 
-  command_dispatcher_.reset(new weave::DBusCommandDispacher{
+  command_dispatcher_.reset(new DBusCommandDispacher{
       dbus_object_.GetObjectManager(), device_->GetCommands()});
 
   device_->GetState()->AddOnChangedCallback(
@@ -143,8 +142,7 @@
 void Manager::UpdateState(DBusMethodResponsePtr<> response,
                           const chromeos::VariantDictionary& property_set) {
   chromeos::ErrorPtr error;
-  auto properties =
-      weave::DictionaryFromDBusVariantDictionary(property_set, &error);
+  auto properties = DictionaryFromDBusVariantDictionary(property_set, &error);
   if (!properties)
     response->ReplyWithError(error.get());
 
diff --git a/buffet/manager.h b/buffet/manager.h
index ef433e2..9dc84d8 100644
--- a/buffet/manager.h
+++ b/buffet/manager.h
@@ -22,10 +22,6 @@
 #include "buffet/org.chromium.Buffet.Manager.h"
 #include "weave/device.h"
 
-namespace weave {
-class DBusCommandDispacher;
-}
-
 namespace chromeos {
 namespace dbus_utils {
 class ExportedObjectManager;
@@ -34,6 +30,8 @@
 
 namespace buffet {
 
+class DBusCommandDispacher;
+
 template<typename... Types>
 using DBusMethodResponsePtr =
     std::unique_ptr<chromeos::dbus_utils::DBusMethodResponse<Types...>>;
@@ -117,7 +115,7 @@
   chromeos::dbus_utils::DBusObject dbus_object_;
 
   std::unique_ptr<weave::Device> device_;
-  std::unique_ptr<weave::DBusCommandDispacher> command_dispatcher_;
+  std::unique_ptr<DBusCommandDispacher> command_dispatcher_;
 
   base::WeakPtrFactory<Manager> weak_ptr_factory_{this};
   DISALLOW_COPY_AND_ASSIGN(Manager);