| Index: update_attempter.cc
|
| diff --git a/update_attempter.cc b/update_attempter.cc
|
| index 3f2012670b78ddf91724a2d03eaa8badc38ee50e..ee1cf00f7bd64ac6abe7cd12f135ddb039d903e5 100644
|
| --- a/update_attempter.cc
|
| +++ b/update_attempter.cc
|
| @@ -83,6 +83,8 @@ const char* UpdateStatusToString(UpdateStatus status) {
|
| return "UPDATE_STATUS_FINALIZING";
|
| case UPDATE_STATUS_UPDATED_NEED_REBOOT:
|
| return "UPDATE_STATUS_UPDATED_NEED_REBOOT";
|
| + case UPDATE_STATUS_REPORTING_ERROR_EVENT:
|
| + return "UPDATE_STATUS_REPORTING_ERROR_EVENT";
|
| default:
|
| return "unknown status";
|
| }
|
| @@ -199,6 +201,13 @@ void UpdateAttempter::ProcessingDone(const ActionProcessor* processor,
|
| CHECK(response_handler_action_);
|
| LOG(INFO) << "Processing Done.";
|
| actions_.clear();
|
| +
|
| + if (status_ == UPDATE_STATUS_REPORTING_ERROR_EVENT) {
|
| + LOG(INFO) << "Error event sent.";
|
| + SetStatusAndNotify(UPDATE_STATUS_IDLE);
|
| + return;
|
| + }
|
| +
|
| if (code == kActionCodeSuccess) {
|
| SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT);
|
| utils::WriteFile(kUpdateCompletedMarker, "", 0);
|
| @@ -210,16 +219,20 @@ void UpdateAttempter::ProcessingDone(const ActionProcessor* processor,
|
| 1, // min = 1 second
|
| 20 * 60, // max = 20 minutes
|
| 50); // buckets
|
| - } else {
|
| - LOG(INFO) << "Update failed.";
|
| - SetStatusAndNotify(UPDATE_STATUS_IDLE);
|
| + return;
|
| }
|
| +
|
| + LOG(INFO) << "Update failed.";
|
| + if (ScheduleErrorEventAction())
|
| + return;
|
| + SetStatusAndNotify(UPDATE_STATUS_IDLE);
|
| }
|
|
|
| void UpdateAttempter::ProcessingStopped(const ActionProcessor* processor) {
|
| download_progress_ = 0.0;
|
| SetStatusAndNotify(UPDATE_STATUS_IDLE);
|
| actions_.clear();
|
| + error_event_.reset(NULL);
|
| }
|
|
|
| // Called whenever an action has finished processing, either successfully
|
| @@ -232,8 +245,19 @@ void UpdateAttempter::ActionCompleted(ActionProcessor* processor,
|
| const string type = action->Type();
|
| if (type == DownloadAction::StaticType())
|
| download_progress_ = 0.0;
|
| - if (code != kActionCodeSuccess)
|
| + if (code != kActionCodeSuccess) {
|
| + // On failure, schedule an error event to be sent to Omaha. For
|
| + // now assume that 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 (type != OmahaResponseHandlerAction::StaticType() &&
|
| + status_ != UPDATE_STATUS_REPORTING_ERROR_EVENT) {
|
| + CreatePendingErrorEvent(code);
|
| + }
|
| return;
|
| + }
|
| // Find out which action completed.
|
| if (type == OmahaResponseHandlerAction::StaticType()) {
|
| SetStatusAndNotify(UPDATE_STATUS_DOWNLOADING);
|
| @@ -308,4 +332,30 @@ void UpdateAttempter::SetStatusAndNotify(UpdateStatus status) {
|
| new_size_);
|
| }
|
|
|
| +void UpdateAttempter::CreatePendingErrorEvent(ActionExitCode code) {
|
| + if (error_event_.get()) {
|
| + // This shouldn't really happen.
|
| + LOG(WARNING) << "There's already an existing pending error event.";
|
| + return;
|
| + }
|
| + error_event_.reset(new OmahaEvent(OmahaEvent::kTypeUpdateComplete,
|
| + OmahaEvent::kResultError,
|
| + code));
|
| +}
|
| +
|
| +bool UpdateAttempter::ScheduleErrorEventAction() {
|
| + if (error_event_.get() == NULL)
|
| + return false;
|
| +
|
| + shared_ptr<OmahaRequestAction> error_event_action(
|
| + new OmahaRequestAction(omaha_request_params_,
|
| + error_event_.release(), // Pass ownership.
|
| + new LibcurlHttpFetcher));
|
| + actions_.push_back(shared_ptr<AbstractAction>(error_event_action));
|
| + processor_.EnqueueAction(error_event_action.get());
|
| + SetStatusAndNotify(UPDATE_STATUS_REPORTING_ERROR_EVENT);
|
| + processor_.StartProcessing();
|
| + return true;
|
| +}
|
| +
|
| } // namespace chromeos_update_engine
|
|
|