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"
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/profiles/profile.h"
25 #include "chrome/browser/profiles/profile_manager.h"
26 #include "chrome/browser/safe_browsing/client_side_detection_service.h"
27 #include "chrome/browser/safe_browsing/database_manager.h"
28 #include "chrome/browser/safe_browsing/download_protection_service.h"
29 #include "chrome/browser/safe_browsing/malware_details.h"
30 #include "chrome/browser/safe_browsing/ping_manager.h"
31 #include "chrome/browser/safe_browsing/protocol_manager.h"
32 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
33 #include "chrome/browser/safe_browsing/ui_manager.h"
34 #include "chrome/common/chrome_constants.h"
35 #include "chrome/common/chrome_paths.h"
36 #include "chrome/common/chrome_switches.h"
37 #include "chrome/common/pref_names.h"
38 #include "chrome/common/url_constants.h"
39 #include "components/user_prefs/tracked/tracked_preference_validation_delegate.h"
40 #include "components/variations/variations_associated_data.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"
50 #include "chrome/installer/util/browser_distribution.h"
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"
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"
68 using content::BrowserThread
;
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 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 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 kSbBackupHttpErrorURLPrefix
[] =
88 "https://alt2-safebrowsing.google.com/safebrowsing";
90 // The backup URL prefix used when there are local network specific issues.
91 const char 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 #if defined(SAFE_BROWSING_DB_REMOTE)
109 // Android field trial
110 const char kAndroidFieldExperiment
[] = "SafeBrowsingAndroid";
111 const char kAndroidFieldParam
[] = "enabled";
112 const char kAndroidFieldParamEnabledValue
[] = "true";
113 #endif // defined(SAFE_BROWSING_DB_REMOTE)
116 class SafeBrowsingURLRequestContextGetter
117 : public net::URLRequestContextGetter
{
119 explicit SafeBrowsingURLRequestContextGetter(
120 SafeBrowsingService
* sb_service_
);
122 // Implementation for net::UrlRequestContextGetter.
123 net::URLRequestContext
* GetURLRequestContext() override
;
124 scoped_refptr
<base::SingleThreadTaskRunner
> GetNetworkTaskRunner()
127 // Shuts down any pending requests using the getter, and nulls out
129 void SafeBrowsingServiceShuttingDown();
132 ~SafeBrowsingURLRequestContextGetter() override
;
135 SafeBrowsingService
* sb_service_
; // Owned by BrowserProcess.
136 scoped_refptr
<base::SingleThreadTaskRunner
> network_task_runner_
;
139 SafeBrowsingURLRequestContextGetter::SafeBrowsingURLRequestContextGetter(
140 SafeBrowsingService
* sb_service
)
141 : sb_service_(sb_service
),
142 network_task_runner_(
143 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
)) {
146 net::URLRequestContext
*
147 SafeBrowsingURLRequestContextGetter::GetURLRequestContext() {
148 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
150 // Check if the service has been shut down.
154 DCHECK(sb_service_
->url_request_context_
.get());
155 return sb_service_
->url_request_context_
.get();
158 scoped_refptr
<base::SingleThreadTaskRunner
>
159 SafeBrowsingURLRequestContextGetter::GetNetworkTaskRunner() const {
160 return network_task_runner_
;
163 void SafeBrowsingURLRequestContextGetter::SafeBrowsingServiceShuttingDown() {
164 sb_service_
= nullptr;
165 URLRequestContextGetter::NotifyContextShuttingDown();
168 SafeBrowsingURLRequestContextGetter::~SafeBrowsingURLRequestContextGetter() {}
171 SafeBrowsingServiceFactory
* SafeBrowsingService::factory_
= NULL
;
173 // The default SafeBrowsingServiceFactory. Global, made a singleton so we
175 class SafeBrowsingServiceFactoryImpl
: public SafeBrowsingServiceFactory
{
177 SafeBrowsingService
* CreateSafeBrowsingService() override
{
178 return new SafeBrowsingService();
182 friend struct base::DefaultLazyInstanceTraits
<SafeBrowsingServiceFactoryImpl
>;
184 SafeBrowsingServiceFactoryImpl() { }
186 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactoryImpl
);
189 static base::LazyInstance
<SafeBrowsingServiceFactoryImpl
>::Leaky
190 g_safe_browsing_service_factory_impl
= LAZY_INSTANCE_INITIALIZER
;
193 base::FilePath
SafeBrowsingService::GetCookieFilePathForTesting() {
194 return CookieFilePath();
198 base::FilePath
SafeBrowsingService::GetBaseFilename() {
200 bool result
= PathService::Get(chrome::DIR_USER_DATA
, &path
);
202 return path
.Append(chrome::kSafeBrowsingBaseFilename
);
207 SafeBrowsingService
* SafeBrowsingService::CreateSafeBrowsingService() {
209 factory_
= g_safe_browsing_service_factory_impl
.Pointer();
210 return factory_
->CreateSafeBrowsingService();
213 SafeBrowsingService::SafeBrowsingService()
214 : protocol_manager_(NULL
),
217 enabled_by_prefs_(false) {
218 #if defined(SAFE_BROWSING_DB_REMOTE)
219 const std::string enabled_param
= variations::GetVariationParamValue(
220 kAndroidFieldExperiment
, kAndroidFieldParam
);
221 is_android_field_trial_enabled_
=
222 (enabled_param
== kAndroidFieldParamEnabledValue
);
223 #endif // defined(SAFE_BROWSING_DB_REMOTE)
226 SafeBrowsingService::~SafeBrowsingService() {
227 // We should have already been shut down. If we're still enabled, then the
228 // database isn't going to be closed properly, which could lead to corruption.
232 void SafeBrowsingService::Initialize() {
233 url_request_context_getter_
=
234 new SafeBrowsingURLRequestContextGetter(this);
236 ui_manager_
= CreateUIManager();
238 database_manager_
= CreateDatabaseManager();
240 BrowserThread::PostTask(
241 BrowserThread::IO
, FROM_HERE
,
243 &SafeBrowsingService::InitURLRequestContextOnIOThread
, this,
244 make_scoped_refptr(g_browser_process
->system_request_context())));
246 #if defined(FULL_SAFE_BROWSING)
247 #if defined(SAFE_BROWSING_CSD)
248 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
249 switches::kDisableClientSidePhishingDetection
)) {
250 csd_service_
.reset(safe_browsing::ClientSideDetectionService::Create(
251 url_request_context_getter_
.get()));
253 #endif // defined(SAFE_BROWSING_CSD)
255 // TODO(nparker): Adding SAFE_BROWSING_SERVICE_DOWNLOAD to control this might
256 // allow removing FULL_SAFE_BROWSING above.
257 #if !defined(OS_ANDROID)
258 download_service_
.reset(new safe_browsing::DownloadProtectionService(
259 this, url_request_context_getter_
.get()));
262 if (IsIncidentReportingServiceEnabled()) {
263 incident_service_
.reset(new safe_browsing::IncidentReportingService(
264 this, url_request_context_getter_
));
265 resource_request_detector_
.reset(new safe_browsing::ResourceRequestDetector(
266 incident_service_
->GetIncidentReceiver()));
269 off_domain_inclusion_detector_
.reset(
270 new safe_browsing::OffDomainInclusionDetector(database_manager_
));
271 #endif // !defined(FULL_SAFE_BROWSING)
273 // Track the safe browsing preference of existing profiles.
274 // The SafeBrowsingService will be started if any existing profile has the
275 // preference enabled. It will also listen for updates to the preferences.
276 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
277 if (profile_manager
) {
278 std::vector
<Profile
*> profiles
= profile_manager
->GetLoadedProfiles();
279 for (size_t i
= 0; i
< profiles
.size(); ++i
) {
280 if (profiles
[i
]->IsOffTheRecord())
282 AddPrefService(profiles
[i
]->GetPrefs());
286 // Track profile creation and destruction.
287 prefs_registrar_
.Add(this, chrome::NOTIFICATION_PROFILE_CREATED
,
288 content::NotificationService::AllSources());
289 prefs_registrar_
.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED
,
290 content::NotificationService::AllSources());
292 #if defined(FULL_SAFE_BROWSING)
293 // Register all the delayed analysis to the incident reporting service.
294 RegisterAllDelayedAnalysis();
298 void SafeBrowsingService::ShutDown() {
299 // Deletes the PrefChangeRegistrars, whose dtors also unregister |this| as an
300 // observer of the preferences.
301 STLDeleteValues(&prefs_map_
);
303 // Remove Profile creation/destruction observers.
304 prefs_registrar_
.RemoveAll();
307 // The IO thread is going away, so make sure the ClientSideDetectionService
308 // dtor executes now since it may call the dtor of URLFetcher which relies
310 csd_service_
.reset();
312 #if defined(FULL_SAFE_BROWSING)
313 off_domain_inclusion_detector_
.reset();
314 resource_request_detector_
.reset();
315 incident_service_
.reset();
318 download_service_
.reset();
320 BrowserThread::PostNonNestableTask(
321 BrowserThread::IO
, FROM_HERE
,
322 base::Bind(&SafeBrowsingService::DestroyURLRequestContextOnIOThread
,
323 this, url_request_context_getter_
));
325 // Release the URLRequestContextGetter after passing it to the IOThread. It
326 // has to be released now rather than in the destructor because it can only
327 // be deleted on the IOThread, and the SafeBrowsingService outlives the IO
329 url_request_context_getter_
= nullptr;
332 // Binhash verification is only enabled for UMA users for now.
333 bool SafeBrowsingService::DownloadBinHashNeeded() const {
334 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
336 #if defined(FULL_SAFE_BROWSING)
337 return (database_manager_
->download_protection_enabled() &&
338 ui_manager_
->CanReportStats()) ||
339 (download_protection_service() &&
340 download_protection_service()->enabled());
346 net::URLRequestContextGetter
* SafeBrowsingService::url_request_context() {
347 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
348 return url_request_context_getter_
.get();
351 const scoped_refptr
<SafeBrowsingUIManager
>&
352 SafeBrowsingService::ui_manager() const {
356 const scoped_refptr
<SafeBrowsingDatabaseManager
>&
357 SafeBrowsingService::database_manager() const {
358 return database_manager_
;
361 SafeBrowsingProtocolManager
* SafeBrowsingService::protocol_manager() const {
362 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
363 return protocol_manager_
;
366 SafeBrowsingPingManager
* SafeBrowsingService::ping_manager() const {
367 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
368 return ping_manager_
;
371 scoped_ptr
<TrackedPreferenceValidationDelegate
>
372 SafeBrowsingService::CreatePreferenceValidationDelegate(
373 Profile
* profile
) const {
374 #if defined(FULL_SAFE_BROWSING)
375 if (incident_service_
)
376 return incident_service_
->CreatePreferenceValidationDelegate(profile
);
378 return scoped_ptr
<TrackedPreferenceValidationDelegate
>();
381 #if defined(FULL_SAFE_BROWSING)
382 void SafeBrowsingService::RegisterDelayedAnalysisCallback(
383 const safe_browsing::DelayedAnalysisCallback
& callback
) {
384 if (incident_service_
)
385 incident_service_
->RegisterDelayedAnalysisCallback(callback
);
389 void SafeBrowsingService::AddDownloadManager(
390 content::DownloadManager
* download_manager
) {
391 #if defined(FULL_SAFE_BROWSING)
392 if (incident_service_
)
393 incident_service_
->AddDownloadManager(download_manager
);
397 void SafeBrowsingService::OnResourceRequest(const net::URLRequest
* request
) {
398 #if defined(FULL_SAFE_BROWSING)
399 if (off_domain_inclusion_detector_
)
400 off_domain_inclusion_detector_
->OnResourceRequest(request
);
401 if (resource_request_detector_
)
402 resource_request_detector_
->OnResourceRequest(request
);
406 SafeBrowsingUIManager
* SafeBrowsingService::CreateUIManager() {
407 return new SafeBrowsingUIManager(this);
410 SafeBrowsingDatabaseManager
* SafeBrowsingService::CreateDatabaseManager() {
411 #if defined(SAFE_BROWSING_DB_LOCAL)
412 return new LocalSafeBrowsingDatabaseManager(this);
413 #elif defined(SAFE_BROWSING_DB_REMOTE)
414 return new RemoteSafeBrowsingDatabaseManager();
420 void SafeBrowsingService::RegisterAllDelayedAnalysis() {
421 #if defined(FULL_SAFE_BROWSING)
422 safe_browsing::RegisterBinaryIntegrityAnalysis();
423 safe_browsing::RegisterBlacklistLoadAnalysis();
424 safe_browsing::RegisterVariationsSeedSignatureAnalysis();
430 void SafeBrowsingService::InitURLRequestContextOnIOThread(
431 net::URLRequestContextGetter
* system_url_request_context_getter
) {
432 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
433 DCHECK(!url_request_context_
.get());
435 scoped_refptr
<net::CookieStore
> cookie_store(
436 content::CreateCookieStore(
437 content::CookieStoreConfig(
439 content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES
,
443 url_request_context_
.reset(new net::URLRequestContext
);
444 // |system_url_request_context_getter| may be NULL during tests.
445 if (system_url_request_context_getter
) {
446 url_request_context_
->CopyFrom(
447 system_url_request_context_getter
->GetURLRequestContext());
449 url_request_context_
->set_cookie_store(cookie_store
.get());
452 void SafeBrowsingService::DestroyURLRequestContextOnIOThread(
453 scoped_refptr
<SafeBrowsingURLRequestContextGetter
> context_getter
) {
454 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
456 context_getter
->SafeBrowsingServiceShuttingDown();
457 url_request_context_
.reset();
460 SafeBrowsingProtocolConfig
SafeBrowsingService::GetProtocolConfig() const {
461 SafeBrowsingProtocolConfig config
;
462 // On Windows, get the safe browsing client name from the browser
463 // distribution classes in installer util. These classes don't yet have
464 // an analog on non-Windows builds so just keep the name specified here.
466 BrowserDistribution
* dist
= BrowserDistribution::GetDistribution();
467 config
.client_name
= dist
->GetSafeBrowsingName();
469 #if defined(GOOGLE_CHROME_BUILD)
470 config
.client_name
= "googlechrome";
472 config
.client_name
= "chromium";
475 // Mark client string to allow server to differentiate mobile.
476 #if defined(OS_ANDROID)
477 config
.client_name
.append("-a");
478 #elif defined(OS_IOS)
479 config
.client_name
.append("-i");
482 #endif // defined(OS_WIN)
483 base::CommandLine
* cmdline
= base::CommandLine::ForCurrentProcess();
484 config
.disable_auto_update
=
485 cmdline
->HasSwitch(switches::kSbDisableAutoUpdate
) ||
486 cmdline
->HasSwitch(switches::kDisableBackgroundNetworking
);
487 config
.url_prefix
= kSbDefaultURLPrefix
;
488 config
.backup_connect_error_url_prefix
= kSbBackupConnectErrorURLPrefix
;
489 config
.backup_http_error_url_prefix
= kSbBackupHttpErrorURLPrefix
;
490 config
.backup_network_error_url_prefix
= kSbBackupNetworkErrorURLPrefix
;
495 // Any tests that create a DatabaseManager that isn't derived from
496 // LocalSafeBrowsingDatabaseManager should override this to return NULL.
497 SafeBrowsingProtocolManagerDelegate
*
498 SafeBrowsingService::GetProtocolManagerDelegate() {
499 #if defined(SAFE_BROWSING_DB_LOCAL)
500 return static_cast<LocalSafeBrowsingDatabaseManager
*>(
501 database_manager_
.get());
508 void SafeBrowsingService::StartOnIOThread(
509 net::URLRequestContextGetter
* url_request_context_getter
) {
510 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
515 SafeBrowsingProtocolConfig config
= GetProtocolConfig();
517 #if defined(SAFE_BROWSING_DB_LOCAL) || defined(SAFE_BROWSING_DB_REMOTE)
518 DCHECK(database_manager_
.get());
519 database_manager_
->StartOnIOThread();
522 #if defined(SAFE_BROWSING_DB_LOCAL)
523 SafeBrowsingProtocolManagerDelegate
* protocol_manager_delegate
=
524 GetProtocolManagerDelegate();
525 if (protocol_manager_delegate
) {
526 protocol_manager_
= SafeBrowsingProtocolManager::Create(
527 protocol_manager_delegate
, url_request_context_getter
, config
);
528 protocol_manager_
->Initialize();
532 DCHECK(!ping_manager_
);
533 ping_manager_
= SafeBrowsingPingManager::Create(
534 url_request_context_getter
, config
);
537 void SafeBrowsingService::StopOnIOThread(bool shutdown
) {
538 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
540 #if defined(SAFE_BROWSING_DB_LOCAL) || defined(SAFE_BROWSING_DB_REMOTE)
541 database_manager_
->StopOnIOThread(shutdown
);
543 ui_manager_
->StopOnIOThread(shutdown
);
548 #if defined(SAFE_BROWSING_DB_LOCAL)
549 // This cancels all in-flight GetHash requests. Note that database_manager_
550 // relies on the protocol_manager_ so if the latter is destroyed, the
551 // former must be stopped.
552 if (protocol_manager_
) {
553 delete protocol_manager_
;
554 protocol_manager_
= NULL
;
557 delete ping_manager_
;
558 ping_manager_
= NULL
;
562 void SafeBrowsingService::Start() {
563 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
565 BrowserThread::PostTask(
566 BrowserThread::IO
, FROM_HERE
,
567 base::Bind(&SafeBrowsingService::StartOnIOThread
, this,
568 url_request_context_getter_
));
571 void SafeBrowsingService::Stop(bool shutdown
) {
572 BrowserThread::PostTask(
573 BrowserThread::IO
, FROM_HERE
,
574 base::Bind(&SafeBrowsingService::StopOnIOThread
, this, shutdown
));
577 void SafeBrowsingService::Observe(int type
,
578 const content::NotificationSource
& source
,
579 const content::NotificationDetails
& details
) {
581 case chrome::NOTIFICATION_PROFILE_CREATED
: {
582 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
583 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
584 if (!profile
->IsOffTheRecord())
585 AddPrefService(profile
->GetPrefs());
588 case chrome::NOTIFICATION_PROFILE_DESTROYED
: {
589 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
590 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
591 if (!profile
->IsOffTheRecord())
592 RemovePrefService(profile
->GetPrefs());
600 void SafeBrowsingService::AddPrefService(PrefService
* pref_service
) {
601 DCHECK(prefs_map_
.find(pref_service
) == prefs_map_
.end());
602 PrefChangeRegistrar
* registrar
= new PrefChangeRegistrar();
603 registrar
->Init(pref_service
);
604 registrar
->Add(prefs::kSafeBrowsingEnabled
,
605 base::Bind(&SafeBrowsingService::RefreshState
,
606 base::Unretained(this)));
607 // ClientSideDetectionService will need to be refresh the models
608 // renderers have if extended-reporting changes.
609 registrar
->Add(prefs::kSafeBrowsingExtendedReportingEnabled
,
610 base::Bind(&SafeBrowsingService::RefreshState
,
611 base::Unretained(this)));
612 prefs_map_
[pref_service
] = registrar
;
616 void SafeBrowsingService::RemovePrefService(PrefService
* pref_service
) {
617 if (prefs_map_
.find(pref_service
) != prefs_map_
.end()) {
618 delete prefs_map_
[pref_service
];
619 prefs_map_
.erase(pref_service
);
626 scoped_ptr
<SafeBrowsingService::StateSubscription
>
627 SafeBrowsingService::RegisterStateCallback(
628 const base::Callback
<void(void)>& callback
) {
629 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
630 return state_callback_list_
.Add(callback
);
633 void SafeBrowsingService::RefreshState() {
634 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
635 // Check if any profile requires the service to be active.
637 std::map
<PrefService
*, PrefChangeRegistrar
*>::iterator iter
;
638 for (iter
= prefs_map_
.begin(); iter
!= prefs_map_
.end(); ++iter
) {
639 if (iter
->first
->GetBoolean(prefs::kSafeBrowsingEnabled
)) {
645 enabled_by_prefs_
= enable
;
652 state_callback_list_
.Notify();
654 #if defined(FULL_SAFE_BROWSING)
656 csd_service_
->SetEnabledAndRefreshState(enable
);
657 if (download_service_
)
658 download_service_
->SetEnabled(enable
);