For actions, switch bool success into an exit code.

This way we can signal specific error conditions and then
send appropriate events to Omaha from the UpdateAttempter.

BUG=560
TEST=unit tests, gmerged and looked at logs

Review URL: http://codereview.chromium.org/3022008
diff --git a/action_processor.cc b/action_processor.cc
index e52cbcd..0d8c046 100644
--- a/action_processor.cc
+++ b/action_processor.cc
@@ -54,17 +54,17 @@
 }
 
 void ActionProcessor::ActionComplete(AbstractAction* actionptr,
-                                     bool success) {
+                                     ActionExitCode code) {
   CHECK_EQ(actionptr, current_action_);
   if (delegate_)
-    delegate_->ActionCompleted(this, actionptr, success);
+    delegate_->ActionCompleted(this, actionptr, code);
   string old_type = current_action_->Type();
   current_action_->SetProcessor(NULL);
   current_action_ = NULL;
   if (actions_.empty()) {
     LOG(INFO) << "ActionProcessor::ActionComplete: finished last action of"
                  " type " << old_type;
-  } else if (!success) {
+  } else if (code != kActionCodeSuccess) {
     LOG(INFO) << "ActionProcessor::ActionComplete: " << old_type
               << " action failed. Aborting processing.";
     actions_.clear();
@@ -73,7 +73,7 @@
     LOG(INFO) << "ActionProcessor::ActionComplete: finished last action of"
                  " type " << old_type;
     if (delegate_) {
-      delegate_->ProcessingDone(this, success);
+      delegate_->ProcessingDone(this, code);
     }
     return;
   }
diff --git a/action_processor.h b/action_processor.h
index 8311b8a..f04345d 100644
--- a/action_processor.h
+++ b/action_processor.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2010 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.
 
@@ -21,6 +21,12 @@
 
 namespace chromeos_update_engine {
 
+// Action exit codes.
+enum ActionExitCode {
+  kActionCodeSuccess = 0,
+  kActionCodeError = 1,
+};
+
 class AbstractAction;
 class ActionProcessorDelegate;
 
@@ -57,7 +63,7 @@
   }
 
   // Called by an action to notify processor that it's done. Caller passes self.
-  void ActionComplete(AbstractAction* actionptr, bool success);
+  void ActionComplete(AbstractAction* actionptr, ActionExitCode code);
 
  private:
   // Actions that have not yet begun processing, in the order in which
@@ -78,9 +84,10 @@
 class ActionProcessorDelegate {
  public:
   // Called when all processing in an ActionProcessor has completed. A pointer
-  // to the ActionProcessor is passed. success is true iff all actions
-  // completed successfully
-  virtual void ProcessingDone(const ActionProcessor* processor, bool success) {}
+  // to the ActionProcessor is passed. |code| is set to the exit code of the
+  // last completed action.
+  virtual void ProcessingDone(const ActionProcessor* processor,
+                              ActionExitCode code) {}
 
   // Called when processing has stopped. Does not mean that all Actions have
   // completed. If/when all Actions complete, ProcessingDone() will be called.
@@ -90,7 +97,7 @@
   // or otherwise.
   virtual void ActionCompleted(ActionProcessor* processor,
                                AbstractAction* action,
-                               bool success) {}
+                               ActionExitCode code) {}
 };
 
 }  // namespace chromeos_update_engine
diff --git a/action_processor_unittest.cc b/action_processor_unittest.cc
index 40275a0..7f39149 100644
--- a/action_processor_unittest.cc
+++ b/action_processor_unittest.cc
@@ -32,7 +32,7 @@
   void PerformAction() {}
   void CompleteAction() {
     ASSERT_TRUE(processor());
-    processor()->ActionComplete(this, true);
+    processor()->ActionComplete(this, kActionCodeSuccess);
   }
   string Type() const { return "ActionProcessorTestAction"; }
 };
@@ -65,9 +65,10 @@
         processing_done_called_(false),
         processing_stopped_called_(false),
         action_completed_called_(false),
