Remove 'RemoveTrailingSeparators' function from SimpleMenuModel
[chromium-blink-merge.git] / chrome / browser / safe_browsing / safe_browsing_service.cc
blobd657e6612e9e143541454ae2206a779c7de3817b
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/debug/leak_tracker.h"
14 #include "base/lazy_instance.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/profiler/scoped_tracker.h"
19 #include "base/stl_util.h"
20 #include "base/strings/string_util.h"
21 #include "base/threading/thread.h"
22 #include "base/threading/thread_restrictions.h"
23 #include "chrome/browser/browser_process.h"
24 #include "chrome/browser/chrome_notification_types.h"
25 #include "chrome/browser/prefs/tracked/tracked_preference_validation_delegate.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/profiles/profile_manager.h"
28 #include "chrome/browser/safe_browsing/client_side_detection_service.h"
29 #include "chrome/browser/safe_browsing/database_manager.h"
30 #include "chrome/browser/safe_browsing/download_protection_service.h"
31 #include "chrome/browser/safe_browsing/malware_details.h"
32 #include "chrome/browser/safe_browsing/ping_manager.h"
33 #include "chrome/browser/safe_browsing/protocol_manager.h"
34 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
35 #include "chrome/browser/safe_browsing/ui_manager.h"
36 #include "chrome/common/chrome_constants.h"
37 #include "chrome/common/chrome_paths.h"
38 #include "chrome/common/chrome_switches.h"
39 #include "chrome/common/pref_names.h"
40 #include "chrome/common/url_constants.h"
41 #include "components/startup_metric_utils/startup_metric_utils.h"
42 #include "components/variations/variations_associated_data.h"
43 #include "content/public/browser/browser_thread.h"
44 #include "content/public/browser/cookie_store_factory.h"
45 #include "content/public/browser/notification_service.h"
46 #include "net/cookies/cookie_monster.h"
47 #include "net/extras/sqlite/cookie_crypto_delegate.h"
48 #include "net/url_request/url_request_context.h"
49 #include "net/url_request/url_request_context_getter.h"
51 #if defined(OS_WIN)
52 #include "chrome/installer/util/browser_distribution.h"
53 #endif
55 #if defined(FULL_SAFE_BROWSING)
56 #include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h"
57 #include "chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.h"
58 #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h"
59 #include "chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector.h"
60 #include "chrome/browser/safe_browsing/incident_reporting/resource_request_detector.h"
61 #include "chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.h"
62 #endif
64 using content::BrowserThread;
66 namespace {
68 // Filename suffix for the cookie database.
69 const base::FilePath::CharType kCookiesFile[] = FILE_PATH_LITERAL(" Cookies");
71 // The default URL prefix where browser fetches chunk updates, hashes,
72 // and reports safe browsing hits and malware details.
73 const char* const kSbDefaultURLPrefix =
74 "https://safebrowsing.google.com/safebrowsing";
76 // The backup URL prefix used when there are issues establishing a connection
77 // with the server at the primary URL.
78 const char* const kSbBackupConnectErrorURLPrefix =
79 "https://alt1-safebrowsing.google.com/safebrowsing";
81 // The backup URL prefix used when there are HTTP-specific issues with the
82 // server at the primary URL.
83 const char* const kSbBackupHttpErrorURLPrefix =
84 "https://alt2-safebrowsing.google.com/safebrowsing";
86 // The backup URL prefix used when there are local network specific issues.
87 const char* const kSbBackupNetworkErrorURLPrefix =
88 "https://alt3-safebrowsing.google.com/safebrowsing";
90 base::FilePath CookieFilePath() {
91 return base::FilePath(
92 SafeBrowsingService::GetBaseFilename().value() + kCookiesFile);
95 #if defined(FULL_SAFE_BROWSING)
96 // Returns true if the incident reporting service is enabled via a field trial.
97 bool IsIncidentReportingServiceEnabled() {
98 const std::string group_name = base::FieldTrialList::FindFullName(
99 "SafeBrowsingIncidentReportingService");
100 return group_name == "Enabled";
102 #endif // defined(FULL_SAFE_BROWSING)
104 } // namespace
106 class SafeBrowsingURLRequestContextGetter
107 : public net::URLRequestContextGetter {
108 public:
109 explicit SafeBrowsingURLRequestContextGetter(
110 SafeBrowsingService* sb_service_);
112 // Implementation for net::UrlRequestContextGetter.
113 net::URLRequestContext* GetURLRequestContext() override;
114 scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
115 const override;
117 protected:
118 ~SafeBrowsingURLRequestContextGetter() override;
120 private:
121 SafeBrowsingService* const sb_service_; // Owned by BrowserProcess.
122 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
124 base::debug::LeakTracker<SafeBrowsingURLRequestContextGetter> leak_tracker_;
127 SafeBrowsingURLRequestContextGetter::SafeBrowsingURLRequestContextGetter(
128 SafeBrowsingService* sb_service)
129 : sb_service_(sb_service),
130 network_task_runner_(
131 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)) {
134 SafeBrowsingURLRequestContextGetter::~SafeBrowsingURLRequestContextGetter() {}
136 net::URLRequestContext*
137 SafeBrowsingURLRequestContextGetter::GetURLRequestContext() {
138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
139 DCHECK(sb_service_->url_request_context_.get());
141 return sb_service_->url_request_context_.get();
144 scoped_refptr<base::SingleThreadTaskRunner>
145 SafeBrowsingURLRequestContextGetter::GetNetworkTaskRunner() const {
146 return network_task_runner_;
149 // static
150 SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL;
152 // The default SafeBrowsingServiceFactory. Global, made a singleton so we
153 // don't leak it.
154 class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory {
155 public:
156 SafeBrowsingService* CreateSafeBrowsingService() override {
157 return new SafeBrowsingService();
160 private:
161 friend struct base::DefaultLazyInstanceTraits<SafeBrowsingServiceFactoryImpl>;
163 SafeBrowsingServiceFactoryImpl() { }
165 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactoryImpl);
168 static base::LazyInstance<SafeBrowsingServiceFactoryImpl>::Leaky
169 g_safe_browsing_service_factory_impl = LAZY_INSTANCE_INITIALIZER;
171 // static
172 base::FilePath SafeBrowsingService::GetCookieFilePathForTesting() {
173 return CookieFilePath();
176 // static
177 base::FilePath SafeBrowsingService::GetBaseFilename() {
178 base::FilePath path;
179 bool result = PathService::Get(chrome::DIR_USER_DATA, &path);
180 DCHECK(result);
181 return path.Append(chrome::kSafeBrowsingBaseFilename);
185 // static
186 SafeBrowsingService* SafeBrowsingService::CreateSafeBrowsingService() {
187 if (!factory_)
188 factory_ = g_safe_browsing_service_factory_impl.Pointer();
189 return factory_->CreateSafeBrowsingService();
193 SafeBrowsingService::SafeBrowsingService()
194 : protocol_manager_(NULL),
195 ping_manager_(NULL),
196 enabled_(false) {
199 SafeBrowsingService::~SafeBrowsingService() {
200 // We should have already been shut down. If we're still enabled, then the
201 // database isn't going to be closed properly, which could lead to corruption.
202 DCHECK(!enabled_);
205 void SafeBrowsingService::Initialize() {
206 startup_metric_utils::ScopedSlowStartupUMA
207 scoped_timer("Startup.SlowStartupSafeBrowsingServiceInitialize");
209 url_request_context_getter_ =
210 new SafeBrowsingURLRequestContextGetter(this);
212 ui_manager_ = CreateUIManager();
214 database_manager_ = CreateDatabaseManager();
216 BrowserThread::PostTask(
217 BrowserThread::IO, FROM_HERE,
218 base::Bind(
219 &SafeBrowsingService::InitURLRequestContextOnIOThread, this,
220 make_scoped_refptr(g_browser_process->system_request_context())));
222 #if defined(FULL_SAFE_BROWSING)
223 #if !defined(OS_ANDROID)
224 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
225 switches::kDisableClientSidePhishingDetection)) {
226 csd_service_.reset(safe_browsing::ClientSideDetectionService::Create(
227 url_request_context_getter_.get()));
229 download_service_.reset(new safe_browsing::DownloadProtectionService(
230 this, url_request_context_getter_.get()));
231 #endif
233 if (IsIncidentReportingServiceEnabled()) {
234 incident_service_.reset(new safe_browsing::IncidentReportingService(
235 this, url_request_context_getter_));
236 resource_request_detector_.reset(new safe_browsing::ResourceRequestDetector(
237 incident_service_->GetIncidentReceiver()));
240 off_domain_inclusion_detector_.reset(
241 new safe_browsing::OffDomainInclusionDetector(database_manager_));
242 #endif
244 // Track the safe browsing preference of existing profiles.
245 // The SafeBrowsingService will be started if any existing profile has the
246 // preference enabled. It will also listen for updates to the preferences.
247 ProfileManager* profile_manager = g_browser_process->profile_manager();
248 if (profile_manager) {
249 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
250 for (size_t i = 0; i < profiles.size(); ++i) {
251 if (profiles[i]->IsOffTheRecord())
252 continue;
253 AddPrefService(profiles[i]->GetPrefs());
257 // Track profile creation and destruction.
258 prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
259 content::NotificationService::AllSources());
260 prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
261 content::NotificationService::AllSources());
263 #if defined(FULL_SAFE_BROWSING)
264 // Register all the delayed analysis to the incident reporting service.
265 RegisterAllDelayedAnalysis();
266 #endif
269 void SafeBrowsingService::ShutDown() {
270 // Deletes the PrefChangeRegistrars, whose dtors also unregister |this| as an
271 // observer of the preferences.
272 STLDeleteValues(&prefs_map_);
274 // Remove Profile creation/destruction observers.
275 prefs_registrar_.RemoveAll();
277 Stop(true);
278 // The IO thread is going away, so make sure the ClientSideDetectionService
279 // dtor executes now since it may call the dtor of URLFetcher which relies
280 // on it.
281 csd_service_.reset();
283 #if defined(FULL_SAFE_BROWSING)
284 off_domain_inclusion_detector_.reset();
285 resource_request_detector_.reset();
286 incident_service_.reset();
287 #endif
289 download_service_.reset();
291 url_request_context_getter_ = NULL;
292 BrowserThread::PostNonNestableTask(
293 BrowserThread::IO, FROM_HERE,
294 base::Bind(&SafeBrowsingService::DestroyURLRequestContextOnIOThread,
295 this));
298 // Binhash verification is only enabled for UMA users for now.
299 bool SafeBrowsingService::DownloadBinHashNeeded() const {
300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
302 #if defined(FULL_SAFE_BROWSING)
303 return (database_manager_->download_protection_enabled() &&
304 ui_manager_->CanReportStats()) ||
305 (download_protection_service() &&
306 download_protection_service()->enabled());
307 #else
308 return false;
309 #endif
312 net::URLRequestContextGetter* SafeBrowsingService::url_request_context() {
313 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
314 return url_request_context_getter_.get();
317 const scoped_refptr<SafeBrowsingUIManager>&
318 SafeBrowsingService::ui_manager() const {
319 return ui_manager_;
322 const scoped_refptr<SafeBrowsingDatabaseManager>&
323 SafeBrowsingService::database_manager() const {
324 return database_manager_;
327 SafeBrowsingProtocolManager* SafeBrowsingService::protocol_manager() const {
328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
329 return protocol_manager_;
332 SafeBrowsingPingManager* SafeBrowsingService::ping_manager() const {
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
334 return ping_manager_;
337 scoped_ptr<TrackedPreferenceValidationDelegate>
338 SafeBrowsingService::CreatePreferenceValidationDelegate(
339 Profile* profile) const {
340 #if defined(FULL_SAFE_BROWSING)
341 if (incident_service_)
342 return incident_service_->CreatePreferenceValidationDelegate(profile);
343 #endif
344 return scoped_ptr<TrackedPreferenceValidationDelegate>();
347 #if defined(FULL_SAFE_BROWSING)
348 void SafeBrowsingService::RegisterDelayedAnalysisCallback(
349 const safe_browsing::DelayedAnalysisCallback& callback) {
350 if (incident_service_)
351 incident_service_->RegisterDelayedAnalysisCallback(callback);
353 #endif
355 void SafeBrowsingService::AddDownloadManager(
356 content::DownloadManager* download_manager) {
357 #if defined(FULL_SAFE_BROWSING)
358 if (incident_service_)
359 incident_service_->AddDownloadManager(download_manager);
360 #endif
363 void SafeBrowsingService::OnResourceRequest(const net::URLRequest* request) {
364 #if defined(FULL_SAFE_BROWSING)
365 if (off_domain_inclusion_detector_)
366 off_domain_inclusion_detector_->OnResourceRequest(request);
367 if (resource_request_detector_)
368 resource_request_detector_->OnResourceRequest(request);
369 #endif
372 SafeBrowsingUIManager* SafeBrowsingService::CreateUIManager() {
373 return new SafeBrowsingUIManager(this);
376 SafeBrowsingDatabaseManager* SafeBrowsingService::CreateDatabaseManager() {
377 #if defined(FULL_SAFE_BROWSING)
378 return new SafeBrowsingDatabaseManager(this);
379 #else
380 return NULL;
381 #endif
384 void SafeBrowsingService::RegisterAllDelayedAnalysis() {
385 #if defined(FULL_SAFE_BROWSING)
386 safe_browsing::RegisterBinaryIntegrityAnalysis();
387 safe_browsing::RegisterBlacklistLoadAnalysis();
388 safe_browsing::RegisterVariationsSeedSignatureAnalysis();
389 #else
390 NOTREACHED();
391 #endif
394 void SafeBrowsingService::InitURLRequestContextOnIOThread(
395 net::URLRequestContextGetter* system_url_request_context_getter) {
396 // TODO(pkasting): Remove ScopedTracker below once crbug.com/455469 is fixed.
397 tracked_objects::ScopedTracker tracking_profile1(
398 FROM_HERE_WITH_EXPLICIT_FUNCTION(
399 "455469 SafeBrowsingService::InitURLRequestContextOnIOThread 1"));
400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
401 DCHECK(!url_request_context_.get());
403 scoped_refptr<net::CookieStore> cookie_store(
404 content::CreateCookieStore(
405 content::CookieStoreConfig(
406 CookieFilePath(),
407 content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
408 NULL,
409 NULL)));
411 // TODO(pkasting): Remove ScopedTracker below once crbug.com/455469 is fixed.
412 tracked_objects::ScopedTracker tracking_profile2(
413 FROM_HERE_WITH_EXPLICIT_FUNCTION(
414 "455469 SafeBrowsingService::InitURLRequestContextOnIOThread 2"));
415 url_request_context_.reset(new net::URLRequestContext);
416 // |system_url_request_context_getter| may be NULL during tests.
417 if (system_url_request_context_getter) {
418 url_request_context_->CopyFrom(
419 system_url_request_context_getter->GetURLRequestContext());
421 url_request_context_->set_cookie_store(cookie_store.get());
424 void SafeBrowsingService::DestroyURLRequestContextOnIOThread() {
425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
427 url_request_context_->AssertNoURLRequests();
429 // Need to do the CheckForLeaks on IOThread instead of in ShutDown where
430 // url_request_context_getter_ is cleared, since the URLRequestContextGetter
431 // will PostTask to IOTread to delete itself.
432 using base::debug::LeakTracker;
433 LeakTracker<SafeBrowsingURLRequestContextGetter>::CheckForLeaks();
435 url_request_context_.reset();
438 SafeBrowsingProtocolConfig SafeBrowsingService::GetProtocolConfig() const {
439 SafeBrowsingProtocolConfig config;
440 // On Windows, get the safe browsing client name from the browser
441 // distribution classes in installer util. These classes don't yet have
442 // an analog on non-Windows builds so just keep the name specified here.
443 #if defined(OS_WIN)
444 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
445 config.client_name = dist->GetSafeBrowsingName();
446 #else
447 #if defined(GOOGLE_CHROME_BUILD)
448 config.client_name = "googlechrome";
449 #else
450 config.client_name = "chromium";
451 #endif
453 // Mark client string to allow server to differentiate mobile.
454 #if defined(OS_ANDROID)
455 config.client_name.append("-a");
456 #elif defined(OS_IOS)
457 config.client_name.append("-i");
458 #endif
460 #endif // defined(OS_WIN)
461 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
462 config.disable_auto_update =
463 cmdline->HasSwitch(switches::kSbDisableAutoUpdate) ||
464 cmdline->HasSwitch(switches::kDisableBackgroundNetworking);
465 config.url_prefix = kSbDefaultURLPrefix;
466 config.backup_connect_error_url_prefix = kSbBackupConnectErrorURLPrefix;
467 config.backup_http_error_url_prefix = kSbBackupHttpErrorURLPrefix;
468 config.backup_network_error_url_prefix = kSbBackupNetworkErrorURLPrefix;
470 return config;
473 void SafeBrowsingService::StartOnIOThread(
474 net::URLRequestContextGetter* url_request_context_getter) {
475 // TODO(pkasting): Remove ScopedTracker below once crbug.com/455469 is fixed.
476 tracked_objects::ScopedTracker tracking_profile1(
477 FROM_HERE_WITH_EXPLICIT_FUNCTION(
478 "455469 SafeBrowsingService::StartOnIOThread 1"));
479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
480 if (enabled_)
481 return;
482 enabled_ = true;
484 SafeBrowsingProtocolConfig config = GetProtocolConfig();
486 #if defined(FULL_SAFE_BROWSING)
487 // TODO(pkasting): Remove ScopedTracker below once crbug.com/455469 is fixed.
488 tracked_objects::ScopedTracker tracking_profile2(
489 FROM_HERE_WITH_EXPLICIT_FUNCTION(
490 "455469 SafeBrowsingService::StartOnIOThread 2"));
491 DCHECK(database_manager_.get());
492 database_manager_->StartOnIOThread();
494 // TODO(pkasting): Remove ScopedTracker below once crbug.com/455469 is fixed.
495 tracked_objects::ScopedTracker tracking_profile3(
496 FROM_HERE_WITH_EXPLICIT_FUNCTION(
497 "455469 SafeBrowsingService::StartOnIOThread 3"));
498 DCHECK(!protocol_manager_);
499 protocol_manager_ = SafeBrowsingProtocolManager::Create(
500 database_manager_.get(), url_request_context_getter, config);
501 protocol_manager_->Initialize();
502 #endif
504 // TODO(pkasting): Remove ScopedTracker below once crbug.com/455469 is fixed.
505 tracked_objects::ScopedTracker tracking_profile4(
506 FROM_HERE_WITH_EXPLICIT_FUNCTION(
507 "455469 SafeBrowsingService::StartOnIOThread 4"));
508 DCHECK(!ping_manager_);
509 ping_manager_ = SafeBrowsingPingManager::Create(
510 url_request_context_getter, config);
513 void SafeBrowsingService::StopOnIOThread(bool shutdown) {
514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
516 #if defined(FULL_SAFE_BROWSING)
517 database_manager_->StopOnIOThread(shutdown);
518 #endif
519 ui_manager_->StopOnIOThread(shutdown);
521 if (enabled_) {
522 enabled_ = false;
524 #if defined(FULL_SAFE_BROWSING)
525 // This cancels all in-flight GetHash requests. Note that database_manager_
526 // relies on the protocol_manager_ so if the latter is destroyed, the
527 // former must be stopped.
528 delete protocol_manager_;
529 protocol_manager_ = NULL;
530 #endif
531 delete ping_manager_;
532 ping_manager_ = NULL;
536 void SafeBrowsingService::Start() {
537 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
539 BrowserThread::PostTask(
540 BrowserThread::IO, FROM_HERE,
541 base::Bind(&SafeBrowsingService::StartOnIOThread, this,
542 url_request_context_getter_));
545 void SafeBrowsingService::Stop(bool shutdown) {
546 BrowserThread::PostTask(
547 BrowserThread::IO, FROM_HERE,
548 base::Bind(&SafeBrowsingService::StopOnIOThread, this, shutdown));
551 void SafeBrowsingService::Observe(int type,
552 const content::NotificationSource& source,
553 const content::NotificationDetails& details) {
554 switch (type) {
555 case chrome::NOTIFICATION_PROFILE_CREATED: {
556 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
557 Profile* profile = content::Source<Profile>(source).ptr();
558 if (!profile->IsOffTheRecord())
559 AddPrefService(profile->GetPrefs());
560 break;
562 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
563 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
564 Profile* profile = content::Source<Profile>(source).ptr();
565 if (!profile->IsOffTheRecord())
566 RemovePrefService(profile->GetPrefs());
567 break;
569 default:
570 NOTREACHED();
574 void SafeBrowsingService::AddPrefService(PrefService* pref_service) {
575 DCHECK(prefs_map_.find(pref_service) == prefs_map_.end());
576 PrefChangeRegistrar* registrar = new PrefChangeRegistrar();
577 registrar->Init(pref_service);
578 registrar->Add(prefs::kSafeBrowsingEnabled,
579 base::Bind(&SafeBrowsingService::RefreshState,
580 base::Unretained(this)));
581 prefs_map_[pref_service] = registrar;
582 RefreshState();
585 void SafeBrowsingService::RemovePrefService(PrefService* pref_service) {
586 if (prefs_map_.find(pref_service) != prefs_map_.end()) {
587 delete prefs_map_[pref_service];
588 prefs_map_.erase(pref_service);
589 RefreshState();
590 } else {
591 NOTREACHED();
595 void SafeBrowsingService::RefreshState() {
596 // Check if any profile requires the service to be active.
597 bool enable = false;
598 std::map<PrefService*, PrefChangeRegistrar*>::iterator iter;
599 for (iter = prefs_map_.begin(); iter != prefs_map_.end(); ++iter) {
600 if (iter->first->GetBoolean(prefs::kSafeBrowsingEnabled)) {
601 enable = true;
602 break;
606 // TODO(asvitkine): Experimental code for measuring start up impact of SB.
607 // Remove when experimentation is complete. http://crbug.com/450037
608 if (!variations::GetVariationParamValue("LightSpeed", "DisableSB").empty())
609 enable = false;
611 if (enable)
612 Start();
613 else
614 Stop(false);
616 #if defined(FULL_SAFE_BROWSING)
617 if (csd_service_)
618 csd_service_->SetEnabledAndRefreshState(enable);
619 if (download_service_)
620 download_service_->SetEnabled(enable);
621 #endif