buffet: Add DBusCommandDispacher and hook it up to CommandQueue

Added DBusCommandDispacher class that maintains DBusCommandProxy object
for each instance of CommandInstance class added to the CommandQueue.

As soon as a command instance is removed from the queue, D-Bus command
dispatcher removes the corresponding command proxy object from D-Bus.

BUG=chromium:374864
TEST=FEATURES=test emerge-link buffet

Change-Id: Ib7ce7370bd3ee471e22f02b8546675021ff063d7
Reviewed-on: https://chromium-review.googlesource.com/211642
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/commands/dbus_command_dispatcher.h b/buffet/commands/dbus_command_dispatcher.h
new file mode 100644
index 0000000..94f938b
--- /dev/null
+++ b/buffet/commands/dbus_command_dispatcher.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_COMMANDS_DBUS_COMMAND_DISPATCHER_H_
+#define BUFFET_COMMANDS_DBUS_COMMAND_DISPATCHER_H_
+
+#include <map>
+#include <string>
+
+#include <base/macros.h>
+#include <base/memory/weak_ptr.h>
+#include <dbus/bus.h>
+
+#include "buffet/commands/command_dispatch_interface.h"
+#include "buffet/commands/dbus_command_proxy.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 over
+// CommandDispachInterface, 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 : public CommandDispachInterface {
+ public:
+  DBusCommandDispacher(
+      const scoped_refptr<dbus::Bus>& bus,
+      chromeos::dbus_utils::ExportedObjectManager* object_manager = nullptr);
+  virtual ~DBusCommandDispacher() = default;
+
+  // CommandDispachInterface overrides. Called by CommandQueue.
+  void OnCommandAdded(CommandInstance* command_instance) override;
+  void OnCommandRemoved(CommandInstance* command_instance) override;
+
+  // Finds a D-Bus command proxy for the given command instance.
+  // Returns nullptr if the proxy does not exist.
+  DBusCommandProxy* FindProxy(CommandInstance* command_instance) const;
+
+ protected:
+  virtual std::unique_ptr<DBusCommandProxy> CreateDBusCommandProxy(
+      CommandInstance* command_instance) const;
+
+ private:
+  scoped_refptr<dbus::Bus> bus_;
+  base::WeakPtr<chromeos::dbus_utils::ExportedObjectManager> object_manager_;
+  // This is the map that tracks relationship between CommandInstance and
+  // corresponding DBusCommandProxy objects.
+  std::map<CommandInstance*, std::unique_ptr<DBusCommandProxy>> command_map_;
+
+  // Default constructor is used in special circumstances such as for testing.
+  DBusCommandDispacher() = default;
+
+  friend class DBusCommandDispacherTest;
+  friend class CommandManager;
+  DISALLOW_COPY_AND_ASSIGN(DBusCommandDispacher);
+};
+
+}  // namespace buffet
+
+#endif  // BUFFET_COMMANDS_DBUS_COMMAND_DISPATCHER_H_