-        action_completed_success_(false) {}
+        action_exit_code_(kActionCodeError) {}
 
-  virtual void ProcessingDone(const ActionProcessor* processor, bool success) {
+  virtual void ProcessingDone(const ActionProcessor* processor,
+                              ActionExitCode code) {
     EXPECT_EQ(processor_, processor);
     EXPECT_FALSE(processing_done_called_);
     processing_done_called_ = true;
@@ -79,18 +80,18 @@
   }
   virtual void ActionCompleted(ActionProcessor* processor,
                                AbstractAction* action,
-                               bool success) {
+                               ActionExitCode code) {
     EXPECT_EQ(processor_, processor);
     EXPECT_FALSE(action_completed_called_);
     action_completed_called_ = true;
-    action_completed_success_ = success;
+    action_exit_code_ = code;
   }
 
   const ActionProcessor* processor_;
   bool processing_done_called_;
   bool processing_stopped_called_;
   bool action_completed_called_;
-  bool action_completed_success_;
+  ActionExitCode action_exit_code_;
 };
 }  // namespace {}
 
diff --git a/action_unittest.cc b/action_unittest.cc
index 8dd9edd..8bb94ca 100644
--- a/action_unittest.cc
+++ b/action_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2010 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.
 
@@ -32,7 +32,7 @@
   void PerformAction() {}
   void CompleteAction() {
     ASSERT_TRUE(processor());
-    processor()->ActionComplete(this, true);
+    processor()->ActionComplete(this, kActionCodeSuccess);
   }
   string Type() const { return "ActionTestAction"; }
 };
diff --git a/download_action.cc b/download_action.cc
index 4787ee2..9be81f0 100644
--- a/download_action.cc
+++ b/download_action.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2010 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.
 
@@ -61,7 +61,7 @@
   if (rc < 0) {
     LOG(ERROR) << "Unable to open output file " << install_plan_.install_path;
     // report error to processor
-    processor_->ActionComplete(this, false);
+    processor_->ActionComplete(this, kActionCodeError);
     return;
   }
   if (!install_plan_.is_full_update) {
@@ -70,7 +70,7 @@
       LOG(ERROR) << "Unable to open kernel file "
                  << install_plan_.kernel_install_path.c_str();
       writer_->Close();
-      processor_->ActionComplete(this, false);
+      processor_->ActionComplete(this, kActionCodeError);
       return;
     }
   }
@@ -126,13 +126,15 @@
       successful = false;
     }
   }
-  
+
   FlushLinuxCaches();
 
   // Write the path to the output pipe if we're successful
   if (successful && HasOutputPipe())
     SetOutputObject(GetInputObject());
-  processor_->ActionComplete(this, successful);
+  processor_->ActionComplete(
+      this,
+      successful ? kActionCodeSuccess : kActionCodeError);
 }
 
 };  // namespace {}
diff --git a/download_action_unittest.cc b/download_action_unittest.cc
index 3b04eae..104107f 100644
--- a/download_action_unittest.cc
+++ b/download_action_unittest.cc
@@ -28,7 +28,8 @@
   virtual ~DownloadActionTestProcessorDelegate() {
     EXPECT_TRUE(processing_done_called_);
   }
