chrome_component_updater_configurator.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
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.
4
5#include "chrome/browser/component_updater/chrome_component_updater_configurator.h"
6
7#include <algorithm>
8#include <string>
9#include <vector>
10
11#include "base/command_line.h"
12#include "base/compiler_specific.h"
13#include "base/strings/string_util.h"
14#include "base/version.h"
15#include "build/build_config.h"
16#include "chrome/browser/component_updater/component_patcher_operation_out_of_process.h"
17#include "chrome/browser/omaha_query_params/chrome_omaha_query_params_delegate.h"
18#include "chrome/common/chrome_version_info.h"
19#include "components/component_updater/component_updater_configurator.h"
20#include "components/component_updater/component_updater_switches.h"
21#include "content/public/browser/browser_thread.h"
22#include "net/url_request/url_request_context_getter.h"
23#include "url/gurl.h"
24
25namespace component_updater {
26
27namespace {
28
29// Default time constants.
30const int kDelayOneMinute = 60;
31const int kDelayOneHour = kDelayOneMinute * 60;
32
33// Debug values you can pass to --component-updater=value1,value2.
34// Speed up component checking.
35const char kSwitchFastUpdate[] = "fast-update";
36
37// Add "testrequest=1" attribute to the update check request.
38const char kSwitchRequestParam[] = "test-request";
39
40// Disables pings. Pings are the requests sent to the update server that report
41// the success or the failure of component install or update attempts.
42extern const char kSwitchDisablePings[] = "disable-pings";
43
44// Sets the URL for updates.
45const char kSwitchUrlSource[] = "url-source";
46
47#define COMPONENT_UPDATER_SERVICE_ENDPOINT \
48  "//clients2.google.com/service/update2"
49
50// The default url for the v3 protocol service endpoint. Can be
51// overridden with --component-updater=url-source=someurl.
52const char kDefaultUrlSource[] = "https:" COMPONENT_UPDATER_SERVICE_ENDPOINT;
53
54// The url to send the pings to.
55const char kPingUrl[] = "https:" COMPONENT_UPDATER_SERVICE_ENDPOINT;
56
57// Disables differential updates.
58const char kSwitchDisableDeltaUpdates[] = "disable-delta-updates";
59
60#if defined(OS_WIN)
61// Disables background downloads.
62const char kSwitchDisableBackgroundDownloads[] = "disable-background-downloads";
63#endif  // defined(OS_WIN)
64
65// Returns true if and only if |test| is contained in |vec|.
66bool HasSwitchValue(const std::vector<std::string>& vec, const char* test) {
67  if (vec.empty())
68    return 0;
69  return (std::find(vec.begin(), vec.end(), test) != vec.end());
70}
71
72// If there is an element of |vec| of the form |test|=.*, returns the right-
73// hand side of that assignment. Otherwise, returns an empty string.
74// The right-hand side may contain additional '=' characters, allowing for
75// further nesting of switch arguments.
76std::string GetSwitchArgument(const std::vector<std::string>& vec,
77                              const char* test) {
78  if (vec.empty())
79    return std::string();
80  for (std::vector<std::string>::const_iterator it = vec.begin();
81       it != vec.end();
82       ++it) {
83    const std::size_t found = it->find("=");
84    if (found != std::string::npos) {
85      if (it->substr(0, found) == test) {
86        return it->substr(found + 1);
87      }
88    }
89  }
90  return std::string();
91}
92
93class ChromeConfigurator : public Configurator {
94 public:
95  ChromeConfigurator(const CommandLine* cmdline,
96                     net::URLRequestContextGetter* url_request_getter);
97
98  virtual ~ChromeConfigurator() {}
99
100  virtual int InitialDelay() const OVERRIDE;
101  virtual int NextCheckDelay() OVERRIDE;
102  virtual int StepDelay() const OVERRIDE;
103  virtual int StepDelayMedium() OVERRIDE;
104  virtual int MinimumReCheckWait() const OVERRIDE;
105  virtual int OnDemandDelay() const OVERRIDE;
106  virtual GURL UpdateUrl() const OVERRIDE;
107  virtual GURL PingUrl() const OVERRIDE;
108  virtual base::Version GetBrowserVersion() const OVERRIDE;
109  virtual std::string GetChannel() const OVERRIDE;
110  virtual std::string GetLang() const OVERRIDE;
111  virtual std::string GetOSLongName() const OVERRIDE;
112  virtual std::string ExtraRequestParams() const OVERRIDE;
113  virtual size_t UrlSizeLimit() const OVERRIDE;
114  virtual net::URLRequestContextGetter* RequestContext() const OVERRIDE;
115  virtual scoped_refptr<OutOfProcessPatcher> CreateOutOfProcessPatcher()
116      const OVERRIDE;
117  virtual bool DeltasEnabled() const OVERRIDE;
118  virtual bool UseBackgroundDownloader() const OVERRIDE;
119  virtual scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner()
120      const OVERRIDE;
121  virtual scoped_refptr<base::SingleThreadTaskRunner>
122      GetSingleThreadTaskRunner() const OVERRIDE;
123
124 private:
125  net::URLRequestContextGetter* url_request_getter_;
126  std::string extra_info_;
127  std::string url_source_;
128  bool fast_update_;
129  bool pings_enabled_;
130  bool deltas_enabled_;
131  bool background_downloads_enabled_;
132};
133
134ChromeConfigurator::ChromeConfigurator(
135    const CommandLine* cmdline,
136    net::URLRequestContextGetter* url_request_getter)
137    : url_request_getter_(url_request_getter),
138      fast_update_(false),
139      pings_enabled_(false),
140      deltas_enabled_(false),
141      background_downloads_enabled_(false) {
142  // Parse comma-delimited debug flags.
143  std::vector<std::string> switch_values;
144  Tokenize(cmdline->GetSwitchValueASCII(switches::kComponentUpdater),
145           ",",
146           &switch_values);
147  fast_update_ = HasSwitchValue(switch_values, kSwitchFastUpdate);
148  pings_enabled_ = !HasSwitchValue(switch_values, kSwitchDisablePings);
149  deltas_enabled_ = !HasSwitchValue(switch_values, kSwitchDisableDeltaUpdates);
150
151#if defined(OS_WIN)
152  background_downloads_enabled_ =
153      !HasSwitchValue(switch_values, kSwitchDisableBackgroundDownloads);
154#else
155  background_downloads_enabled_ = false;
156#endif
157
158  url_source_ = GetSwitchArgument(switch_values, kSwitchUrlSource);
159  if (url_source_.empty()) {
160    url_source_ = kDefaultUrlSource;
161  }
162
163  if (HasSwitchValue(switch_values, kSwitchRequestParam))
164    extra_info_ += "testrequest=\"1\"";
165}
166
167int ChromeConfigurator::InitialDelay() const {
168  return fast_update_ ? 1 : (6 * kDelayOneMinute);
169}
170
171int ChromeConfigurator::NextCheckDelay() {
172  return fast_update_ ? 3 : (6 * kDelayOneHour);
173}
174
175int ChromeConfigurator::StepDelayMedium() {
176  return fast_update_ ? 3 : (15 * kDelayOneMinute);
177}
178
179int ChromeConfigurator::StepDelay() const {
180  return fast_update_ ? 1 : 1;
181}
182
183int ChromeConfigurator::MinimumReCheckWait() const {
184  return fast_update_ ? 30 : (6 * kDelayOneHour);
185}
186
187int ChromeConfigurator::OnDemandDelay() const {
188  return fast_update_ ? 2 : (30 * kDelayOneMinute);
189}
190
191GURL ChromeConfigurator::UpdateUrl() const {
192  return GURL(url_source_);
193}
194
195GURL ChromeConfigurator::PingUrl() const {
196  return pings_enabled_ ? GURL(kPingUrl) : GURL();
197}
198
199base::Version ChromeConfigurator::GetBrowserVersion() const {
200  return base::Version(chrome::VersionInfo().Version());
201}
202
203std::string ChromeConfigurator::GetChannel() const {
204  return ChromeOmahaQueryParamsDelegate::GetChannelString();
205}
206
207std::string ChromeConfigurator::GetLang() const {
208  return ChromeOmahaQueryParamsDelegate::GetLang();
209}
210
211std::string ChromeConfigurator::GetOSLongName() const {
212  return chrome::VersionInfo().OSType();
213}
214
215std::string ChromeConfigurator::ExtraRequestParams() const {
216  return extra_info_;
217}
218
219size_t ChromeConfigurator::UrlSizeLimit() const {
220  return 1024ul;
221}
222
223net::URLRequestContextGetter* ChromeConfigurator::RequestContext() const {
224  return url_request_getter_;
225}
226
227scoped_refptr<OutOfProcessPatcher>
228ChromeConfigurator::CreateOutOfProcessPatcher() const {
229  return make_scoped_refptr(new ChromeOutOfProcessPatcher);
230}
231
232bool ChromeConfigurator::DeltasEnabled() const {
233  return deltas_enabled_;
234}
235
236bool ChromeConfigurator::UseBackgroundDownloader() const {
237  return background_downloads_enabled_;
238}
239
240scoped_refptr<base::SequencedTaskRunner>
241ChromeConfigurator::GetSequencedTaskRunner() const {
242  return content::BrowserThread::GetBlockingPool()
243      ->GetSequencedTaskRunnerWithShutdownBehavior(
244          content::BrowserThread::GetBlockingPool()->GetSequenceToken(),
245          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
246}
247
248scoped_refptr<base::SingleThreadTaskRunner>
249ChromeConfigurator::GetSingleThreadTaskRunner() const {
250  return content::BrowserThread::GetMessageLoopProxyForThread(
251      content::BrowserThread::FILE);
252}
253
254}  // namespace
255
256Configurator* MakeChromeComponentUpdaterConfigurator(
257    const base::CommandLine* cmdline,
258    net::URLRequestContextGetter* context_getter) {
259  return new ChromeConfigurator(cmdline, context_getter);
260}
261
262}  // namespace component_updater
263