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 "chrome/browser/component_updater/chrome_component_updater_configurator.h"
11 #include "base/command_line.h"
12 #include "base/compiler_specific.h"
13 #include "base/strings/string_util.h"
14 #include "base/version.h"
16 #include "base/win/win_util.h"
18 #include "build/build_config.h"
19 #include "chrome/browser/component_updater/component_patcher_operation_out_of_process.h"
20 #include "chrome/browser/component_updater/component_updater_url_constants.h"
21 #include "chrome/browser/update_client/chrome_update_query_params_delegate.h"
22 #include "chrome/common/chrome_version_info.h"
23 #include "components/component_updater/component_updater_switches.h"
24 #include "components/update_client/configurator.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "net/url_request/url_request_context_getter.h"
29 using update_client::Configurator
;
30 using update_client::OutOfProcessPatcher
;
32 namespace component_updater
{
36 // Default time constants.
37 const int kDelayOneMinute
= 60;
38 const int kDelayOneHour
= kDelayOneMinute
* 60;
40 // Debug values you can pass to --component-updater=value1,value2.
41 // Speed up component checking.
42 const char kSwitchFastUpdate
[] = "fast-update";
44 // Add "testrequest=1" attribute to the update check request.
45 const char kSwitchRequestParam
[] = "test-request";
47 // Disables pings. Pings are the requests sent to the update server that report
48 // the success or the failure of component install or update attempts.
49 extern const char kSwitchDisablePings
[] = "disable-pings";
51 // Sets the URL for updates.
52 const char kSwitchUrlSource
[] = "url-source";
54 // Disables differential updates.
55 const char kSwitchDisableDeltaUpdates
[] = "disable-delta-updates";
58 // Disables background downloads.
59 const char kSwitchDisableBackgroundDownloads
[] = "disable-background-downloads";
60 #endif // defined(OS_WIN)
62 // Returns true if and only if |test| is contained in |vec|.
63 bool HasSwitchValue(const std::vector
<std::string
>& vec
, const char* test
) {
66 return (std::find(vec
.begin(), vec
.end(), test
) != vec
.end());
69 // Returns true if falling back on an alternate, unsafe, service URL is
70 // allowed. In the fallback case, the security of the component update relies
71 // only on the integrity of the CRX payloads, which is self-validating.
72 // This is allowed only for some of the pre-Windows Vista versions not including
73 // Windows XP SP3. As a side note, pings could be sent to the alternate URL too.
74 bool CanUseAltUrlSource() {
76 return !base::win::MaybeHasSHA256Support();
82 // If there is an element of |vec| of the form |test|=.*, returns the right-
83 // hand side of that assignment. Otherwise, returns an empty string.
84 // The right-hand side may contain additional '=' characters, allowing for
85 // further nesting of switch arguments.
86 std::string
GetSwitchArgument(const std::vector
<std::string
>& vec
,
90 for (std::vector
<std::string
>::const_iterator it
= vec
.begin();
93 const std::size_t found
= it
->find("=");
94 if (found
!= std::string::npos
) {
95 if (it
->substr(0, found
) == test
) {
96 return it
->substr(found
+ 1);
100 return std::string();
103 class ChromeConfigurator
: public Configurator
{
105 ChromeConfigurator(const base::CommandLine
* cmdline
,
106 net::URLRequestContextGetter
* url_request_getter
);
108 int InitialDelay() const override
;
109 int NextCheckDelay() override
;
110 int StepDelay() const override
;
111 int StepDelayMedium() override
;
112 int MinimumReCheckWait() const override
;
113 int OnDemandDelay() const override
;
114 int UpdateDelay() const override
;
115 std::vector
<GURL
> UpdateUrl() const override
;
116 std::vector
<GURL
> PingUrl() const override
;
117 base::Version
GetBrowserVersion() const override
;
118 std::string
GetChannel() const override
;
119 std::string
GetLang() const override
;
120 std::string
GetOSLongName() const override
;
121 std::string
ExtraRequestParams() const override
;
122 size_t UrlSizeLimit() const override
;
123 net::URLRequestContextGetter
* RequestContext() const override
;
124 scoped_refptr
<OutOfProcessPatcher
> CreateOutOfProcessPatcher() const override
;
125 bool DeltasEnabled() const override
;
126 bool UseBackgroundDownloader() const override
;
127 scoped_refptr
<base::SequencedTaskRunner
> GetSequencedTaskRunner()
129 scoped_refptr
<base::SingleThreadTaskRunner
> GetSingleThreadTaskRunner()
133 friend class base::RefCountedThreadSafe
<ChromeConfigurator
>;
135 ~ChromeConfigurator() override
{}
137 net::URLRequestContextGetter
* url_request_getter_
;
138 std::string extra_info_
;
139 GURL url_source_override_
;
142 bool deltas_enabled_
;
143 bool background_downloads_enabled_
;
144 bool fallback_to_alt_source_url_enabled_
;
147 ChromeConfigurator::ChromeConfigurator(
148 const base::CommandLine
* cmdline
,
149 net::URLRequestContextGetter
* url_request_getter
)
150 : url_request_getter_(url_request_getter
),
152 pings_enabled_(false),
153 deltas_enabled_(false),
154 background_downloads_enabled_(false),
155 fallback_to_alt_source_url_enabled_(false) {
156 // Parse comma-delimited debug flags.
157 std::vector
<std::string
> switch_values
;
158 Tokenize(cmdline
->GetSwitchValueASCII(switches::kComponentUpdater
),
161 fast_update_
= HasSwitchValue(switch_values
, kSwitchFastUpdate
);
162 pings_enabled_
= !HasSwitchValue(switch_values
, kSwitchDisablePings
);
163 deltas_enabled_
= !HasSwitchValue(switch_values
, kSwitchDisableDeltaUpdates
);
166 background_downloads_enabled_
=
167 !HasSwitchValue(switch_values
, kSwitchDisableBackgroundDownloads
);
169 background_downloads_enabled_
= false;
172 const std::string switch_url_source
=
173 GetSwitchArgument(switch_values
, kSwitchUrlSource
);
174 if (!switch_url_source
.empty()) {
175 url_source_override_
= GURL(switch_url_source
);
176 DCHECK(url_source_override_
.is_valid());
179 if (HasSwitchValue(switch_values
, kSwitchRequestParam
))
180 extra_info_
+= "testrequest=\"1\"";
182 fallback_to_alt_source_url_enabled_
= CanUseAltUrlSource();
185 int ChromeConfigurator::InitialDelay() const {
186 return fast_update_
? 1 : (6 * kDelayOneMinute
);
189 int ChromeConfigurator::NextCheckDelay() {
190 return fast_update_
? 3 : (6 * kDelayOneHour
);
193 int ChromeConfigurator::StepDelayMedium() {
194 return fast_update_
? 3 : (15 * kDelayOneMinute
);
197 int ChromeConfigurator::StepDelay() const {
198 return fast_update_
? 1 : 1;
201 int ChromeConfigurator::MinimumReCheckWait() const {
202 return fast_update_
? 30 : (6 * kDelayOneHour
);
205 int ChromeConfigurator::OnDemandDelay() const {
206 return fast_update_
? 2 : (30 * kDelayOneMinute
);
209 int ChromeConfigurator::UpdateDelay() const {
210 return fast_update_
? 1 : (15 * kDelayOneMinute
);
213 std::vector
<GURL
> ChromeConfigurator::UpdateUrl() const {
214 std::vector
<GURL
> urls
;
215 if (url_source_override_
.is_valid()) {
216 urls
.push_back(GURL(url_source_override_
));
218 urls
.push_back(GURL(kUpdaterDefaultUrl
));
219 if (fallback_to_alt_source_url_enabled_
) {
220 urls
.push_back(GURL(kUpdaterAltUrl
));
226 std::vector
<GURL
> ChromeConfigurator::PingUrl() const {
227 return pings_enabled_
? UpdateUrl() : std::vector
<GURL
>();
230 base::Version
ChromeConfigurator::GetBrowserVersion() const {
231 return base::Version(chrome::VersionInfo().Version());
234 std::string
ChromeConfigurator::GetChannel() const {
235 return ChromeUpdateQueryParamsDelegate::GetChannelString();
238 std::string
ChromeConfigurator::GetLang() const {
239 return ChromeUpdateQueryParamsDelegate::GetLang();
242 std::string
ChromeConfigurator::GetOSLongName() const {
243 return chrome::VersionInfo().OSType();
246 std::string
ChromeConfigurator::ExtraRequestParams() const {
250 size_t ChromeConfigurator::UrlSizeLimit() const {
254 net::URLRequestContextGetter
* ChromeConfigurator::RequestContext() const {
255 return url_request_getter_
;
258 scoped_refptr
<OutOfProcessPatcher
>
259 ChromeConfigurator::CreateOutOfProcessPatcher() const {
260 return make_scoped_refptr(new ChromeOutOfProcessPatcher
);
263 bool ChromeConfigurator::DeltasEnabled() const {
264 return deltas_enabled_
;
267 bool ChromeConfigurator::UseBackgroundDownloader() const {
268 return background_downloads_enabled_
;
271 scoped_refptr
<base::SequencedTaskRunner
>
272 ChromeConfigurator::GetSequencedTaskRunner() const {
273 return content::BrowserThread::GetBlockingPool()
274 ->GetSequencedTaskRunnerWithShutdownBehavior(
275 content::BrowserThread::GetBlockingPool()->GetSequenceToken(),
276 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
);
279 scoped_refptr
<base::SingleThreadTaskRunner
>
280 ChromeConfigurator::GetSingleThreadTaskRunner() const {
281 return content::BrowserThread::GetMessageLoopProxyForThread(
282 content::BrowserThread::FILE);
287 scoped_refptr
<update_client::Configurator
>
288 MakeChromeComponentUpdaterConfigurator(
289 const base::CommandLine
* cmdline
,
290 net::URLRequestContextGetter
* context_getter
) {
291 return new ChromeConfigurator(cmdline
, context_getter
);
294 } // namespace component_updater