-  virtual void ProcessingDone(const ActionProcessor* processor, bool success) {
+  virtual void ProcessingDone(const ActionProcessor* processor,
+                              ActionExitCode code) {
     ASSERT_TRUE(loop_);
     g_main_loop_quit(loop_);
     vector<char> found_data;
@@ -42,9 +43,9 @@
 
   virtual void ActionCompleted(ActionProcessor* processor,
                                AbstractAction* action,
-                               bool success) {
+                               ActionExitCode code) {
     // make sure actions always succeed
-    EXPECT_TRUE(success);
+    EXPECT_EQ(kActionCodeSuccess, code);
   }
 
   GMainLoop *loop_;
@@ -199,7 +200,7 @@
     ASSERT_TRUE(HasInputObject());
     EXPECT_TRUE(expected_input_object_ == GetInputObject());
     ASSERT_TRUE(processor());
-    processor()->ActionComplete(this, true);
+    processor()->ActionComplete(this, kActionCodeSuccess);
   }
   string Type() const { return "DownloadActionTestAction"; }
   InstallPlan expected_input_object_;
@@ -212,7 +213,7 @@
 // only by the test PassObjectOutTest.
 class PassObjectOutTestProcessorDelegate : public ActionProcessorDelegate {
  public:
-  void ProcessingDone(const ActionProcessor* processor, bool success) {
+  void ProcessingDone(const ActionProcessor* processor, ActionExitCode code) {
     ASSERT_TRUE(loop_);
     g_main_loop_quit(loop_);
   }
@@ -275,7 +276,7 @@
   feeder_action.set_obj(install_plan);
   DownloadAction download_action(new MockHttpFetcher("x", 1));
   download_action.SetTestFileWriter(&writer);
-  
+
   BondActions(&feeder_action, &download_action);
 
   ActionProcessor processor;
diff --git a/filesystem_copier_action.cc b/filesystem_copier_action.cc
index 6d7cd22..388e0e7 100755
--- a/filesystem_copier_action.cc
+++ b/filesystem_copier_action.cc
@@ -45,7 +45,7 @@
     // No copy needed. Done!
     if (HasOutputPipe())
       SetOutputObject(install_plan_);
-    abort_action_completer.set_success(true);
+    abort_action_completer.set_code(kActionCodeSuccess);
     return;
   }
 
@@ -59,7 +59,7 @@
   const string destination = copying_kernel_install_path_ ?
       install_plan_.kernel_install_path :
       install_plan_.install_path;
-  
+
   int src_fd = open(source.c_str(), O_RDONLY);
   if (src_fd < 0) {
     PLOG(ERROR) << "Unable to open " << source << " for reading:";
@@ -110,7 +110,9 @@
     return;
   if (success && HasOutputPipe())
     SetOutputObject(install_plan_);
-  processor_->ActionComplete(this, success);
+  processor_->ActionComplete(
+      this,
+      success ? kActionCodeSuccess : kActionCodeError);
 }
 
 void FilesystemCopierAction::AsyncReadyCallback(GObject *source_object,
diff --git a/filesystem_copier_action_unittest.cc b/filesystem_copier_action_unittest.cc
index e2bd42b..03aa86a 100644
--- a/filesystem_copier_action_unittest.cc
+++ b/filesystem_copier_action_unittest.cc
@@ -33,14 +33,14 @@
 
 class FilesystemCopierActionTestDelegate : public ActionProcessorDelegate {
  public:
-  FilesystemCopierActionTestDelegate() : ran_(false), success_(false) {}
+  FilesystemCopierActionTestDelegate() : ran_(false), code_(kActionCodeError) {}
   void ExitMainLoop() {
     while (g_main_context_pending(NULL)) {
       g_main_context_iteration(NULL, false);
     }
     g_main_loop_quit(loop_);
   }
-  void ProcessingDone(const ActionProcessor* processor, bool success) {
+  void ProcessingDone(const ActionProcessor* processor, ActionExitCode code) {
     ExitMainLoop();
   }
   void ProcessingStopped(const ActionProcessor* processor) {
@@ -48,21 +48,21 @@
   }
   void ActionCompleted(ActionProcessor* processor,
                        AbstractAction* action,
-                       bool success) {
+                       ActionExitCode code) {
     if (action->Type() == FilesystemCopierAction::StaticType()) {
       ran_ = true;
-      success_ = success;
+      code_ = code;
     }
   }
   void set_loop(GMainLoop* loop) {
     loop_ = loop;
   }
   bool ran() { return ran_; }
-  bool success() { return success_; }
+  ActionExitCode code() { return code_; }
  private:
   GMainLoop* loop_;
   bool ran_;
-  bool success_;
+  ActionExitCode code_;
 };
 
 struct StartProcessorCallbackArgs {
@@ -96,7 +96,7 @@
 
   string a_loop_file;
   string b_loop_file;
-  
+
   EXPECT_TRUE(utils::MakeTempFile("/tmp/a_loop_file.XXXXXX",
                                   &a_loop_file,
                                   NULL));
@@ -105,7 +105,7 @@
                                   &b_loop_file,
                                   NULL));
   ScopedPathUnlinker b_loop_file_unlinker(b_loop_file);
-  
+
   // Make random data for a, zero filled data for b.
   const size_t kLoopFileSize = 10 * 1024 * 1024 + 512;
   vector<char> a_loop_data(kLoopFileSize);
@@ -173,10 +173,10 @@
   if (!terminate_early)
     EXPECT_TRUE(delegate.ran());
   if (run_out_of_space || terminate_early) {
-    EXPECT_FALSE(delegate.success());
+    EXPECT_EQ(kActionCodeError, delegate.code());
     return;
   }
-  EXPECT_TRUE(delegate.success());
+  EXPECT_EQ(kActionCodeSuccess, delegate.code());
 
   // Make sure everything in the out_image is there
   vector<char> a_out;
@@ -193,15 +193,15 @@
  public:
   void ActionCompleted(ActionProcessor* processor,
                        AbstractAction* action,
-                       bool success) {
+                       ActionExitCode code) {
     if (action->Type() == FilesystemCopierAction::StaticType()) {
       ran_ = true;
-      success_ = success;
+      code_ = code;
     }
   }
   GMainLoop *loop_;
   bool ran_;
-  bool success_;
+  ActionExitCode code_;
 };
 
 TEST_F(FilesystemCopierActionTest, MissingInputObjectTest) {
@@ -220,7 +220,7 @@
   processor.StartProcessing();
   EXPECT_FALSE(processor.IsRunning());
   EXPECT_TRUE(delegate.ran_);
-  EXPECT_FALSE(delegate.success_);
+  EXPECT_EQ(kActionCodeError, delegate.code_);
 }
 
 TEST_F(FilesystemCopierActionTest, FullUpdateTest) {
@@ -245,7 +245,7 @@
   processor.StartProcessing();
   EXPECT_FALSE(processor.IsRunning());
   EXPECT_TRUE(delegate.ran_);
-  EXPECT_TRUE(delegate.success_);
+  EXPECT_EQ(kActionCodeSuccess, delegate.code_);
   EXPECT_EQ(kUrl, collector_action.object().download_url);
 }
 
@@ -269,7 +269,7 @@
   processor.StartProcessing();
   EXPECT_FALSE(processor.IsRunning());
   EXPECT_TRUE(delegate.ran_);
-  EXPECT_FALSE(delegate.success_);
+  EXPECT_EQ(kActionCodeError, delegate.code_);
 }
 
 TEST_F(FilesystemCopierActionTest, RunAsRootNoSpaceTest) {
diff --git a/integration_unittest.cc b/integration_unittest.cc
index 8a0ac61..c20d810 100644
--- a/integration_unittest.cc
+++ b/integration_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2010 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.
 
@@ -40,16 +40,17 @@
   virtual ~IntegrationTestProcessorDelegate() {
     EXPECT_TRUE(processing_done_called_);
   }
-  virtual void ProcessingDone(const ActionProcessor* processor, bool success) {
+  virtual void ProcessingDone(const ActionProcessor* processor,
+                              ActionExitCode code) {
     processing_done_called_ = true;
     g_main_loop_quit(loop_);
   }
 
   virtual void ActionCompleted(ActionProcessor* processor,
                                AbstractAction* action,
-                               bool success) {
+                               ActionExitCode code) {
     // make sure actions always succeed
-    EXPECT_TRUE(success);
+    EXPECT_EQ(kActionCodeSuccess, code);
 
     // Swap in the device path for PostinstallRunnerAction with a loop device
     if (action->Type() == InstallAction::StaticType()) {
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 6f9a790..e801f40 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -215,7 +215,7 @@
   // Events are best effort transactions -- assume they always succeed.
   if (IsEvent()) {
     CHECK(!HasOutputPipe()) << "No output pipe allowed for event requests.";
-    completer.set_success(true);
+    completer.set_code(kActionCodeSuccess);
     return;
   }
 
@@ -226,7 +226,7 @@
   if (!HasOutputPipe()) {
     // Just set success to whether or not the http transfer succeeded,
     // which must be true at this point in the code.
-    completer.set_success(true);
+    completer.set_code(kActionCodeSuccess);
     return;
   }
 
@@ -267,7 +267,7 @@
     LOG(INFO) << "No update.";
     output_object.update_exists = false;
     SetOutputObject(output_object);
-    completer.set_success(true);
+    completer.set_code(kActionCodeSuccess);
     return;
   }
 
@@ -279,7 +279,7 @@
   // In best-effort fashion, fetch the rest of the expected attributes
   // from the updatecheck node, then return the object
   output_object.update_exists = true;
-  completer.set_success(true);
+  completer.set_code(kActionCodeSuccess);
 
   output_object.display_version =
       XmlGetProperty(updatecheck_node, "DisplayVersion");
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index dedb972..05ec1b8 100755
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -56,25 +56,26 @@
  public:
   OmahaRequestActionTestProcessorDelegate()
       : loop_(NULL),
-        expected_success_(true) {}
+        expected_code_(kActionCodeSuccess) {}
   virtual ~OmahaRequestActionTestProcessorDelegate() {
   }
-  virtual void ProcessingDone(const ActionProcessor* processor, bool success) {
+  virtual void ProcessingDone(const ActionProcessor* processor,
+                              ActionExitCode code) {
     ASSERT_TRUE(loop_);
     g_main_loop_quit(loop_);
   }
 
   virtual void ActionCompleted(ActionProcessor* processor,
                                AbstractAction* action,
-                               bool success) {
+                               ActionExitCode code) {
     // make sure actions always succeed
     if (action->Type() == OmahaRequestAction::StaticType())
-      EXPECT_EQ(expected_success_, success);
+      EXPECT_EQ(expected_code_, code);
     else
-      EXPECT_TRUE(success);
+      EXPECT_EQ(kActionCodeSuccess, code);
   }
   GMainLoop *loop_;
-  bool expected_success_;
+  ActionExitCode expected_code_;
 };
 
 gboolean StartProcessorInRunLoop(gpointer data) {
@@ -104,7 +105,7 @@
     has_input_object_ = HasInputObject();
     if (has_input_object_)
       omaha_response_ = GetInputObject();
-    processor_->ActionComplete(this, true);
+    processor_->ActionComplete(this, kActionCodeSuccess);
   }
   // Should never be called
   void TerminateProcessing() {
@@ -125,7 +126,7 @@
 // mock HttpFetcher is returned.
 bool TestUpdateCheck(const OmahaRequestParams& params,
                      const string& http_response,
-                     bool expected_success,
+                     ActionExitCode expected_code,
                      OmahaResponse* out_response,
                      vector<char>* out_post_data) {
   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
@@ -134,7 +135,7 @@
   OmahaRequestAction action(params, NULL, fetcher);
   OmahaRequestActionTestProcessorDelegate delegate;
   delegate.loop_ = loop;
-  delegate.expected_success_ = expected_success;
+  delegate.expected_code_ = expected_code;
 
   ActionProcessor processor;
   processor.set_delegate(&delegate);
@@ -195,7 +196,7 @@
   ASSERT_TRUE(
       TestUpdateCheck(params,
                       GetNoUpdateResponse(OmahaRequestParams::kAppId),
-                      true,
+                      kActionCodeSuccess,
                       &response,
                       NULL));
   EXPECT_FALSE(response.update_exists);
@@ -225,7 +226,7 @@
                                         "HASH1234=",  // checksum
                                         "false",  // needs admin
                                         "123"),  // size
-                      true,
+                      kActionCodeSuccess,
                       &response,
                       NULL));
   EXPECT_TRUE(response.update_exists);
@@ -288,7 +289,7 @@
   ASSERT_FALSE(
       TestUpdateCheck(params,
                       "invalid xml>",
-                      false,
+                      kActionCodeError,
                       &response,
                       NULL));
   EXPECT_FALSE(response.update_exists);
@@ -314,7 +315,7 @@
       "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
       "appid=\"foo\" status=\"ok\"><ping "
       "status=\"ok\"/><updatecheck/></app></gupdate>",
-      false,
+      kActionCodeError,
       &response,
       NULL));
   EXPECT_FALSE(response.update_exists);
@@ -340,7 +341,7 @@
       "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
       "appid=\"foo\" status=\"ok\"><ping "
       "status=\"ok\"/><updatecheck status=\"foo\"/></app></gupdate>",
-      false,
+      kActionCodeError,
       &response,
       NULL));
   EXPECT_FALSE(response.update_exists);
