blob: b153fa7e5dfb8a8c7bdaa5dd11080480e8c18e68 [file] [log] [blame]
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "update_engine/payload_state.h"
6
7#include <base/logging.h>
8#include <base/stringprintf.h>
9
10#include "update_engine/omaha_request_action.h"
11#include "update_engine/prefs.h"
12
13using std::string;
14
15namespace chromeos_update_engine {
16
17// Returns a string containing that subset of the fields from the OmahaResponse
18// which we're interested in persisting for the purpose of detecting whether
19// we should clear the rest of the payload state when we get a new
20// OmahaResponse.
21static string GetFilteredResponse(const OmahaResponse& response) {
22 string mini_response = StringPrintf("NumURLs = %d\n",
23 response.payload_urls.size());
24
25 for (size_t i = 0; i < response.payload_urls.size(); i++)
26 mini_response += StringPrintf("Url%d = %s\n",
27 i, response.payload_urls[i].c_str());
28
29 mini_response += StringPrintf("Payload Size = %llu\n"
30 "Payload Sha256 Hash = %s\n"
31 "Metadata Size = %llu\n"
32 "Metadata Signature = %s\n",
33 response.size,
34 response.hash.c_str(),
35 response.metadata_size,
36 response.metadata_signature.c_str());
37 return mini_response;
38}
39
40bool PayloadState::Initialize(PrefsInterface* prefs) {
41 CHECK(prefs);
42 prefs_ = prefs;
43 LoadResponse();
44 LoadUrlIndex();
45 LogPayloadState();
46 return true;
47}
48
49void PayloadState::LogPayloadState() {
50 LOG(INFO) << "Current Payload State:\n"
51 << "Current Response = \n" << response_
52 << "Current URL Index = " << url_index_;
53}
54
55void PayloadState::SetResponse(const OmahaResponse& omaha_response) {
56 CHECK(prefs_);
57 num_urls_ = omaha_response.payload_urls.size();
58 string new_response = GetFilteredResponse(omaha_response);
59 bool has_response_changed = (response_ != new_response);
60 response_ = new_response;
61 LOG(INFO) << "Stored Response = \n" << response_;
62 prefs_->SetString(kPrefsCurrentResponse, response_);
63
64 if (has_response_changed) {
65 LOG(INFO) << "Resetting all payload state as this is a new response";
66 SetUrlIndex(0);
67 }
68}
69
70void PayloadState::UpdateFailed(ActionExitCode error) {
71 LOG(INFO) << "Updating payload state for error code: " << error;
72
73 if (!num_urls_) {
74 // Since we don't persist num_urls_, it's possible that we get an error in
75 // our communication to Omaha before even OmahaRequestAction code had a
76 // chance to call SetResponse (which sets num_urls_). So we should not
77 // advance the url_index_ in such cases.
78 LOG(INFO) << "Ignoring failures until we get a valid Omaha response.";
79 return;
80 }
81
82 // chromium-os:37206: Classify the errors and advance the URL index at
83 // different rates for different errors in the next CL. Until then, advance
84 // URL index on every single error.
85 uint32_t next_url_index = GetUrlIndex() + 1;
86 if (next_url_index < num_urls_) {
87 LOG(INFO) << "Advancing the URL index for next attempt";
88 } else {
89 LOG(INFO) << "Resetting the current URL index (" << GetUrlIndex() << ") to "
90 << "0 as we only have " << num_urls_ << " URL(s)";
91 next_url_index = 0;
92
93 // TODO(jaysri): This is the place where we should increment the
94 // payload_attempt_number so that we can back-off appropriately.
95 }
96
97 SetUrlIndex(next_url_index);
98}
99
100string PayloadState::LoadResponse() {
101 CHECK(prefs_);
102 string stored_value;
103 if (prefs_->Exists(kPrefsCurrentResponse) &&
104 prefs_->GetString(kPrefsCurrentResponse, &stored_value)) {
105 response_ = stored_value;
106 }
107 return response_;
108}
109
110uint32_t PayloadState::LoadUrlIndex() {
111 CHECK(prefs_);
112 int64_t stored_value;
113 if (prefs_->Exists(kPrefsCurrentUrlIndex) &&
114 prefs_->GetInt64(kPrefsCurrentUrlIndex, &stored_value)) {
115 url_index_ = stored_value;
116 }
117 return url_index_;
118}
119
120void PayloadState::SetUrlIndex(uint32_t url_index) {
121 CHECK(prefs_);
122 // TODO(jaysri): When we implement failure count, make sure to reset
123 // the failure count when url index changes.
124 url_index_ = url_index;
125 LOG(INFO) << "Current URL Index = " << url_index_;
126 prefs_->SetInt64(kPrefsCurrentUrlIndex, url_index_);
127}
128
129} // namespace chromeos_update_engine