Fix error code for no update.
am: 89e24c11b4

Change-Id: Ib768fc40ba50a9c97bb16d26c2e83f814a658c6f
diff --git a/common/error_code.h b/common/error_code.h
index adae391..ce41d19 100644
--- a/common/error_code.h
+++ b/common/error_code.h
@@ -76,6 +76,7 @@
   // kOmahaUpdateIgnoredOverCellular = 50,
   // kPayloadTimestampError = 51,
   kUpdatedButNotActive = 52,
+  kNoUpdate = 53,
 
   // VERY IMPORTANT! When adding new error codes:
   //
diff --git a/common/error_code_utils.cc b/common/error_code_utils.cc
index 983d004..5efc120 100644
--- a/common/error_code_utils.cc
+++ b/common/error_code_utils.cc
@@ -146,6 +146,8 @@
       return "ErrorCode::kNonCriticalUpdateInOOBE";
     case ErrorCode::kUpdatedButNotActive:
       return "ErrorCode::kUpdatedButNotActive";
+    case ErrorCode::kNoUpdate:
+      return "ErrorCode::kNoUpdate";
       // Don't add a default case to let the compiler warn about newly added
       // error codes which should be added here.
   }
diff --git a/common_service.cc b/common_service.cc
index 9f3b862..2c8f80d 100644
--- a/common_service.cc
+++ b/common_service.cc
@@ -360,7 +360,8 @@
 
 bool UpdateEngineService::GetLastAttemptError(ErrorPtr* /* error */,
                                               int32_t* out_last_attempt_error) {
-  ErrorCode error_code = system_state_->payload_state()->GetAttemptErrorCode();
+  ErrorCode error_code =
+      system_state_->update_attempter()->GetAttemptErrorCode();
   *out_last_attempt_error = static_cast<int>(error_code);
   return true;
 }
diff --git a/metrics_utils.cc b/metrics_utils.cc
index 7e6b20f..f87828f 100644
--- a/metrics_utils.cc
+++ b/metrics_utils.cc
@@ -113,6 +113,7 @@
     case ErrorCode::kPostinstallPowerwashError:
     case ErrorCode::kUpdateCanceledByChannelChange:
     case ErrorCode::kOmahaRequestXMLHasEntityDecl:
+    case ErrorCode::kNoUpdate:
       return metrics::AttemptResult::kInternalError;
 
     // Special flags. These can't happen (we mask them out above) but
@@ -214,6 +215,7 @@
     case ErrorCode::kFilesystemVerifierError:
     case ErrorCode::kUserCanceled:
     case ErrorCode::kUpdatedButNotActive:
+    case ErrorCode::kNoUpdate:
       break;
 
     // Special flags. These can't happen (we mask them out above) but
diff --git a/mock_payload_state.h b/mock_payload_state.h
index 6dccc64..259dcaf 100644
--- a/mock_payload_state.h
+++ b/mock_payload_state.h
@@ -75,7 +75,6 @@
   MOCK_CONST_METHOD0(GetUsingP2PForSharing, bool());
   MOCK_METHOD0(GetScatteringWaitPeriod, base::TimeDelta());
   MOCK_CONST_METHOD0(GetP2PUrl, std::string());
-  MOCK_CONST_METHOD0(GetAttemptErrorCode, ErrorCode());
 };
 
 }  // namespace chromeos_update_engine
diff --git a/omaha_response_handler_action.cc b/omaha_response_handler_action.cc
index 52aea4a..770f898 100644
--- a/omaha_response_handler_action.cc
+++ b/omaha_response_handler_action.cc
@@ -59,6 +59,7 @@
   if (!response.update_exists) {
     got_no_update_response_ = true;
     LOG(INFO) << "There are no updates. Aborting.";
+    completer.set_code(ErrorCode::kNoUpdate);
     return;
   }
 
diff --git a/payload_state.cc b/payload_state.cc
index cff02b1..48cbb05 100644
--- a/payload_state.cc
+++ b/payload_state.cc
@@ -66,7 +66,6 @@
       url_switch_count_(0),
       attempt_num_bytes_downloaded_(0),
       attempt_connection_type_(metrics::ConnectionType::kUnknown),
-      attempt_error_code_(ErrorCode::kSuccess),
       attempt_type_(AttemptType::kUpdate) {
   for (int i = 0; i <= kNumDownloadSources; i++)
     total_bytes_downloaded_[i] = current_bytes_downloaded_[i] = 0;
@@ -242,7 +241,6 @@
           metrics::RollbackResult::kSuccess);
       break;
   }
-  attempt_error_code_ = ErrorCode::kSuccess;
 
   // Reset the number of responses seen since it counts from the last
   // successful update, e.g. now.
@@ -256,7 +254,6 @@
   ErrorCode base_error = utils::GetBaseErrorCode(error);
   LOG(INFO) << "Updating payload state for error code: " << base_error
             << " (" << utils::ErrorCodeToString(base_error) << ")";