@@ -366,7 +367,7 @@
       "xmlns=\"http://www.google.com/update2/response\" protocol=\"2.0\"><app "
       "appid=\"foo\" status=\"ok\"><ping "
       "status=\"ok\"/></app></gupdate>",
-      false,
+      kActionCodeError,
       &response,
       NULL));
   EXPECT_FALSE(response.update_exists);
@@ -401,7 +402,7 @@
                               "hash=\"HASH1234=\" needsadmin=\"true\" "
                               "size=\"123\" "
                               "status=\"ok\"/></app></gupdate>",
-                              true,
+                              kActionCodeSuccess,
                               &response,
                               NULL));
   EXPECT_TRUE(response.update_exists);
@@ -490,7 +491,7 @@
   ASSERT_FALSE(
       TestUpdateCheck(params,
                       "invalid xml>",
-                      false,
+                      kActionCodeError,
                       &response,
                       &post_data));
   // convert post_data to string
@@ -528,7 +529,7 @@
                                         "HASH1234=", // checksum
                                         "false",  // needs admin
                                         "123"),  // size
-                      true,
+                      kActionCodeSuccess,
                       &response,
                       NULL));
 
@@ -561,7 +562,7 @@
                                         "false",  // needs admin
                                         // overflows int32:
                                         "123123123123123"),  // size
