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_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/version.h"
16 #include "build/build_config.h"
17 #include "chrome/browser/component_updater/component_patcher_operation_out_of_process.h"
18 #include "chrome/browser/component_updater/component_updater_url_constants.h"
19 #include "chrome/browser/update_client/chrome_update_query_params_delegate.h"
20 #include "components/component_updater/component_updater_switches.h"
21 #include "components/update_client/configurator.h"
22 #include "components/version_info/version_info.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "net/url_request/url_request_context_getter.h"
28 #include "base/win/win_util.h"
31 using update_client::Configurator
;
32 using update_client::OutOfProcessPatcher
;
34 namespace component_updater
{
38 // Default time constants.
39 const int kDelayOneMinute
= 60;
40 const int kDelayOneHour
= kDelayOneMinute
* 60;
42 // Debug values you can pass to --component-updater=value1,value2.
43 // Speed up component checking.
44 const char kSwitchFastUpdate
[] = "fast-update";
46 // Add "testrequest=1" attribute to the update check request.
47 const char kSwitchRequestParam
[] = "test-request";
49 // Disables pings. Pings are the requests sent to the update server that report
50 // the success or the failure of component install or update attempts.
51 extern const char kSwitchDisablePings
[] = "disable-pings";
53 // Sets the URL for updates.
54 const char kSwitchUrlSource
[] = "url-source";
56 // Disables differential updates.
57 const char kSwitchDisableDeltaUpdates
[] = "disable-delta-updates";
60 // Disables background downloads.
61 const char kSwitchDisableBackgroundDownloads
[] = "disable-background-downloads";
62 #endif // defined(OS_WIN)
64 // Returns true if and only if |test| is contained in |vec|.
65 bool HasSwitchValue(const std::vector
<std::string
>& vec
, const char* test
) {
68 return (std::find(vec
.begin(), vec
.end(), test
) != vec
.end());
71 // Returns true if falling back on an alternate, unsafe, service URL is
72 // allowed. In the fallback case, the security of the component update relies
73 // only on the integrity of the CRX payloads, which is self-validating.
74 // This is allowed only for some of the pre-Windows Vista versions not including
75 // Windows XP SP3. As a side note, pings could be sent to the alternate URL too.
76 bool CanUseAltUrlSource() {
78 return !base::win::MaybeHasSHA256Support();
84 // If there is an element of |vec| of the form |test|=.*, returns the right-
85 // hand side of that assignment. Otherwise, returns an empty string.
86 // The right-hand side may contain additional '=' characters, allowing for
87 // further nesting of switch arguments.
88 std::string
GetSwitchArgument(const std::vector
<std::string
>& vec
,
92 for (std::vector
<std::string
>::const_iterator it
= vec
.begin();
95 const std::size_t found
= it
->find("=");
96 if (found
!= std::string::npos
) {
97 if (it
->substr(0, found
) == test
) {
98 return it
->substr(found
+ 1);
102 return std::string();
105 class ChromeConfigurator
: public Configurator
{
107 ChromeConfigurator(const base::CommandLine
* cmdline
,
108 net::URLRequestContextGetter
* url_request_getter
);
110 int InitialDelay() const override
;
111 int NextCheckDelay() const override
;
112 int StepDelay() 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 net::URLRequestContextGetter
* RequestContext() const override
;
123 scoped_refptr
<OutOfProcessPatcher
> CreateOutOfProcessPatcher() const override
;
124 bool DeltasEnabled() const override
;
125 bool UseBackgroundDownloader() const override
;
126 scoped_refptr
<base::SequencedTaskRunner
> GetSequencedTaskRunner()
128 scoped_refptr
<base::SingleThreadTaskRunner
> GetSingleThreadTaskRunner()
132 friend class base::RefCountedThreadSafe
<ChromeConfigurator
>;
134 ~ChromeConfigurator() override
{}
136 net::URLRequestContextGetter
* url_request_getter_
;
137 std::string extra_info_
;
138 GURL url_source_override_
;
141 bool deltas_enabled_
;
142 bool background_downloads_enabled_
;
143 bool fallback_to_alt_source_url_enabled_
;
146 ChromeConfigurator::ChromeConfigurator(
147 const base::CommandLine
* cmdline
,
148 net::URLRequestContextGetter
* url_request_getter
)
149 : url_request_getter_(url_request_getter
),
151 pings_enabled_(false),
152 deltas_enabled_(false),
153 background_downloads_enabled_(false),
154 fallback_to_alt_source_url_enabled_(false) {
155 // Parse comma-delimited debug flags.
156 std::vector
<std::string
> switch_values
= base::SplitString(
157 cmdline
->GetSwitchValueASCII(switches::kComponentUpdater
),
158 ",", base::KEEP_WHITESPACE
, base::SPLIT_WANT_NONEMPTY
);
159 fast_update_
= HasSwitchValue(switch_values
, kSwitchFastUpdate
);
160 pings_enabled_
= !HasSwitchValue(switch_values
, kSwitchDisablePings
);
161 deltas_enabled_
= !HasSwitchValue(switch_values
, kSwitchDisableDeltaUpdates
);
164 background_downloads_enabled_
=
165 !HasSwitchValue(switch_values
, kSwitchDisableBackgroundDownloads
);
167 background_downloads_enabled_
= false;
170 const std::string switch_url_source
=
171 GetSwitchArgument(switch_values
, kSwitchUrlSource
);
172 if (!switch_url_source
.empty()) {
173 url_source_override_
= GURL(switch_url_source
);
174 DCHECK(url_source_override_
.is_valid());
177 if (HasSwitchValue(switch_values
, kSwitchRequestParam
))
178 extra_info_
+= "testrequest=\"1\"";
180 fallback_to_alt_source_url_enabled_
= CanUseAltUrlSource();
183 int ChromeConfigurator::InitialDelay() const {
184 return fast_update_
? 10 : (6 * kDelayOneMinute
);
187 int ChromeConfigurator::NextCheckDelay() const {
188 return fast_update_
? 60 : (6 * kDelayOneHour
);
191 int ChromeConfigurator::StepDelay() const {
192 return fast_update_
? 1 : 1;
195 int ChromeConfigurator::OnDemandDelay() const {
196 return fast_update_
? 2 : (30 * kDelayOneMinute
);
199 int ChromeConfigurator::UpdateDelay() const {
200 return fast_update_
? 10 : (15 * kDelayOneMinute
);
203 std::vector
<GURL
> ChromeConfigurator::UpdateUrl() const {
204 std::vector
<GURL
> urls
;
205 if (url_source_override_
.is_valid()) {
206 urls
.push_back(GURL(url_source_override_
));
208 urls
.push_back(GURL(kUpdaterDefaultUrl
));
209 if (fallback_to_alt_source_url_enabled_
) {
210 urls
.push_back(GURL(kUpdaterAltUrl
));
216 std::vector
<GURL
> ChromeConfigurator::PingUrl() const {
217 return pings_enabled_
? UpdateUrl() : std::vector
<GURL
>();
220 base::Version
ChromeConfigurator::GetBrowserVersion() const {
221 return base::Version(version_info::GetVersionNumber());
224 std::string
ChromeConfigurator::GetChannel() const {
225 return ChromeUpdateQueryParamsDelegate::GetChannelString();
228 std::string
ChromeConfigurator::GetLang() const {
229 return ChromeUpdateQueryParamsDelegate::GetLang();
232 std::string
ChromeConfigurator::GetOSLongName() const {
233 return version_info::GetOSType();
236 std::string
ChromeConfigurator::ExtraRequestParams() const {
240 net::URLRequestContextGetter
* ChromeConfigurator::RequestContext() const {
241 return url_request_getter_
;
244 scoped_refptr
<OutOfProcessPatcher
>
245 ChromeConfigurator::CreateOutOfProcessPatcher() const {
246 return make_scoped_refptr(new ChromeOutOfProcessPatcher
);
249 bool ChromeConfigurator::DeltasEnabled() const {
250 return deltas_enabled_
;
253 bool ChromeConfigurator::UseBackgroundDownloader() const {
254 return background_downloads_enabled_
;
257 scoped_refptr
<base::SequencedTaskRunner
>
258 ChromeConfigurator::GetSequencedTaskRunner() const {
259 return content::BrowserThread::GetBlockingPool()
260 ->GetSequencedTaskRunnerWithShutdownBehavior(
261 content::BrowserThread::GetBlockingPool()->GetSequenceToken(),
262 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
);
265 scoped_refptr
<base::SingleThreadTaskRunner
>
266 ChromeConfigurator::GetSingleThreadTaskRunner() const {
267 return content::BrowserThread::GetMessageLoopProxyForThread(
268 content::BrowserThread::FILE);
273 scoped_refptr
<update_client::Configurator
>
274 MakeChromeComponentUpdaterConfigurator(
275 const base::CommandLine
* cmdline
,
276 net::URLRequestContextGetter
* context_getter
) {
277 return new ChromeConfigurator(cmdline
, context_getter
);
280 } // namespace component_updater