AU: Set error code bit 30 for error events on resumed updates.

BUG=chromium-os:16006
TEST=unit tests, tested on device

Change-Id: I94938529aa2cf2d85396a632d03624c71528b7f9
Reviewed-on: http://gerrit.chromium.org/gerrit/2786
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Andrew de los Reyes <adlr@chromium.org>
diff --git a/action_processor.h b/action_processor.h
index 2ed5f78..57b1d37 100644
--- a/action_processor.h
+++ b/action_processor.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2011 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.
 
@@ -51,6 +51,7 @@
   kActionCodeOmahaRequestHTTPResponseBase = 2000,  // + HTTP response code
 
   // Bit flags.
+  kActionCodeResumedFlag = 1 << 30,  // Set if resuming an interruped update.
   kActionCodeBootModeFlag = 1 << 31,  // Set if boot mode not normal.
 };
 
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index c64e01a..78af1c0 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -128,11 +128,7 @@
     // is not success.
     string error_code;
     if (event->result != OmahaEvent::kResultSuccess) {
-      int code = event->error_code;
-      if (!utils::IsNormalBootMode()) {
-        code |= kActionCodeBootModeFlag;
-      }
-      error_code = StringPrintf(" errorcode=\"%d\"", code);
+      error_code = StringPrintf(" errorcode=\"%d\"", event->error_code);
     }
     body = StringPrintf(
         "        <o:event eventtype=\"%d\" eventresult=\"%d\"%s></o:event>\n",
diff --git a/omaha_response_handler_action.h b/omaha_response_handler_action.h
index 1785138..d9bf01f 100644
--- a/omaha_response_handler_action.h
+++ b/omaha_response_handler_action.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2011 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.
 
@@ -6,6 +6,9 @@
 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_OMAHA_RESPONSE_HANDLER_ACTION_H__
 
 #include <string>
+
+#include <gtest/gtest_prod.h>  // for FRIEND_TEST
+
 #include "update_engine/action.h"
 #include "update_engine/install_plan.h"
 #include "update_engine/omaha_request_action.h"
@@ -54,6 +57,8 @@
   void set_key_path(const std::string& path) { key_path_ = path; }
 
  private:
+  FRIEND_TEST(UpdateAttempterTest, CreatePendingErrorEventResumedTest);
+
   // Assumes you want to install on the "other" device, where the other
   // device is what you get if you swap 1 for 2 or 3 for 4 or vice versa
   // for the number at the end of the boot device. E.g., /dev/sda1 -> /dev/sda2
diff --git a/update_attempter.cc b/update_attempter.cc
index f29b3d7..3206067 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -553,6 +553,15 @@
 
   code = GetErrorCodeForAction(action, code);
   fake_update_success_ = code == kActionCodePostinstallBootedFromFirmwareB;
+
+  // Apply the bit modifiers to the error code.
+  if (!utils::IsNormalBootMode()) {
+    code = static_cast<ActionExitCode>(code | kActionCodeBootModeFlag);
+  }
+  if (response_handler_action_.get() &&
+      response_handler_action_->install_plan().is_resume) {
+    code = static_cast<ActionExitCode>(code | kActionCodeResumedFlag);
+  }
   error_event_.reset(new OmahaEvent(OmahaEvent::kTypeUpdateComplete,
                                     OmahaEvent::kResultError,
                                     code));
diff --git a/update_attempter.h b/update_attempter.h
index 33e97c5..726685e 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -136,12 +136,14 @@
   FRIEND_TEST(UpdateAttempterTest, ActionCompletedDownloadTest);
   FRIEND_TEST(UpdateAttempterTest, ActionCompletedErrorTest);
   FRIEND_TEST(UpdateAttempterTest, ActionCompletedOmahaRequestTest);
+  FRIEND_TEST(UpdateAttempterTest, CreatePendingErrorEventTest);
+  FRIEND_TEST(UpdateAttempterTest, CreatePendingErrorEventResumedTest);
   FRIEND_TEST(UpdateAttempterTest, DisableDeltaUpdateIfNeededTest);
   FRIEND_TEST(UpdateAttempterTest, MarkDeltaUpdateFailureTest);
+  FRIEND_TEST(UpdateAttempterTest, PingOmahaTest);
   FRIEND_TEST(UpdateAttempterTest, ScheduleErrorEventActionNoEventTest);
   FRIEND_TEST(UpdateAttempterTest, ScheduleErrorEventActionTest);
   FRIEND_TEST(UpdateAttempterTest, UpdateTest);
-  FRIEND_TEST(UpdateAttempterTest, PingOmahaTest);
 
   // Sets the status to the given status and notifies a status update
   // over dbus.
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index 4059957..b61377b 100644
--- a/update_attempter_unittest.cc
+++ b/update_attempter_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2011 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.
 
@@ -341,4 +341,29 @@
   EXPECT_EQ(true, scheduler.scheduled_);
 }
 
+TEST_F(UpdateAttempterTest, CreatePendingErrorEventTest) {
+  ActionMock action;
+  const ActionExitCode kCode = kActionCodeDownloadTransferError;
+  attempter_.CreatePendingErrorEvent(&action, kCode);
+  ASSERT_TRUE(attempter_.error_event_.get() != NULL);
+  EXPECT_EQ(OmahaEvent::kTypeUpdateComplete, attempter_.error_event_->type);
+  EXPECT_EQ(OmahaEvent::kResultError, attempter_.error_event_->result);
+  EXPECT_EQ(kCode, attempter_.error_event_->error_code);
+}
+
+TEST_F(UpdateAttempterTest, CreatePendingErrorEventResumedTest) {
+  OmahaResponseHandlerAction *response_action =
+      new OmahaResponseHandlerAction(&prefs_);
+  response_action->install_plan_.is_resume = true;
+  attempter_.response_handler_action_.reset(response_action);
+  ActionMock action;
+  const ActionExitCode kCode = kActionCodeInstallDeviceOpenError;
+  attempter_.CreatePendingErrorEvent(&action, kCode);
+  ASSERT_TRUE(attempter_.error_event_.get() != NULL);
+  EXPECT_EQ(OmahaEvent::kTypeUpdateComplete, attempter_.error_event_->type);
+  EXPECT_EQ(OmahaEvent::kResultError, attempter_.error_event_->result);
+  EXPECT_EQ(kCode | kActionCodeResumedFlag,
+            attempter_.error_event_->error_code);
+}
+
 }  // namespace chromeos_update_engine