Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / safe_browsing / safe_browsing_service.cc
blobc78ff0046b737782726e94dee3adcd69f47e9a8f
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 "content/public/browser/browser_thread.h"
41 #include "content/public/browser/cookie_store_factory.h"
42 #include "content/public/browser/notification_service.h"
43 #include "net/cookies/cookie_monster.h"
44 #include "net/extras/sqlite/cookie_crypto_delegate.h"
45 #include "net/url_request/url_request_context.h"
46 #include "net/url_request/url_request_context_getter.h"
48 #if defined(OS_WIN)
49 #include "chrome/installer/util/browser_distribution.h"
50 #endif
52 #if defined(SAFE_BROWSING_DB_LOCAL)
53 #include "chrome/browser/safe_browsing/local_database_manager.h"
54 #elif defined(SAFE_BROWSING_DB_REMOTE)
55 #include "chrome/browser/safe_browsing/remote_database_manager.h"
56 #endif
58 #if defined(FULL_SAFE_BROWSING)
59 #include "chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer.h"
60 #include "chrome/browser/safe_browsing/incident_reporting/blacklist_load_analyzer.h"
61 #include "chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.h"
62 #include "chrome/browser/safe_browsing/incident_reporting/off_domain_inclusion_detector.h"
63 #include "chrome/browser/safe_browsing/incident_reporting/resource_request_detector.h"
64 #include "chrome/browser/safe_browsing/incident_reporting/variations_seed_signature_analyzer.h"
65 #endif
67 using content::BrowserThread;
69 namespace {
71 // Filename suffix for the cookie database.
72 const base::FilePath::CharType kCookiesFile[] = FILE_PATH_LITERAL(" Cookies");
74 // The default URL prefix where browser fetches chunk updates, hashes,
75 // and reports safe browsing hits and malware details.
76 const char* const kSbDefaultURLPrefix =
77 "https://safebrowsing.google.com/safebrowsing";
79 // The backup URL prefix used when there are issues establishing a connection
80 // with the server at the primary URL.
81 const char* const kSbBackupConnectErrorURLPrefix =
82 "https://alt1-safebrowsing.google.com/safebrowsing";
84 // The backup URL prefix used when there are HTTP-specific issues with the
85 // server at the primary URL.
86 const char* const kSbBackupHttpErrorURLPrefix =
87 "https://alt2-safebrowsing.google.com/safebrowsing";
89 // The backup URL prefix used when there are local network specific issues.
90 const char* const kSbBackupNetworkErrorURLPrefix =
91 "https://alt3-safebrowsing.google.com/safebrowsing";
93 base::FilePath CookieFilePath() {
94 return base::FilePath(
95 SafeBrowsingService::GetBaseFilename().value() + kCookiesFile);
98 #if defined(FULL_SAFE_BROWSING)
99 // Returns true if the incident reporting service is enabled via a field trial.
100 bool IsIncidentReportingServiceEnabled() {
101 const std::string group_name = base::FieldTrialList::FindFullName(
102 "SafeBrowsingIncidentReportingService");
103 return group_name == "Enabled";
105 #endif // defined(FULL_SAFE_BROWSING)
107 } // namespace
109 class SafeBrowsingURLRequestContextGetter
110 : public net::URLRequestContextGetter {
111 public:
112 explicit SafeBrowsingURLRequestContextGetter(
113 SafeBrowsingService* sb_service_);
115 // Implementation for net::UrlRequestContextGetter.
116 net::URLRequestContext* GetURLRequestContext() override;
117 scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
118 const override;
120 // Shuts down any pending requests using the getter, and nulls out
121 // |sb_service_|.
122 void SafeBrowsingServiceShuttingDown();
124 protected:
125 ~SafeBrowsingURLRequestContextGetter() override;
127 private:
128 SafeBrowsingService* sb_service_; // Owned by BrowserProcess.
129 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
132 SafeBrowsingURLRequestContextGetter::SafeBrowsingURLRequestContextGetter(
133 SafeBrowsingService* sb_service)
134 : sb_service_(sb_service),
135 network_task_runner_(
136 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)) {
139 net::URLRequestContext*
140 SafeBrowsingURLRequestContextGetter::GetURLRequestContext() {
141 DCHECK_CURRENTLY_ON(BrowserThread::IO);
143 // Check if the service has been shut down.
144 if (!sb_service_)
145 return nullptr;
147 DCHECK(sb_service_->url_request_context_.get());
148 return sb_service_->url_request_context_.get();
151 scoped_refptr<base::SingleThreadTaskRunner>
152 SafeBrowsingURLRequestContextGetter::GetNetworkTaskRunner() const {
153 return network_task_runner_;
156 void SafeBrowsingURLRequestContextGetter::SafeBrowsingServiceShuttingDown() {
157 sb_service_ = nullptr;
158 URLRequestContextGetter::NotifyContextShuttingDown();
161 SafeBrowsingURLRequestContextGetter::~SafeBrowsingURLRequestContextGetter() {}
163 // static
164 SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL;
166 // The default SafeBrowsingServiceFactory. Global, made a singleton so we
167 // don't leak it.
168 class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory {
169 public:
170 SafeBrowsingService* CreateSafeBrowsingService() override {
171 return new SafeBrowsingService();
174 private:
175 friend struct base::DefaultLazyInstanceTraits<SafeBrowsingServiceFactoryImpl>;
177 SafeBrowsingServiceFactoryImpl() { }
179 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactoryImpl);
182 static base::LazyInstance<SafeBrowsingServiceFactoryImpl>::Leaky
183 g_safe_browsing_service_factory_impl = LAZY_INSTANCE_INITIALIZER;
185 // static
186 base::FilePath SafeBrowsingService::GetCookieFilePathForTesting() {
187 return CookieFilePath();
190 // static
191 base::FilePath SafeBrowsingService::GetBaseFilename() {
192 base::FilePath path;
193 bool result = PathService::Get(chrome::DIR_USER_DATA, &path);
194 DCHECK(result);
195 return path.Append(chrome::kSafeBrowsingBaseFilename);
199 // static
200 SafeBrowsingService* SafeBrowsingService::CreateSafeBrowsingService() {
201 if (!factory_)
202 factory_ = g_safe_browsing_service_factory_impl.Pointer();
203 return factory_->CreateSafeBrowsingService();
207 SafeBrowsingService::SafeBrowsingService()
208 : protocol_manager_(NULL),
209 ping_manager_(NULL),
210 enabled_(false),
211 enabled_by_prefs_(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 url_request_context_getter_ =
222 new SafeBrowsingURLRequestContextGetter(this);
224 ui_manager_ = CreateUIManager();
226 database_manager_ = CreateDatabaseManager();
228 BrowserThread::PostTask(
229 BrowserThread::IO, FROM_HERE,
230 base::Bind(
231 &SafeBrowsingService::InitURLRequestContextOnIOThread, this,
232 make_scoped_refptr(g_browser_process->system_request_context())));
234 #if defined(FULL_SAFE_BROWSING)
235 #if defined(SAFE_BROWSING_CSD)
236 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
237 switches::kDisableClientSidePhishingDetection)) {
238 csd_service_.reset(safe_browsing::ClientSideDetectionService::Create(
239 url_request_context_getter_.get()));
241 #endif // defined(SAFE_BROWSING_CSD)
243 // TODO(nparker): Adding SAFE_BROWSING_SERVICE_DOWNLOAD to control this might
244 // allow removing FULL_SAFE_BROWSING above.
245 #if !defined(OS_ANDROID)
246 download_service_.reset(new safe_browsing::DownloadProtectionService(
247 this, url_request_context_getter_.get()));
248 #endif
250 if (IsIncidentReportingServiceEnabled()) {
251 incident_service_.reset(new safe_browsing::IncidentReportingService(
252 this, url_request_context_getter_));
253 resource_request_detector_.reset(new safe_browsing::ResourceRequestDetector(
254 incident_service_->GetIncidentReceiver()));
257 off_domain_inclusion_detector_.reset(
258 new safe_browsing::OffDomainInclusionDetector(database_manager_));
259 #endif // !defined(FULL_SAFE_BROWSING)
261 // Track the safe browsing preference of existing profiles.
262 // The SafeBrowsingService will be started if any existing profile has the
263 // preference enabled. It will also listen for updates to the preferences.
264 ProfileManager* profile_manager = g_browser_process->profile_manager();
265 if (profile_manager) {
266 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
267 for (size_t i = 0; i < profiles.size(); ++i) {
268 if (profiles[i]->IsOffTheRecord())
269 continue;
270 AddPrefService(profiles[i]->GetPrefs());
274 // Track profile creation and destruction.
275 prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
276 content::NotificationService::AllSources());
277 prefs_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
278 content::NotificationService::AllSources());
280 #if defined(FULL_SAFE_BROWSING)
281 // Register all the delayed analysis to the incident reporting service.
282 RegisterAllDelayedAnalysis();
283 #endif
286 void SafeBrowsingService::ShutDown() {
287 // Deletes the PrefChangeRegistrars, whose dtors also unregister |this| as an
288 // observer of the preferences.
289 STLDeleteValues(&prefs_map_);
291 // Remove Profile creation/destruction observers.
292 prefs_registrar_.RemoveAll();
294 Stop(true);
295 // The IO thread is going away, so make sure the ClientSideDetectionService
296 // dtor executes now since it may call the dtor of URLFetcher which relies
297 // on it.
298 csd_service_.reset();
300 #if defined(FULL_SAFE_BROWSING)
301 off_domain_inclusion_detector_.reset();
302 resource_request_detector_.reset();
303 incident_service_.reset();
304 #endif
306 download_service_.reset();
308 BrowserThread::PostNonNestableTask(
309 BrowserThread::IO, FROM_HERE,
310 base::Bind(&SafeBrowsingService::DestroyURLRequestContextOnIOThread,
311 this, url_request_context_getter_));
313 // Release the URLRequestContextGetter after passing it to the IOThread. It
314 // has to be released now rather than in the destructor because it can only
315 // be deleted on the IOThread, and the SafeBrowsingService outlives the IO
316 // thread.
317 url_request_context_getter_ = nullptr;
320 // Binhash verification is only enabled for UMA users for now.
321 bool SafeBrowsingService::DownloadBinHashNeeded() const {
322 DCHECK_CURRENTLY_ON(BrowserThread::UI);
324 #if defined(FULL_SAFE_BROWSING)
325 return (database_manager_->download_protection_enabled() &&
326 ui_manager_->CanReportStats()) ||
327 (download_protection_service() &&
328 download_protection_service()->enabled());
329 #else
330 return false;
331 #endif
334 net::URLRequestContextGetter* SafeBrowsingService::url_request_context() {
335 DCHECK_CURRENTLY_ON(BrowserThread::UI);
336 return url_request_context_getter_.get();
339 const scoped_refptr<SafeBrowsingUIManager>&
340 SafeBrowsingService::ui_manager() const {
341 return ui_manager_;
344 const scoped_refptr<SafeBrowsingDatabaseManager>&
345 SafeBrowsingService::database_manager() const {
346 return database_manager_;
349 SafeBrowsingProtocolManager* SafeBrowsingService::protocol_manager() const {
350 DCHECK_CURRENTLY_ON(BrowserThread::IO);
351 return protocol_manager_;
354 SafeBrowsingPingManager* SafeBrowsingService::ping_manager() const {
355 DCHECK_CURRENTLY_ON(BrowserThread::IO);
356 return ping_manager_;
359 scoped_ptr<TrackedPreferenceValidationDelegate>
360 SafeBrowsingService::CreatePreferenceValidationDelegate(
361 Profile* profile) const {
362 #if defined(FULL_SAFE_BROWSING)
363 if (incident_service_)
364 return incident_service_->CreatePreferenceValidationDelegate(profile);
365 #endif
366 return scoped_ptr<TrackedPreferenceValidationDelegate>();
369 #if defined(FULL_SAFE_BROWSING)
370 void SafeBrowsingService::RegisterDelayedAnalysisCallback(
371 const safe_browsing::DelayedAnalysisCallback& callback) {
372 if (incident_service_)
373 incident_service_->RegisterDelayedAnalysisCallback(callback);
375 #endif
377 void SafeBrowsingService::AddDownloadManager(
378 content::DownloadManager* download_manager) {
379 #if defined(FULL_SAFE_BROWSING)
380 if (incident_service_)
381 incident_service_->AddDownloadManager(download_manager);
382 #endif
385 void SafeBrowsingService::OnResourceRequest(const net::URLRequest* request) {
386 #if defined(FULL_SAFE_BROWSING)
387 if (off_domain_inclusion_detector_)
388 off_domain_inclusion_detector_->OnResourceRequest(request);
389 if (resource_request_detector_)
390 resource_request_detector_->OnResourceRequest(request);
391 #endif
394 SafeBrowsingUIManager* SafeBrowsingService::CreateUIManager() {
395 return new SafeBrowsingUIManager(this);
398 SafeBrowsingDatabaseManager* SafeBrowsingService::CreateDatabaseManager() {
399 #if defined(SAFE_BROWSING_DB_LOCAL)
400 return new LocalSafeBrowsingDatabaseManager(this);
401 #elif defined(SAFE_BROWSING_DB_REMOTE)
402 return new RemoteSafeBrowsingDatabaseManager();
403 #else
404 return NULL;
405 #endif
408 void SafeBrowsingService::RegisterAllDelayedAnalysis() {
409 #if defined(FULL_SAFE_BROWSING)
410 safe_browsing::RegisterBinaryIntegrityAnalysis();
411 safe_browsing::RegisterBlacklistLoadAnalysis();
412 safe_browsing::RegisterVariationsSeedSignatureAnalysis();
413 #else
414 NOTREACHED();
415 #endif
418 void SafeBrowsingService::InitURLRequestContextOnIOThread(
419 net::URLRequestContextGetter* system_url_request_context_getter) {
420 DCHECK_CURRENTLY_ON(BrowserThread::IO);
421 DCHECK(!url_request_context_.get());
423 scoped_refptr<net::CookieStore> cookie_store(
424 content::CreateCookieStore(
425 content::CookieStoreConfig(
426 CookieFilePath(),
427 content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES,
428 NULL,
429 NULL)));
431 url_request_context_.reset(new net::URLRequestContext);
432 // |system_url_request_context_getter| may be NULL during tests.
433 if (system_url_request_context_getter) {
434 url_request_context_->CopyFrom(
435 system_url_request_context_getter->GetURLRequestContext());
437 url_request_context_->set_cookie_store(cookie_store.get());
440 void SafeBrowsingService::DestroyURLRequestContextOnIOThread(
441 scoped_refptr<SafeBrowsingURLRequestContextGetter> context_getter) {
442 DCHECK_CURRENTLY_ON(BrowserThread::IO);
444 context_getter->SafeBrowsingServiceShuttingDown();
445 url_request_context_.reset();
448 SafeBrowsingProtocolConfig SafeBrowsingService::GetProtocolConfig() const {
449 SafeBrowsingProtocolConfig config;
450 // On Windows, get the safe browsing client name from the browser
451 // distribution classes in installer util. These classes don't yet have
452 // an analog on non-Windows builds so just keep the name specified here.
453 #if defined(OS_WIN)
454 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
455 config.client_name = dist->GetSafeBrowsingName();
456 #else
457 #if defined(GOOGLE_CHROME_BUILD)
458 config.client_name = "googlechrome";
459 #else
460 config.client_name = "chromium";
461 #endif
463 // Mark client string to allow server to differentiate mobile.
464 #if defined(OS_ANDROID)
465 config.client_name.append("-a");
466 #elif defined(OS_IOS)
467 config.client_name.append("-i");
468 #endif
470 #endif // defined(OS_WIN)
471 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
472 config.disable_auto_update =
473 cmdline->HasSwitch(switches::kSbDisableAutoUpdate) ||
474 cmdline->HasSwitch(switches::kDisableBackgroundNetworking);
475 config.url_prefix = kSbDefaultURLPrefix;
476 config.backup_connect_error_url_prefix = kSbBackupConnectErrorURLPrefix;
477 config.backup_http_error_url_prefix = kSbBackupHttpErrorURLPrefix;
478 config.backup_network_error_url_prefix = kSbBackupNetworkErrorURLPrefix;
480 return config;
483 // Any tests that create a DatabaseManager that isn't derived from
484 // LocalSafeBrowsingDatabaseManager should override this to return NULL.
485 SafeBrowsingProtocolManagerDelegate*
486 SafeBrowsingService::GetProtocolManagerDelegate() {
487 #if defined(SAFE_BROWSING_DB_LOCAL)
488 return static_cast<LocalSafeBrowsingDatabaseManager*>(
489 database_manager_.get());
490 #else
491 NOTREACHED();
492 return NULL;
493 #endif
496 void SafeBrowsingService::StartOnIOThread(
497 net::URLRequestContextGetter* url_request_context_getter) {
498 DCHECK_CURRENTLY_ON(BrowserThread::IO);
499 if (enabled_)
500 return;
501 enabled_ = true;
503 SafeBrowsingProtocolConfig config = GetProtocolConfig();
505 #if defined(SAFE_BROWSING_DB_LOCAL) || defined(SAFE_BROWSING_DB_REMOTE)
506 DCHECK(database_manager_.get());
507 database_manager_->StartOnIOThread();
508 #endif
510 #if defined(SAFE_BROWSING_DB_LOCAL)
511 SafeBrowsingProtocolManagerDelegate* protocol_manager_delegate =
512 GetProtocolManagerDelegate();
513 if (protocol_manager_delegate) {
514 protocol_manager_ = SafeBrowsingProtocolManager::Create(
515 protocol_manager_delegate, url_request_context_getter, config);
516 protocol_manager_->Initialize();
518 #endif
520 DCHECK(!ping_manager_);
521 ping_manager_ = SafeBrowsingPingManager::Create(
522 url_request_context_getter, config);
525 void SafeBrowsingService::StopOnIOThread(bool shutdown) {
526 DCHECK_CURRENTLY_ON(BrowserThread::IO);
528 #if defined(SAFE_BROWSING_DB_LOCAL) || defined(SAFE_BROWSING_DB_REMOTE)
529 database_manager_->StopOnIOThread(shutdown);
530 #endif
531 ui_manager_->StopOnIOThread(shutdown);
533 if (enabled_) {
534 enabled_ = false;
536 #if defined(SAFE_BROWSING_DB_LOCAL)
537 // This cancels all in-flight GetHash requests. Note that database_manager_
538 // relies on the protocol_manager_ so if the latter is destroyed, the
539 // former must be stopped.
540 if (protocol_manager_) {
541 delete protocol_manager_;
542 protocol_manager_ = NULL;
544 #endif
545 delete ping_manager_;
546 ping_manager_ = NULL;
550 void SafeBrowsingService::Start() {
551 DCHECK_CURRENTLY_ON(BrowserThread::UI);
553 BrowserThread::PostTask(
554 BrowserThread::IO, FROM_HERE,
555 base::Bind(&SafeBrowsingService::StartOnIOThread, this,
556 url_request_context_getter_));
559 void SafeBrowsingService::Stop(bool shutdown) {
560 BrowserThread::PostTask(
561 BrowserThread::IO, FROM_HERE,
562 base::Bind(&SafeBrowsingService::StopOnIOThread, this, shutdown));
565 void SafeBrowsingService::Observe(int type,
566 const content::NotificationSource& source,
567 const content::NotificationDetails& details) {
568 switch (type) {
569 case chrome::NOTIFICATION_PROFILE_CREATED: {
570 DCHECK_CURRENTLY_ON(BrowserThread::UI);
571 Profile* profile = content::Source<Profile>(source).ptr();
572 if (!profile->IsOffTheRecord())
573 AddPrefService(profile->GetPrefs());
574 break;
576 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
577 DCHECK_CURRENTLY_ON(BrowserThread::UI);
578 Profile* profile = content::Source<Profile>(source).ptr();
579 if (!profile->IsOffTheRecord())
580 RemovePrefService(profile->GetPrefs());
581 break;
583 default:
584 NOTREACHED();
588 void SafeBrowsingService::AddPrefService(PrefService* pref_service) {
589 DCHECK(prefs_map_.find(pref_service) == prefs_map_.end());
590 PrefChangeRegistrar* registrar = new PrefChangeRegistrar();
591 registrar->Init(pref_service);
592 registrar->Add(prefs::kSafeBrowsingEnabled,
593 base::Bind(&SafeBrowsingService::RefreshState,
594 base::Unretained(this)));
595 // ClientSideDetectionService will need to be refresh the models
596 // renderers have if extended-reporting changes.
597 registrar->Add(prefs::kSafeBrowsingExtendedReportingEnabled,
598 base::Bind(&SafeBrowsingService::RefreshState,
599 base::Unretained(this)));
600 prefs_map_[pref_service] = registrar;
601 RefreshState();
604 void SafeBrowsingService::RemovePrefService(PrefService* pref_service) {
605 if (prefs_map_.find(pref_service) != prefs_map_.end()) {
606 delete prefs_map_[pref_service];
607 prefs_map_.erase(pref_service);
608 RefreshState();
609 } else {
610 NOTREACHED();
614 scoped_ptr<SafeBrowsingService::StateSubscription>
615 SafeBrowsingService::RegisterStateCallback(
616 const base::Callback<void(void)>& callback) {
617 DCHECK_CURRENTLY_ON(BrowserThread::UI);
618 return state_callback_list_.Add(callback);
621 void SafeBrowsingService::RefreshState() {
622 DCHECK_CURRENTLY_ON(BrowserThread::UI);
623 // Check if any profile requires the service to be active.
624 bool enable = false;
625 std::map<PrefService*, PrefChangeRegistrar*>::iterator iter;
626 for (iter = prefs_map_.begin(); iter != prefs_map_.end(); ++iter) {
627 if (iter->first->GetBoolean(prefs::kSafeBrowsingEnabled)) {
628 enable = true;
629 break;
633 enabled_by_prefs_ = enable;
635 if (enable)
636 Start();
637 else
638 Stop(false);
640 state_callback_list_.Notify();
642 #if defined(FULL_SAFE_BROWSING)
643 if (csd_service_)
644 csd_service_->SetEnabledAndRefreshState(enable);
645 if (download_service_)
646 download_service_->SetEnabled(enable);
647 #endif