update_engine: added CanRollback dbus method

Added a method to the update engine to check if a rollback
partition is available and can be booted from.
update_engine_client is also updated to call the function
when --can_rollback paramater is specified

BUG=chromium:343301
TEST=Ran "update_engine_client --can_rollback" and unit tests

Change-Id: If3fcb29a0067069a22812f60e9b67c6fdbbd18bd
Reviewed-on: https://chromium-review.googlesource.com/187157
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Don Garrett <dgarrett@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/update_attempter.cc b/update_attempter.cc
index 7b34cee..dcde2cf 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <tr1/memory>
 #include <vector>
+#include <algorithm>
 
 #include <base/file_util.h>
 #include <base/logging.h>
@@ -788,6 +789,35 @@
   return true;
 }
 
+bool UpdateAttempter::CanRollback() const {
+  std::vector<std::string> kernel_devices =
+      system_state_->hardware()->GetKernelDevices();
+
+  std::string boot_kernel_device =
+      system_state_->hardware()->BootKernelDevice();
+
+  auto current = std::find(kernel_devices.begin(), kernel_devices.end(),
+                           boot_kernel_device);
+
+  if(current == kernel_devices.end()) {
+    LOG(ERROR) << "Unable to find the boot kernel device in the list of "
+               << "available devices";
+    return false;
+  }
+
+  for (std::string const& device_name : kernel_devices) {
+    if (device_name != *current) {
+      bool bootable = false;
+      if (system_state_->hardware()->IsKernelBootable(device_name, &bootable) &&
+          bootable) {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
 void UpdateAttempter::CheckForUpdate(const string& app_version,
                                      const string& omaha_url,
                                      bool interactive) {