Fix wrong ifdef that disabled client side detection.
[chromium-blink-merge.git] / chrome / browser / safe_browsing / safe_browsing_service.cc
blob0d7f7da2926884c8884e550ce06a73c689474780
1 // Copyright (c) 2012 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/safe_browsing/safe_browsing_service.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/command_line.h"
13 #include "base/lazy_instance.h"
14 #include "base/metrics/field_trial.h"
15 #include "base/path_service.h"
16 #include "base/prefs/pref_change_registrar.h"
17 #include "base/prefs/pref_service.h"
18 #include "base/stl_util.h"
19 #include "base/strings/string_util.h"
20 #include "base/threading/thread.h"
21 #include "base/threading/thread_restrictions.h"
22 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/chrome_notification_types.h"
24 #include "chrome/browser/prefs/tracked/tracked_preference_validation_delegate.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/profiles/profile_manager.h"
27 #include "chrome/browser/safe_browsing/client_side_detection_service.h"
28 #include "chrome/browser/safe_browsing/database_manager.h"
29 #include "chrome/browser/safe_browsing/download_protection_service.h"
30 #include "chrome/browser/safe_browsing/malware_details.h"
31 #include "chrome/browser/safe_browsing/ping_manager.h"
32 #include "chrome/browser/safe_browsing/protocol_manager.h"
33 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
34 #include "chrome/browser/safe_browsing/ui_manager.h"
35 #include "chrome/common/chrome_constants.h"
36 #include "chrome/common/chrome_paths.h"
37 #include "chrome/common/chrome_switches.h"
38 #include "chrome/common/pref_names.h"
39 #include "chrome/common/url_constants.h"
40 #include "components/startup_metric_utils/startup_metric_utils.h"
41 #include "content/public/browser/browser_thread.h"
42 #include "content/public/browser/cookie_store_factory.h"
43 #include "content/public/browser/notification_service.h"
44 #include "net/cookies/cookie_monster.h"
45 #include "net/extras/sqlite/cookie_crypto_delegate.h"
46 #include "net/url_request/url_request_context.h"
47 #include "net/url_request/url_request_context_getter.h"
49 #if defined(OS_WIN)
50 #include "chrome/installer/util/browser_distribution.h"
51 #endif
53 #if defined(SAFE_BROWSING_DB_LOCAL)
54 #include "chrome/browser/safe_browsing/local_database_manager.h"
55 #elif defined(SAFE_BROWSING_DB_REMOTE)
56 #include "chrome/browser/safe_browsing/remote_database_manager.h"
57 #endif
59 #if defined(FULL_SAFE_BROWSING)
60 #include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h"
61 #include "chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.h"
62 #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h"
63 #include "chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector.h"
64 #include "chrome/browser/safe_browsing/incident_reporting/resource_request_detector.h"
65 #include "chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.h"
66 #endif
68 using content::BrowserThread;
70 namespace {
72 // Filename suffix for the cookie database.
73 const base::FilePath::CharType kCookiesFile[] = FILE_PATH_LITERAL(" Cookies");
75 // The default URL prefix where browser fetches chunk updates, hashes,
76 // and reports safe browsing hits and malware details.
77 const char* const kSbDefaultURLPrefix =
78 "https://safebrowsing.google.com/safebrowsing";
80 // The backup URL prefix used when there are issues establishing a connection
81 // with the server at the primary URL.
82 const char* const kSbBackupConnectErrorURLPrefix =
83 "https://alt1-safebrowsing.google.com/safebrowsing";
85 // The backup URL prefix used when there are HTTP-specific issues with the
86 // server at the primary URL.
87 const char* const kSbBackupHttpErrorURLPrefix =
88 "https://alt2-safebrowsing.google.com/safebrowsing";
90 // The backup URL prefix used when there are local network specific issues.
91 const char* const kSbBackupNetworkErrorURLPrefix =
92 "https://alt3-safebrowsing.google.com/safebrowsing";
94 base::FilePath CookieFilePath() {
95 return base::FilePath(
96 SafeBrowsingService::GetBaseFilename().value() + kCookiesFile);
99 #if defined(FULL_SAFE_BROWSING)
100 // Returns true if the incident reporting service is enabled via a field trial.
101 bool IsIncidentReportingServiceEnabled() {
102 const std::string group_name = base::FieldTrialList::FindFullName(
103 "SafeBrowsingIncidentReportingService");
104 return group_name == "Enabled";
106 #endif // defined(FULL_SAFE_BROWSING)
108 } // namespace
110 class SafeBrowsingURLRequestContextGetter
111 : public net::URLRequestContextGetter {
112 public:
113 explicit SafeBrowsingURLRequestContextGetter(
114 SafeBrowsingService* sb_service_);
116 // Implementation for net::UrlRequestContextGetter.
117 net::URLRequestContext* GetURLRequestContext() override;
118 scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
119 const override;
121 // Shuts down any pending requests using the getter, and nulls out
122 // |sb_service_|.
123 void SafeBrowsingServiceShuttingDown();
125 protected:
126 ~SafeBrowsingURLRequestContextGetter() override;
128 private:
129 SafeBrowsingService* sb_service_; // Owned by BrowserProcess.
130 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
133 SafeBrowsingURLRequestContextGetter::SafeBrowsingURLRequestContextGetter(
134 SafeBrowsingService* sb_service)
135 : sb_service_(sb_service),
136 network_task_runner_(
137 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)) {
140 net::URLRequestContext*
141 SafeBrowsingURLRequestContextGetter::GetURLRequestContext() {
142 DCHECK_CURRENTLY_ON(BrowserThread::IO);
144 // Check if the service has been shut down.
145 if (!sb_service_)
146 return nullptr;
148 DCHECK(sb_service_->url_request_context_.get());
149 return sb_service_->url_request_context_.get();
152 scoped_refptr<base::SingleThreadTaskRunner>
153 SafeBrowsingURLRequestContextGetter::GetNetworkTaskRunner() const {
154 return network_task_runner_;
157 void SafeBrowsingURLRequestContextGetter::SafeBrowsingServiceShuttingDown() {
158 sb_service_ = nullptr;
159 URLRequestContextGetter::NotifyContextShuttingDown();
162 SafeBrowsingURLRequestContextGetter::~SafeBrowsingURLRequestContextGetter() {}
164 // static
165 SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL;
167 // The default SafeBrowsingServiceFactory. Global, made a singleton so we
168 // don't leak it.
169 class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory {
170 public:
171 SafeBrowsingService* CreateSafeBrowsingService() override {
172 return new SafeBrowsingService();
175 private:
176 friend struct base::DefaultLazyInstanceTraits<SafeBrowsingServiceFactoryImpl>;
178 SafeBrowsingServiceFactoryImpl() { }
180 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactoryImpl);
183 static base::LazyInstance<SafeBrowsingServiceFactoryImpl>::Leaky
184 g_safe_browsing_service_factory_impl = LAZY_INSTANCE_INITIALIZER;
186 // static
187 base::FilePath SafeBrowsingService::GetCookieFilePathForTesting() {
188 return CookieFilePath();
191 // static
192 base::FilePath SafeBrowsingService::GetBaseFilename() {
193 base::FilePath path;
194 bool result = PathService::Get(chrome::DIR_USER_DATA, &path);
195 DCHECK(result);
196 return path.Append(chrome::kSafeBrowsingBaseFilename);
200 // static
201 SafeBrowsingService* SafeBrowsingService::CreateSafeBrowsingService() {
202 if (!factory_)
203 factory_ = g_safe_browsing_service_factory_impl.Pointer();
204 return factory_->CreateSafeBrowsingService();
208 SafeBrowsingService::SafeBrowsingService()
209 : protocol_manager_(NULL),
210 ping_manager_(NULL),
211 enabled_(false) {
214 SafeBrowsingService::~SafeBrowsingService() {
215 // We should have already been shut down. If we're still enabled, then the
216 // database isn't going to be closed properly, which could lead to corruption.
217 DCHECK(!enabled_);
220 void SafeBrowsingService::Initialize() {
221 startup_metric_utils::ScopedSlowStartupUMA
222 scoped_timer("Startup.SlowStartupSafeBrowsingServiceInitialize");
224 url_request_context_getter_ =
225 new SafeBrowsingURLRequestContextGetter(this);
227 ui_manager_ = CreateUIManager();
229 database_manager_ = CreateDatabaseManager();
231 BrowserThread::PostTask(
232 BrowserThread::IO, FROM_HERE,
233 base::Bind(
234 &SafeBrowsingService::InitURLRequestContextOnIOThread, this,
235 make_scoped_refptr(g_browser_process->system_request_context())));
237 #if defined(FULL_SAFE_BROWSING)
238 #if defined(SAFE_BROWSING_CSD)
239 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
240 switches::kDisableClientSidePhishingDetection)) {
241 csd_service_.reset(safe_browsing::ClientSideDetectionService::Create(
242 url_request_context_getter_.get()));
244 #endif // defined(SAFE_BROWSING_CSD)
246 // TODO(nparker): Adding SAFE_BROWSING_SERVICE_DOWNLOAD to control this might
247 // allow removing FULL_SAFE_BROWSING above.
248 #if !defined(OS_ANDROID)
249 download_service_.reset(new safe_browsing::DownloadProtectionService(
250 this, url_request_context_getter_.get()));
251 #endif
253 if (IsIncidentReportingServiceEnabled()) {
254 incident_service_.reset(new safe_browsing::IncidentReportingService(
255 this, url_request_context_getter_));
256 resource_request_detector_.reset(new safe_browsing::ResourceRequestDetector(
257 incident_service_->GetIncidentReceiver()));
260 off_domain_inclusion_detector_.reset(
261 new safe_browsing::OffDomainInclusionDetector(database_manager_));
262 #endif // !defined(FULL_SAFE_BROWSING)
264 // Track the safe browsing preference of existing profiles.
265 // The SafeBrowsingService will be started if any existing profile has the
266 // preference enabled. It will also listen for updates to the preferences.
267 ProfileManager* profile_manager = g_browser_process->profile_manager();
268 if (profile_manager) {
269 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
270 for (size_t i = 0; i < profiles.size(); ++i) {
271 if (profiles[i]->IsOffTheRecord())
272 continue;
273 AddPrefService(profiles[i]->GetPrefs());
277 // Track profile creation and destruction.
278 prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
279 content::NotificationService::AllSources());
280 prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
281 content::NotificationService::AllSources());
283 #if defined(FULL_SAFE_BROWSING)
284 // Register all the delayed analysis to the incident reporting service.
285 RegisterAllDelayedAnalysis();
286 #endif
289 void SafeBrowsingService::ShutDown() {
290 // Deletes the PrefChangeRegistrars, whose dtors also unregister |this| as an
291 // observer of the preferences.
292 STLDeleteValues(&prefs_map_);
294 // Remove Profile creation/destruction observers.
295 prefs_registrar_.RemoveAll();
297 Stop(true);
298 // The IO thread is going away, so make sure the ClientSideDetectionService
299 // dtor executes now since it may call the dtor of URLFetcher which relies
300 // on it.
301 csd_service_.reset();
303 #if defined(FULL_SAFE_BROWSING)
304 off_domain_inclusion_detector_.reset();
305 resource_request_detector_.reset();
306 incident_service_.reset();
307 #endif
309 download_service_.reset();
311 BrowserThread::PostNonNestableTask(
312 BrowserThread::IO, FROM_HERE,
313 base::Bind(&SafeBrowsingService::DestroyURLRequestContextOnIOThread,
314 this, url_request_context_getter_));
316 // Release the URLRequestContextGetter after passing it to the IOThread. It
317 // has to be released now rather than in the destructor because it can only
318 // be deleted on the IOThread, and the SafeBrowsingService outlives the IO
319 // thread.
320 url_request_context_getter_ = nullptr;
323 // Binhash verification is only enabled for UMA users for now.
324 bool SafeBrowsingService::DownloadBinHashNeeded() const {
325 DCHECK_CURRENTLY_ON(BrowserThread::UI);
327 #if defined(FULL_SAFE_BROWSING)
328 return (database_manager_->download_protection_enabled() &&
329 ui_manager_->CanReportStats()) ||
330 (download_protection_service() &&
331 download_protection_service()->enabled());
332 #else
333 return false;
334 #endif
337 net::URLRequestContextGetter* SafeBrowsingService::url_request_context() {
338 DCHECK_CURRENTLY_ON(BrowserThread::UI);
339 return url_request_context_getter_.get();
342 const scoped_refptr<SafeBrowsingUIManager>&
343 SafeBrowsingService::ui_manager() const {
344 return ui_manager_;
347 const scoped_refptr<SafeBrowsingDatabaseManager>&
348 SafeBrowsingService::database_manager() const {
349 return database_manager_;
352 SafeBrowsingProtocolManager* SafeBrowsingService::protocol_manager() const {
353 DCHECK_CURRENTLY_ON(BrowserThread::IO);
354 return protocol_manager_;
357 SafeBrowsingPingManager* SafeBrowsingService::ping_manager() const {
358 DCHECK_CURRENTLY_ON(BrowserThread::IO);
359 return ping_manager_;
362 scoped_ptr<TrackedPreferenceValidationDelegate>
363 SafeBrowsingService::CreatePreferenceValidationDelegate(
364 Profile* profile) const {
365 #if defined(FULL_SAFE_BROWSING)
366 if (incident_service_)
367 return incident_service_->CreatePreferenceValidationDelegate(profile);
368 #endif
369 return scoped_ptr<TrackedPreferenceValidationDelegate>();
372 #if defined(FULL_SAFE_BROWSING)
373 void SafeBrowsingService::RegisterDelayedAnalysisCallback(
374 const safe_browsing::DelayedAnalysisCallback& callback) {
375 if (incident_service_)
376 incident_service_->RegisterDelayedAnalysisCallback(callback);
378 #endif
380 void SafeBrowsingService::AddDownloadManager(
381 content::DownloadManager* download_manager) {
382 #if defined(FULL_SAFE_BROWSING)
383 if (incident_service_)
384 incident_service_->AddDownloadManager(download_manager);
385 #endif
388 void SafeBrowsingService::OnResourceRequest(const net::URLRequest* request) {
389 #if defined(FULL_SAFE_BROWSING)
390 if (off_domain_inclusion_detector_)
391 off_domain_inclusion_detector_->OnResourceRequest(request);
392 if (resource_request_detector_)
393 resource_request_detector_->OnResourceRequest(request);
394 #endif
397 SafeBrowsingUIManager* SafeBrowsingService::CreateUIManager() {
398 return new SafeBrowsingUIManager(this);
401 SafeBrowsingDatabaseManager* SafeBrowsingService::CreateDatabaseManager() {
402 #if defined(SAFE_BROWSING_DB_LOCAL)
403 return new LocalSafeBrowsingDatabaseManager(this);
404 #elif defined(SAFE_BROWSING_DB_REMOTE)
405 return new RemoteSafeBrowsingDatabaseManager();
406 #else
407 return NULL;
408 #endif
411 void SafeBrowsingService::RegisterAllDelayedAnalysis() {
412 #if defined(FULL_SAFE_BROWSING)
413 safe_browsing::RegisterBinaryIntegrityAnalysis();
414 safe_browsing::RegisterBlacklistLoadAnalysis();
415 safe_browsing::RegisterVariationsSeedSignatureAnalysis();
416 #else
417 NOTREACHED();
418 #endif
421 void SafeBrowsingService::InitURLRequestContextOnIOThread(
422 net::URLRequestContextGetter* system_url_request_context_getter) {
423 DCHECK_CURRENTLY_ON(BrowserThread::IO);
424 DCHECK(!url_request_context_.get());
426 scoped_refptr<net::CookieStore> cookie_store(
427 content::CreateCookieStore(
428 content::CookieStoreConfig(
429 CookieFilePath(),
430 content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
431 NULL,
432 NULL)));
434 url_request_context_.reset(new net::URLRequestContext);
435 // |system_url_request_context_getter| may be NULL during tests.
436 if (system_url_request_context_getter) {
437 url_request_context_->CopyFrom(
438 system_url_request_context_getter->GetURLRequestContext());
440 url_request_context_->set_cookie_store(cookie_store.get());
443 void SafeBrowsingService::DestroyURLRequestContextOnIOThread(
444 scoped_refptr<SafeBrowsingURLRequestContextGetter> context_getter) {
445 DCHECK_CURRENTLY_ON(BrowserThread::IO);
447 context_getter->SafeBrowsingServiceShuttingDown();
448 url_request_context_.reset();
451 SafeBrowsingProtocolConfig SafeBrowsingService::GetProtocolConfig() const {
452 SafeBrowsingProtocolConfig config;
453 // On Windows, get the safe browsing client name from the browser
454 // distribution classes in installer util. These classes don't yet have
455 // an analog on non-Windows builds so just keep the name specified here.
456 #if defined(OS_WIN)
457 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
458 config.client_name = dist->GetSafeBrowsingName();
459 #else
460 #if defined(GOOGLE_CHROME_BUILD)
461 config.client_name = "googlechrome";
462 #else
463 config.client_name = "chromium";
464 #endif
466 // Mark client string to allow server to differentiate mobile.
467 #if defined(OS_ANDROID)
468 config.client_name.append("-a");
469 #elif defined(OS_IOS)
470 config.client_name.append("-i");
471 #endif
473 #endif // defined(OS_WIN)
474 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
475 config.disable_auto_update =
476 cmdline->HasSwitch(switches::kSbDisableAutoUpdate) ||
477 cmdline->HasSwitch(switches::kDisableBackgroundNetworking);
478 config.url_prefix = kSbDefaultURLPrefix;
479 config.backup_connect_error_url_prefix = kSbBackupConnectErrorURLPrefix;
480 config.backup_http_error_url_prefix = kSbBackupHttpErrorURLPrefix;
481 config.backup_network_error_url_prefix = kSbBackupNetworkErrorURLPrefix;
483 return config;
486 // Any tests that create a DatabaseManager that isn't derived from
487 // LocalSafeBrowsingDatabaseManager should override this to return NULL.
488 SafeBrowsingProtocolManagerDelegate*
489 SafeBrowsingService::GetProtocolManagerDelegate() {
490 #if defined(SAFE_BROWSING_DB_LOCAL)
491 return static_cast<LocalSafeBrowsingDatabaseManager*>(
492 database_manager_.get());
493 #else
494 NOTREACHED();
495 return NULL;
496 #endif
499 void SafeBrowsingService::StartOnIOThread(
500 net::URLRequestContextGetter* url_request_context_getter) {
501 DCHECK_CURRENTLY_ON(BrowserThread::IO);
502 if (enabled_)
503 return;
504 enabled_ = true;
506 SafeBrowsingProtocolConfig config = GetProtocolConfig();
508 #if defined(SAFE_BROWSING_DB_LOCAL) || defined(SAFE_BROWSING_DB_REMOTE)
509 DCHECK(database_manager_.get());
510 database_manager_->StartOnIOThread();
511 #endif
513 #if defined(SAFE_BROWSING_DB_LOCAL)
514 SafeBrowsingProtocolManagerDelegate* protocol_manager_delegate =
515 GetProtocolManagerDelegate();
516 if (protocol_manager_delegate) {
517 protocol_manager_ = SafeBrowsingProtocolManager::Create(
518 protocol_manager_delegate, url_request_context_getter, config);
519 protocol_manager_->Initialize();
521 #endif
523 DCHECK(!ping_manager_);
524 ping_manager_ = SafeBrowsingPingManager::Create(
525 url_request_context_getter, config);
528 void SafeBrowsingService::StopOnIOThread(bool shutdown) {
529 DCHECK_CURRENTLY_ON(BrowserThread::IO);
531 #if defined(SAFE_BROWSING_DB_LOCAL) || defined(SAFE_BROWSING_DB_REMOTE)
532 database_manager_->StopOnIOThread(shutdown);
533 #endif
534 ui_manager_->StopOnIOThread(shutdown);
536 if (enabled_) {
537 enabled_ = false;
539 #if defined(SAFE_BROWSING_DB_LOCAL)
540 // This cancels all in-flight GetHash requests. Note that database_manager_
541 // relies on the protocol_manager_ so if the latter is destroyed, the
542 // former must be stopped.
543 if (protocol_manager_) {
544 delete protocol_manager_;
545 protocol_manager_ = NULL;
547 #endif
548 delete ping_manager_;
549 ping_manager_ = NULL;
553 void SafeBrowsingService::Start() {
554 DCHECK_CURRENTLY_ON(BrowserThread::UI);
556 BrowserThread::PostTask(
557 BrowserThread::IO, FROM_HERE,
558 base::Bind(&SafeBrowsingService::StartOnIOThread, this,
559 url_request_context_getter_));
562 void SafeBrowsingService::Stop(bool shutdown) {
563 BrowserThread::PostTask(
564 BrowserThread::IO, FROM_HERE,
565 base::Bind(&SafeBrowsingService::StopOnIOThread, this, shutdown));
568 void SafeBrowsingService::Observe(int type,
569 const content::NotificationSource& source,
570 const content::NotificationDetails& details) {
571 switch (type) {
572 case chrome::NOTIFICATION_PROFILE_CREATED: {
573 DCHECK_CURRENTLY_ON(BrowserThread::UI);
574 Profile* profile = content::Source<Profile>(source).ptr();
575 if (!profile->IsOffTheRecord())
576 AddPrefService(profile->GetPrefs());
577 break;
579 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
580 DCHECK_CURRENTLY_ON(BrowserThread::UI);
581 Profile* profile = content::Source<Profile>(source).ptr();
582 if (!profile->IsOffTheRecord())
583 RemovePrefService(profile->GetPrefs());
584 break;
586 default:
587 NOTREACHED();
591 void SafeBrowsingService::AddPrefService(PrefService* pref_service) {
592 DCHECK(prefs_map_.find(pref_service) == prefs_map_.end());
593 PrefChangeRegistrar* registrar = new PrefChangeRegistrar();
594 registrar->Init(pref_service);
595 registrar->Add(prefs::kSafeBrowsingEnabled,
596 base::Bind(&SafeBrowsingService::RefreshState,
597 base::Unretained(this)));
598 prefs_map_[pref_service] = registrar;
599 RefreshState();
602 void SafeBrowsingService::RemovePrefService(PrefService* pref_service) {
603 if (prefs_map_.find(pref_service) != prefs_map_.end()) {
604 delete prefs_map_[pref_service];
605 prefs_map_.erase(pref_service);
606 RefreshState();
607 } else {
608 NOTREACHED();
612 void SafeBrowsingService::RefreshState() {
613 // Check if any profile requires the service to be active.
614 bool enable = false;
615 std::map<PrefService*, PrefChangeRegistrar*>::iterator iter;
616 for (iter = prefs_map_.begin(); iter != prefs_map_.end(); ++iter) {
617 if (iter->first->GetBoolean(prefs::kSafeBrowsingEnabled)) {
618 enable = true;
619 break;
623 if (enable)
624 Start();
625 else
626 Stop(false);
628 #if defined(FULL_SAFE_BROWSING)
629 if (csd_service_)
630 csd_service_->SetEnabledAndRefreshState(enable);
631 if (download_service_)
632 download_service_->SetEnabled(enable);
633 #endif