-                      true,
+                      kActionCodeSuccess,
                       &response,
                       NULL));
 
@@ -585,7 +586,7 @@
   OmahaResponse response;
   ASSERT_FALSE(TestUpdateCheck(params,
                                "invalid xml>",
-                               false,
+                               kActionCodeError,
                                &response,
                                &post_data));
   // convert post_data to string
@@ -679,7 +680,7 @@
                               "http://url");
     ASSERT_FALSE(TestUpdateCheck(params,
                                  "invalid xml>",
-                                 false,
+                                 kActionCodeError,
                                  NULL,
                                  &post_data));
     // convert post_data to string
diff --git a/omaha_response_handler_action.cc b/omaha_response_handler_action.cc
index d93919a..75776ab 100644
--- a/omaha_response_handler_action.cc
+++ b/omaha_response_handler_action.cc
@@ -43,7 +43,7 @@
   LOG(INFO) << "Using this install plan:";
   install_plan_.Dump();
 
-  completer.set_success(true);
+  completer.set_code(kActionCodeSuccess);
 }
 
 bool OmahaResponseHandlerAction::GetInstallDev(const std::string& boot_dev,
diff --git a/omaha_response_handler_action_unittest.cc b/omaha_response_handler_action_unittest.cc
index f751bbe..90cbed9 100644
--- a/omaha_response_handler_action_unittest.cc
+++ b/omaha_response_handler_action_unittest.cc
@@ -25,18 +25,18 @@
     : public ActionProcessorDelegate {
  public:
   OmahaResponseHandlerActionProcessorDelegate()
-      : success_(false),
-        success_set_(false) {}
+      : code_(kActionCodeError),
+        code_set_(false) {}
   void ActionCompleted(ActionProcessor* processor,
                        AbstractAction* action,
-                       bool success) {
+                       ActionExitCode code) {
     if (action->Type() == OmahaResponseHandlerAction::StaticType()) {
-      success_ = success;
-      success_set_ = true;
+      code_ = code;
+      code_set_ = true;
     }
   }
-  bool success_;
-  bool success_set_;
+  ActionExitCode code_;
+  bool code_set_;
 };
 
 namespace {
@@ -73,8 +73,8 @@
       << "Update test to handle non-asynch actions";
   if (out)
     *out = collector_action.object();
-  EXPECT_TRUE(delegate.success_set_);
-  return delegate.success_;
+  EXPECT_TRUE(delegate.code_set_);
+  return delegate.code_ == kActionCodeSuccess;
 }
 
 TEST_F(OmahaResponseHandlerActionTest, SimpleTest) {
diff --git a/postinstall_runner_action.cc b/postinstall_runner_action.cc
index 281582a..21d7231 100644
--- a/postinstall_runner_action.cc
+++ b/postinstall_runner_action.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -23,7 +23,7 @@
   const InstallPlan install_plan = GetInputObject();
   const string install_device = install_plan.install_path;
   ScopedActionCompleter completer(processor_, this);
-  
+
   // Make mountpoint
   string temp_dir;
   TEST_AND_RETURN(utils::MakeTempDirectory("/tmp/au_postint_mount.XXXXXX",
@@ -71,7 +71,7 @@
   if (HasOutputPipe()) {
     SetOutputObject(install_plan);
   }
-  completer.set_success(true);
+  completer.set_code(kActionCodeSuccess);
 }
 
 }  // namespace chromeos_update_engine
diff --git a/postinstall_runner_action_unittest.cc b/postinstall_runner_action_unittest.cc
index 9b19158..578f7f4 100644
--- a/postinstall_runner_action_unittest.cc
+++ b/postinstall_runner_action_unittest.cc
@@ -24,17 +24,19 @@
 
 class PostinstActionProcessorDelegate : public ActionProcessorDelegate {
  public:
-  PostinstActionProcessorDelegate() : success_(false), success_set_(false) {}
+  PostinstActionProcessorDelegate()
+      : code_(kActionCodeError),
+        code_set_(false) {}
   void ActionCompleted(ActionProcessor* processor,
                        AbstractAction* action,
-                       bool success) {
+                       ActionExitCode code) {
     if (action->Type() == PostinstallRunnerAction::StaticType()) {
-      success_ = success;
-      success_set_ = true;
+      code_ = code;
+      code_set_ = true;
     }
   }
-  bool success_;
-  bool success_set_;
+  ActionExitCode code_;
+  bool code_set_;
 };
 
 TEST_F(PostinstallRunnerActionTest, RunAsRootSimpleTest) {
@@ -127,8 +129,8 @@
   ASSERT_FALSE(processor.IsRunning())
       << "Update test to handle non-asynch actions";
 
-  EXPECT_TRUE(delegate.success_set_);
-  EXPECT_EQ(do_losetup && !do_err_script, delegate.success_);
+  EXPECT_TRUE(delegate.code_set_);
+  EXPECT_EQ(do_losetup && !do_err_script, delegate.code_ == kActionCodeSuccess);
   EXPECT_EQ(do_losetup && !do_err_script,
             !collector_action.object().install_path.empty());
   if (do_losetup && !do_err_script) {
diff --git a/set_bootable_flag_action.cc b/set_bootable_flag_action.cc
index ad574cc..1cec31e 100644
--- a/set_bootable_flag_action.cc
+++ b/set_bootable_flag_action.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -69,7 +69,7 @@
   Subprocess::SynchronousExec(command, &rc);
   TEST_AND_RETURN(rc == 0);
 
-  completer.set_success(true);
+  completer.set_code(kActionCodeSuccess);
   if (HasOutputPipe())
     SetOutputObject(GetInputObject());
 }
diff --git a/test_utils.h b/test_utils.h
index ca797d9..9f2fee2 100644
--- a/test_utils.h
+++ b/test_utils.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2010 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.
 
@@ -162,7 +162,7 @@
     if (this->HasOutputPipe()) {
       this->SetOutputObject(out_obj_);
     }
-    this->processor_->ActionComplete(this, true);
+    this->processor_->ActionComplete(this, kActionCodeSuccess);
   }
   static std::string StaticType() { return "ObjectFeederAction"; }
   std::string Type() const { return StaticType(); }
@@ -196,7 +196,7 @@
     if (this->HasInputObject()) {
       object_ = this->GetInputObject();
     }
-    this->processor_->ActionComplete(this, true);
+    this->processor_->ActionComplete(this, kActionCodeSuccess);
   }
   static std::string StaticType() { return "ObjectCollectorAction"; }
   std::string Type() const { return StaticType(); }
diff --git a/update_attempter.cc b/update_attempter.cc
index 7e536b4..b5d9644 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -198,11 +198,11 @@
 
 // Delegate methods:
 void UpdateAttempter::ProcessingDone(const ActionProcessor* processor,
-                                     bool success) {
+                                     ActionExitCode code) {
   CHECK(response_handler_action_);
   LOG(INFO) << "Processing Done.";
   actions_.clear();
-  if (success) {
+  if (code == kActionCodeSuccess) {
     SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT);
     utils::WriteFile(kUpdateCompletedMarker, "", 0);
   } else {
@@ -221,13 +221,13 @@
 // or otherwise.
 void UpdateAttempter::ActionCompleted(ActionProcessor* processor,
                                       AbstractAction* action,
-                                      bool success) {
+                                      ActionExitCode code) {
   // Reset download progress regardless of whether or not the download action
   // succeeded.
   const string type = action->Type();
   if (type == DownloadAction::StaticType())
     download_progress_ = 0.0;
-  if (!success)
+  if (code != kActionCodeSuccess)
     return;
   // Find out which action completed.
   if (type == OmahaResponseHandlerAction::StaticType()) {
diff --git a/update_attempter.h b/update_attempter.h
index 753b409..711c8ea 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -50,11 +50,11 @@
   void Update();
 
   // ActionProcessorDelegate methods:
-  void ProcessingDone(const ActionProcessor* processor, bool success);
+  void ProcessingDone(const ActionProcessor* processor, ActionExitCode code);
   void ProcessingStopped(const ActionProcessor* processor);
   void ActionCompleted(ActionProcessor* processor,
                        AbstractAction* action,
-                       bool success);
+                       ActionExitCode code);
 
   // Stop updating. An attempt will be made to record status to the disk
   // so that updates can be resumed later.
diff --git a/utils.h b/utils.h
index c6edb7d..5a3efe9 100644
--- a/utils.h
+++ b/utils.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -134,7 +134,7 @@
 
 template<typename T>
 bool VectorContainsValue(const std::vector<T>& vect, const T& value) {
-  return std::find(vect.begin(), vect.end(), value) != vect.end(); 
+  return std::find(vect.begin(), vect.end(), value) != vect.end();
 }
 
 template<typename T>
@@ -234,22 +234,21 @@
                                  AbstractAction* action)
       : processor_(processor),
         action_(action),
-        success_(false),
+        code_(kActionCodeError),
         should_complete_(true) {}
   ~ScopedActionCompleter() {
     if (should_complete_)
-      processor_->ActionComplete(action_, success_);
+      processor_->ActionComplete(action_, code_);
   }
-  void set_success(bool success) {
-    success_ = success;
-  }
+  void set_code(ActionExitCode code) { code_ = code; }
   void set_should_complete(bool should_complete) {
     should_complete_ = should_complete;
   }
+
  private:
   ActionProcessor* processor_;
   AbstractAction* action_;
-  bool success_;
+  ActionExitCode code_;
   bool should_complete_;
   DISALLOW_COPY_AND_ASSIGN(ScopedActionCompleter);
 };