Fix layout of the Connection Tab of the Origin Info Bubble.
[chromium-blink-merge.git] / components / update_client / update_checker.cc
blobbe686ef7cf9b1ab3a3789c2d0595e291e5d2dda3
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/update_client/update_checker.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/compiler_specific.h"
13 #include "base/location.h"
14 #include "base/logging.h"
15 #include "base/macros.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/thread_task_runner_handle.h"
19 #include "base/threading/thread_checker.h"
20 #include "components/update_client/configurator.h"
21 #include "components/update_client/crx_update_item.h"
22 #include "components/update_client/request_sender.h"
23 #include "components/update_client/utils.h"
24 #include "net/url_request/url_fetcher.h"
25 #include "url/gurl.h"
27 namespace update_client {
29 namespace {
31 // Builds an update check request for |components|. |additional_attributes| is
32 // serialized as part of the <request> element of the request to customize it
33 // with data that is not platform or component specific. For each |item|, a
34 // corresponding <app> element is created and inserted as a child node of
35 // the <request>.
37 // An app element looks like this:
38 // <app appid="hnimpnehoodheedghdeeijklkeaacbdc"
39 // version="0.1.2.3" installsource="ondemand">
40 // <updatecheck />
41 // <packages>
42 // <package fp="abcd" />
43 // </packages>
44 // </app>
45 std::string BuildUpdateCheckRequest(const Configurator& config,
46 const std::vector<CrxUpdateItem*>& items,
47 const std::string& additional_attributes) {
48 std::string app_elements;
49 for (size_t i = 0; i != items.size(); ++i) {
50 const CrxUpdateItem* item = items[i];
51 std::string app("<app ");
52 base::StringAppendF(&app, "appid=\"%s\" version=\"%s\"", item->id.c_str(),
53 item->component.version.GetString().c_str());
54 if (item->on_demand)
55 base::StringAppendF(&app, " installsource=\"ondemand\"");
56 base::StringAppendF(&app, ">");
57 base::StringAppendF(&app, "<updatecheck />");
58 if (!item->component.fingerprint.empty()) {
59 base::StringAppendF(&app,
60 "<packages>"
61 "<package fp=\"%s\"/>"
62 "</packages>",
63 item->component.fingerprint.c_str());
65 base::StringAppendF(&app, "</app>");
66 app_elements.append(app);
67 VLOG(1) << "Appending to update request: " << app;
70 return BuildProtocolRequest(config.GetBrowserVersion().GetString(),
71 config.GetChannel(), config.GetLang(),
72 config.GetOSLongName(), app_elements,
73 additional_attributes);
76 class UpdateCheckerImpl : public UpdateChecker {
77 public:
78 explicit UpdateCheckerImpl(const Configurator& config);
79 ~UpdateCheckerImpl() override;
81 // Overrides for UpdateChecker.
82 bool CheckForUpdates(
83 const std::vector<CrxUpdateItem*>& items_to_check,
84 const std::string& additional_attributes,
85 const UpdateCheckCallback& update_check_callback) override;
87 private:
88 void OnRequestSenderComplete(const net::URLFetcher* source);
90 const Configurator& config_;
91 UpdateCheckCallback update_check_callback_;
92 scoped_ptr<RequestSender> request_sender_;
94 base::ThreadChecker thread_checker_;
96 DISALLOW_COPY_AND_ASSIGN(UpdateCheckerImpl);
99 UpdateCheckerImpl::UpdateCheckerImpl(const Configurator& config)
100 : config_(config) {
103 UpdateCheckerImpl::~UpdateCheckerImpl() {
104 DCHECK(thread_checker_.CalledOnValidThread());
107 bool UpdateCheckerImpl::CheckForUpdates(
108 const std::vector<CrxUpdateItem*>& items_to_check,
109 const std::string& additional_attributes,
110 const UpdateCheckCallback& update_check_callback) {
111 DCHECK(thread_checker_.CalledOnValidThread());
113 if (request_sender_.get()) {
114 NOTREACHED();
115 return false; // Another update check is in progress.
118 update_check_callback_ = update_check_callback;
120 request_sender_.reset(new RequestSender(config_));
121 request_sender_->Send(
122 BuildUpdateCheckRequest(config_, items_to_check, additional_attributes),
123 config_.UpdateUrl(),
124 base::Bind(&UpdateCheckerImpl::OnRequestSenderComplete,
125 base::Unretained(this)));
126 return true;
129 void UpdateCheckerImpl::OnRequestSenderComplete(const net::URLFetcher* source) {
130 DCHECK(thread_checker_.CalledOnValidThread());
132 GURL original_url;
133 int error = 0;
134 std::string error_message;
135 UpdateResponse update_response;
137 if (source) {
138 original_url = source->GetOriginalURL();
139 VLOG(1) << "Update check request went to: " << original_url.spec();
140 if (FetchSuccess(*source)) {
141 std::string xml;
142 source->GetResponseAsString(&xml);
143 if (!update_response.Parse(xml)) {
144 error = -1;
145 error_message = update_response.errors();
147 } else {
148 error = GetFetchError(*source);
149 error_message.assign("network error");
151 } else {
152 error = -1;
153 error_message = "no fetcher";
156 if (error) {
157 VLOG(1) << "Update request failed: " << error_message;
160 request_sender_.reset();
162 base::ThreadTaskRunnerHandle::Get()->PostTask(
163 FROM_HERE, base::Bind(update_check_callback_, original_url, error,
164 error_message, update_response.results()));
167 } // namespace
169 scoped_ptr<UpdateChecker> UpdateChecker::Create(const Configurator& config) {
170 return scoped_ptr<UpdateChecker>(new UpdateCheckerImpl(config));
173 } // namespace update_client