-  attempt_error_code_ = base_error;
 
   if (candidate_urls_.size() == 0) {
     // This means we got this error even before we got a valid Omaha response
@@ -358,6 +355,7 @@
     case ErrorCode::kFilesystemVerifierError:
     case ErrorCode::kUserCanceled:
     case ErrorCode::kUpdatedButNotActive:
+    case ErrorCode::kNoUpdate:
       LOG(INFO) << "Not incrementing URL index or failure count for this error";
       break;
 
diff --git a/payload_state.h b/payload_state.h
index 24e9900..d1906c2 100644
--- a/payload_state.h
+++ b/payload_state.h
@@ -150,10 +150,6 @@
     return p2p_url_;
   }
 
-  inline ErrorCode GetAttemptErrorCode() const override {
-    return attempt_error_code_;
-  }
-
   bool NextPayload() override;
 
  private:
@@ -568,9 +564,6 @@
   // The connection type when the attempt started.
   metrics::ConnectionType attempt_connection_type_;
 
-  // The attempt error code when the attempt finished.
-  ErrorCode attempt_error_code_;
-
   // Whether we're currently rolling back.
   AttemptType attempt_type_;
 
diff --git a/payload_state_interface.h b/payload_state_interface.h
index 4aa25e3..f553909 100644
--- a/payload_state_interface.h
+++ b/payload_state_interface.h
@@ -192,7 +192,6 @@
   // Sets/gets the P2P download URL, if one is to be used.
   virtual void SetP2PUrl(const std::string& url) = 0;
   virtual std::string GetP2PUrl() const = 0;
-  virtual ErrorCode GetAttemptErrorCode() const = 0;
 
   // Switch to next payload.
   virtual bool NextPayload() = 0;
diff --git a/update_attempter.cc b/update_attempter.cc
index 9cef154..c26a661 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -926,6 +926,8 @@
         "so requesting reboot from user.";
   }
 
+  attempt_error_code_ = utils::GetBaseErrorCode(code);
+
   if (code == ErrorCode::kSuccess) {
     WriteUpdateCompletedMarker();
     prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0);
@@ -1062,8 +1064,10 @@
         code != ErrorCode::kDownloadTransferError) {
       MarkDeltaUpdateFailure();
     }
-    // On failure, schedule an error event to be sent to Omaha.
-    CreatePendingErrorEvent(action, code);
+    if (code != ErrorCode::kNoUpdate) {
+      // On failure, schedule an error event to be sent to Omaha.
+      CreatePendingErrorEvent(action, code);
+    }
     return;
   }
   // Find out which action completed (successfully).
@@ -1263,22 +1267,12 @@
 
 void UpdateAttempter::CreatePendingErrorEvent(AbstractAction* action,
                                               ErrorCode code) {
-  if (error_event_.get()) {
+  if (error_event_.get() || status_ == UpdateStatus::REPORTING_ERROR_EVENT) {
     // This shouldn't really happen.
     LOG(WARNING) << "There's already an existing pending error event.";
     return;
   }
 
-  // For now assume that a generic Omaha response action failure means that
-  // there's no update so don't send an event. Also, double check that the
-  // failure has not occurred while sending an error event -- in which case
-  // don't schedule another. This shouldn't really happen but just in case...
-  if ((action->Type() == OmahaResponseHandlerAction::StaticType() &&
-       code == ErrorCode::kError) ||
-      status_ == UpdateStatus::REPORTING_ERROR_EVENT) {
-    return;
-  }
-
   // Classify the code to generate the appropriate result so that
   // the Borgmon charts show up the results correctly.
   // Do this before calling GetErrorCodeForAction which could potentially
diff --git a/update_attempter.h b/update_attempter.h
index 76e93a2..41b7f8e 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -177,6 +177,8 @@
   // Broadcasts the current status to all observers.
   void BroadcastStatus();
 
+  ErrorCode GetAttemptErrorCode() const { return attempt_error_code_; }
+
   // Returns the special flags to be added to ErrorCode values based on the
   // parameters used in the current update attempt.
   uint32_t GetErrorCodeFlags();
@@ -437,6 +439,9 @@
   // HTTP server response code from the last HTTP request action.
   int http_response_code_ = 0;
 
+  // The attempt error code when the update attempt finished.
+  ErrorCode attempt_error_code_ = ErrorCode::kSuccess;
+
   // CPU limiter during the update.
   CPULimiter cpu_limiter_;
 
diff --git a/update_manager/chromeos_policy.cc b/update_manager/chromeos_policy.cc
index 842839a..a56758f 100644
--- a/update_manager/chromeos_policy.cc
+++ b/update_manager/chromeos_policy.cc
@@ -142,6 +142,7 @@
     case ErrorCode::kFilesystemVerifierError:
     case ErrorCode::kUserCanceled:
     case ErrorCode::kUpdatedButNotActive:
+    case ErrorCode::kNoUpdate:
       LOG(INFO) << "Not changing URL index or failure count due to error "
                 << chromeos_update_engine::utils::ErrorCodeToString(err_code)
                 << " (" << static_cast<int>(err_code) << ")";