Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / components / component_updater / update_checker.cc
blob49b2821e7972dcd6117896f863ed55c7a71e2185
1 // Copyright 2014 The Chromium 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.
5 #include "components/component_updater/update_checker.h"
7 #include "base/compiler_specific.h"
8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/threading/thread_checker.h"
11 #include "components/component_updater/component_updater_configurator.h"
12 #include "components/component_updater/component_updater_utils.h"
13 #include "components/component_updater/crx_update_item.h"
14 #include "net/url_request/url_fetcher.h"
15 #include "net/url_request/url_fetcher_delegate.h"
16 #include "url/gurl.h"
18 namespace component_updater {
20 // Builds an update check request for |components|. |additional_attributes| is
21 // serialized as part of the <request> element of the request to customize it
22 // with data that is not platform or component specific. For each |item|, a
23 // corresponding <app> element is created and inserted as a child node of
24 // the <request>.
26 // An app element looks like this:
27 // <app appid="hnimpnehoodheedghdeeijklkeaacbdc"
28 // version="0.1.2.3" installsource="ondemand">
29 // <updatecheck />
30 // <packages>
31 // <package fp="abcd" />
32 // </packages>
33 // </app>
34 std::string BuildUpdateCheckRequest(const Configurator& config,
35 const std::vector<CrxUpdateItem*>& items,
36 const std::string& additional_attributes) {
37 std::string app_elements;
38 for (size_t i = 0; i != items.size(); ++i) {
39 const CrxUpdateItem* item = items[i];
40 std::string app("<app ");
41 base::StringAppendF(&app,
42 "appid=\"%s\" version=\"%s\"",
43 item->id.c_str(),
44 item->component.version.GetString().c_str());
45 if (item->on_demand)
46 base::StringAppendF(&app, " installsource=\"ondemand\"");
47 base::StringAppendF(&app, ">");
48 base::StringAppendF(&app, "<updatecheck />");
49 if (!item->component.fingerprint.empty()) {
50 base::StringAppendF(&app,
51 "<packages>"
52 "<package fp=\"%s\"/>"
53 "</packages>",
54 item->component.fingerprint.c_str());
56 base::StringAppendF(&app, "</app>");
57 app_elements.append(app);
58 VLOG(1) << "Appending to update request: " << app;
61 return BuildProtocolRequest(config.GetBrowserVersion().GetString(),
62 config.GetChannel(),
63 config.GetLang(),
64 config.GetOSLongName(),
65 app_elements,
66 additional_attributes);
69 class UpdateCheckerImpl : public UpdateChecker, public net::URLFetcherDelegate {
70 public:
71 UpdateCheckerImpl(const Configurator& config,
72 const UpdateCheckCallback& update_check_callback);
73 virtual ~UpdateCheckerImpl();
75 // Overrides for UpdateChecker.
76 virtual bool CheckForUpdates(
77 const std::vector<CrxUpdateItem*>& items_to_check,
78 const std::string& additional_attributes) OVERRIDE;
80 // Overrides for UrlFetcher.
81 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
83 private:
84 const Configurator& config_;
85 const UpdateCheckCallback update_check_callback_;
87 scoped_ptr<net::URLFetcher> url_fetcher_;
89 base::ThreadChecker thread_checker_;
91 DISALLOW_COPY_AND_ASSIGN(UpdateCheckerImpl);
94 scoped_ptr<UpdateChecker> UpdateChecker::Create(
95 const Configurator& config,
96 const UpdateCheckCallback& update_check_callback) {
97 scoped_ptr<UpdateCheckerImpl> update_checker(
98 new UpdateCheckerImpl(config, update_check_callback));
99 return update_checker.PassAs<UpdateChecker>();
102 UpdateCheckerImpl::UpdateCheckerImpl(
103 const Configurator& config,
104 const UpdateCheckCallback& update_check_callback)
105 : config_(config), update_check_callback_(update_check_callback) {
108 UpdateCheckerImpl::~UpdateCheckerImpl() {
109 DCHECK(thread_checker_.CalledOnValidThread());
112 bool UpdateCheckerImpl::CheckForUpdates(
113 const std::vector<CrxUpdateItem*>& items_to_check,
114 const std::string& additional_attributes) {
115 DCHECK(thread_checker_.CalledOnValidThread());
117 if (url_fetcher_)
118 return false; // Another fetch is in progress.
120 url_fetcher_.reset(SendProtocolRequest(
121 config_.UpdateUrl(),
122 BuildUpdateCheckRequest(config_, items_to_check, additional_attributes),
123 this,
124 config_.RequestContext()));
126 return true;
129 void UpdateCheckerImpl::OnURLFetchComplete(const net::URLFetcher* source) {
130 DCHECK(thread_checker_.CalledOnValidThread());
131 DCHECK(url_fetcher_.get() == source);
133 int error = 0;
134 std::string error_message;
135 UpdateResponse update_response;
137 if (FetchSuccess(*source)) {
138 std::string xml;
139 source->GetResponseAsString(&xml);
140 if (!update_response.Parse(xml)) {
141 error = -1;
142 error_message = update_response.errors();
143 VLOG(1) << "Update request failed: " << error_message;
145 } else {
146 error = GetFetchError(*source);
147 error_message.assign("network error");
148 VLOG(1) << "Update request failed: network error";
151 url_fetcher_.reset();
152 update_check_callback_.Run(error, error_message, update_response.results());
155 } // namespace component_updater