OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/safe_browsing/client_side_detection_host.h" | 5 #include "chrome/browser/safe_browsing/client_side_detection_host.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 ClientSideDetectionService* csd_service, | 70 ClientSideDetectionService* csd_service, |
71 SafeBrowsingDatabaseManager* database_manager, | 71 SafeBrowsingDatabaseManager* database_manager, |
72 ClientSideDetectionHost* host) | 72 ClientSideDetectionHost* host) |
73 : params_(params), | 73 : params_(params), |
74 web_contents_(web_contents), | 74 web_contents_(web_contents), |
75 csd_service_(csd_service), | 75 csd_service_(csd_service), |
76 database_manager_(database_manager), | 76 database_manager_(database_manager), |
77 host_(host), | 77 host_(host), |
78 start_phishing_classification_cb_(start_phishing_classification), | 78 start_phishing_classification_cb_(start_phishing_classification), |
79 start_malware_classification_cb_(start_malware_classification) { | 79 start_malware_classification_cb_(start_malware_classification) { |
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 80 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
81 DCHECK(web_contents_); | 81 DCHECK(web_contents_); |
82 DCHECK(csd_service_); | 82 DCHECK(csd_service_); |
83 DCHECK(database_manager_.get()); | 83 DCHECK(database_manager_.get()); |
84 DCHECK(host_); | 84 DCHECK(host_); |
85 } | 85 } |
86 | 86 |
87 void Start() { | 87 void Start() { |
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 88 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
89 | 89 |
90 // We start by doing some simple checks that can run on the UI thread. | 90 // We start by doing some simple checks that can run on the UI thread. |
91 UMA_HISTOGRAM_BOOLEAN("SBClientPhishing.ClassificationStart", 1); | 91 UMA_HISTOGRAM_BOOLEAN("SBClientPhishing.ClassificationStart", 1); |
92 UMA_HISTOGRAM_BOOLEAN("SBClientMalware.ClassificationStart", 1); | 92 UMA_HISTOGRAM_BOOLEAN("SBClientMalware.ClassificationStart", 1); |
93 | 93 |
94 // Only classify [X]HTML documents. | 94 // Only classify [X]HTML documents. |
95 if (params_.contents_mime_type != "text/html" && | 95 if (params_.contents_mime_type != "text/html" && |
96 params_.contents_mime_type != "application/xhtml+xml") { | 96 params_.contents_mime_type != "application/xhtml+xml") { |
97 DVLOG(1) << "Skipping phishing classification for URL: " << params_.url | 97 DVLOG(1) << "Skipping phishing classification for URL: " << params_.url |
98 << " because it has an unsupported MIME type: " | 98 << " because it has an unsupported MIME type: " |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 NO_CLASSIFY_RESULT_FROM_CACHE, | 167 NO_CLASSIFY_RESULT_FROM_CACHE, |
168 NO_CLASSIFY_NOT_HTTP_URL, | 168 NO_CLASSIFY_NOT_HTTP_URL, |
169 | 169 |
170 NO_CLASSIFY_MAX // Always add new values before this one. | 170 NO_CLASSIFY_MAX // Always add new values before this one. |
171 }; | 171 }; |
172 | 172 |
173 // The destructor can be called either from the UI or the IO thread. | 173 // The destructor can be called either from the UI or the IO thread. |
174 virtual ~ShouldClassifyUrlRequest() { } | 174 virtual ~ShouldClassifyUrlRequest() { } |
175 | 175 |
176 bool ShouldClassifyForPhishing() const { | 176 bool ShouldClassifyForPhishing() const { |
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 177 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
178 return !start_phishing_classification_cb_.is_null(); | 178 return !start_phishing_classification_cb_.is_null(); |
179 } | 179 } |
180 | 180 |
181 bool ShouldClassifyForMalware() const { | 181 bool ShouldClassifyForMalware() const { |
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 182 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
183 return !start_malware_classification_cb_.is_null(); | 183 return !start_malware_classification_cb_.is_null(); |
184 } | 184 } |
185 | 185 |
186 void DontClassifyForPhishing(PreClassificationCheckFailures reason) { | 186 void DontClassifyForPhishing(PreClassificationCheckFailures reason) { |
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 187 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
188 if (ShouldClassifyForPhishing()) { | 188 if (ShouldClassifyForPhishing()) { |
189 // Track the first reason why we stopped classifying for phishing. | 189 // Track the first reason why we stopped classifying for phishing. |
190 UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.PreClassificationCheckFail", | 190 UMA_HISTOGRAM_ENUMERATION("SBClientPhishing.PreClassificationCheckFail", |
191 reason, NO_CLASSIFY_MAX); | 191 reason, NO_CLASSIFY_MAX); |
192 DVLOG(2) << "Failed phishing pre-classification checks. Reason: " | 192 DVLOG(2) << "Failed phishing pre-classification checks. Reason: " |
193 << reason; | 193 << reason; |
194 start_phishing_classification_cb_.Run(false); | 194 start_phishing_classification_cb_.Run(false); |
195 } | 195 } |
196 start_phishing_classification_cb_.Reset(); | 196 start_phishing_classification_cb_.Reset(); |
197 } | 197 } |
198 | 198 |
199 void DontClassifyForMalware(PreClassificationCheckFailures reason) { | 199 void DontClassifyForMalware(PreClassificationCheckFailures reason) { |
200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 200 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
201 if (ShouldClassifyForMalware()) { | 201 if (ShouldClassifyForMalware()) { |
202 // Track the first reason why we stopped classifying for malware. | 202 // Track the first reason why we stopped classifying for malware. |
203 UMA_HISTOGRAM_ENUMERATION("SBClientMalware.PreClassificationCheckFail", | 203 UMA_HISTOGRAM_ENUMERATION("SBClientMalware.PreClassificationCheckFail", |
204 reason, NO_CLASSIFY_MAX); | 204 reason, NO_CLASSIFY_MAX); |
205 DVLOG(2) << "Failed malware pre-classification checks. Reason: " | 205 DVLOG(2) << "Failed malware pre-classification checks. Reason: " |
206 << reason; | 206 << reason; |
207 start_malware_classification_cb_.Run(false); | 207 start_malware_classification_cb_.Run(false); |
208 } | 208 } |
209 start_malware_classification_cb_.Reset(); | 209 start_malware_classification_cb_.Reset(); |
210 } | 210 } |
211 | 211 |
212 void CheckSafeBrowsingDatabase(const GURL& url) { | 212 void CheckSafeBrowsingDatabase(const GURL& url) { |
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 213 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
214 // We don't want to call the classification callbacks from the IO | 214 // We don't want to call the classification callbacks from the IO |
215 // thread so we simply pass the results of this method to CheckCache() | 215 // thread so we simply pass the results of this method to CheckCache() |
216 // which is called on the UI thread; | 216 // which is called on the UI thread; |
217 PreClassificationCheckFailures phishing_reason = NO_CLASSIFY_MAX; | 217 PreClassificationCheckFailures phishing_reason = NO_CLASSIFY_MAX; |
218 PreClassificationCheckFailures malware_reason = NO_CLASSIFY_MAX; | 218 PreClassificationCheckFailures malware_reason = NO_CLASSIFY_MAX; |
219 if (!database_manager_.get()) { | 219 if (!database_manager_.get()) { |
220 // We cannot check the Safe Browsing whitelists so we stop here | 220 // We cannot check the Safe Browsing whitelists so we stop here |
221 // for safety. | 221 // for safety. |
222 malware_reason = phishing_reason = NO_CLASSIFY_NO_DATABASE_MANAGER; | 222 malware_reason = phishing_reason = NO_CLASSIFY_NO_DATABASE_MANAGER; |
223 } else { | 223 } else { |
(...skipping 10 matching lines...) Expand all Loading... |
234 BrowserThread::UI, | 234 BrowserThread::UI, |
235 FROM_HERE, | 235 FROM_HERE, |
236 base::Bind(&ShouldClassifyUrlRequest::CheckCache, | 236 base::Bind(&ShouldClassifyUrlRequest::CheckCache, |
237 this, | 237 this, |
238 phishing_reason, | 238 phishing_reason, |
239 malware_reason)); | 239 malware_reason)); |
240 } | 240 } |
241 | 241 |
242 void CheckCache(PreClassificationCheckFailures phishing_reason, | 242 void CheckCache(PreClassificationCheckFailures phishing_reason, |
243 PreClassificationCheckFailures malware_reason) { | 243 PreClassificationCheckFailures malware_reason) { |
244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 244 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
245 if (phishing_reason != NO_CLASSIFY_MAX) | 245 if (phishing_reason != NO_CLASSIFY_MAX) |
246 DontClassifyForPhishing(phishing_reason); | 246 DontClassifyForPhishing(phishing_reason); |
247 if (malware_reason != NO_CLASSIFY_MAX) | 247 if (malware_reason != NO_CLASSIFY_MAX) |
248 DontClassifyForMalware(malware_reason); | 248 DontClassifyForMalware(malware_reason); |
249 if (!ShouldClassifyForMalware() && !ShouldClassifyForPhishing()) { | 249 if (!ShouldClassifyForMalware() && !ShouldClassifyForPhishing()) { |
250 return; // No point in doing anything else. | 250 return; // No point in doing anything else. |
251 } | 251 } |
252 // If result is cached, we don't want to run classification again. | 252 // If result is cached, we don't want to run classification again. |
253 // In that case we're just trying to show the warning. | 253 // In that case we're just trying to show the warning. |
254 bool is_phishing; | 254 bool is_phishing; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 // Tell any pending classification request that it is being canceled. | 482 // Tell any pending classification request that it is being canceled. |
483 if (classification_request_.get()) { | 483 if (classification_request_.get()) { |
484 classification_request_->Cancel(); | 484 classification_request_->Cancel(); |
485 } | 485 } |
486 // Cancel all pending feature extractions. | 486 // Cancel all pending feature extractions. |
487 feature_extractor_.reset(); | 487 feature_extractor_.reset(); |
488 } | 488 } |
489 | 489 |
490 void ClientSideDetectionHost::OnPhishingPreClassificationDone( | 490 void ClientSideDetectionHost::OnPhishingPreClassificationDone( |
491 bool should_classify) { | 491 bool should_classify) { |
492 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 492 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
493 if (browse_info_.get() && should_classify) { | 493 if (browse_info_.get() && should_classify) { |
494 DVLOG(1) << "Instruct renderer to start phishing detection for URL: " | 494 DVLOG(1) << "Instruct renderer to start phishing detection for URL: " |
495 << browse_info_->url; | 495 << browse_info_->url; |
496 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); | 496 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); |
497 rvh->Send(new SafeBrowsingMsg_StartPhishingDetection( | 497 rvh->Send(new SafeBrowsingMsg_StartPhishingDetection( |
498 rvh->GetRoutingID(), browse_info_->url)); | 498 rvh->GetRoutingID(), browse_info_->url)); |
499 } | 499 } |
500 } | 500 } |
501 | 501 |
502 void ClientSideDetectionHost::OnMalwarePreClassificationDone( | 502 void ClientSideDetectionHost::OnMalwarePreClassificationDone( |
503 bool should_classify) { | 503 bool should_classify) { |
504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 504 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
505 // If classification checks failed we should stop extracting malware features. | 505 // If classification checks failed we should stop extracting malware features. |
506 DVLOG(2) << "Malware pre-classification checks done. Should classify: " | 506 DVLOG(2) << "Malware pre-classification checks done. Should classify: " |
507 << should_classify; | 507 << should_classify; |
508 should_extract_malware_features_ = should_classify; | 508 should_extract_malware_features_ = should_classify; |
509 should_classify_for_malware_ = should_classify; | 509 should_classify_for_malware_ = should_classify; |
510 MaybeStartMalwareFeatureExtraction(); | 510 MaybeStartMalwareFeatureExtraction(); |
511 } | 511 } |
512 | 512 |
513 void ClientSideDetectionHost::DidStopLoading() { | 513 void ClientSideDetectionHost::DidStopLoading() { |
514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 514 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
515 if (!csd_service_ || !browse_info_.get()) | 515 if (!csd_service_ || !browse_info_.get()) |
516 return; | 516 return; |
517 DVLOG(2) << "Page finished loading."; | 517 DVLOG(2) << "Page finished loading."; |
518 pageload_complete_ = true; | 518 pageload_complete_ = true; |
519 MaybeStartMalwareFeatureExtraction(); | 519 MaybeStartMalwareFeatureExtraction(); |
520 } | 520 } |
521 | 521 |
522 void ClientSideDetectionHost::MaybeStartMalwareFeatureExtraction() { | 522 void ClientSideDetectionHost::MaybeStartMalwareFeatureExtraction() { |
523 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 523 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
524 if (csd_service_ && browse_info_.get() && | 524 if (csd_service_ && browse_info_.get() && |
525 should_classify_for_malware_ && | 525 should_classify_for_malware_ && |
526 pageload_complete_) { | 526 pageload_complete_) { |
527 scoped_ptr<ClientMalwareRequest> malware_request( | 527 scoped_ptr<ClientMalwareRequest> malware_request( |
528 new ClientMalwareRequest); | 528 new ClientMalwareRequest); |
529 // Start browser-side malware feature extraction. Once we're done it will | 529 // Start browser-side malware feature extraction. Once we're done it will |
530 // send the malware client verdict request. | 530 // send the malware client verdict request. |
531 malware_request->set_url(browse_info_->url.spec()); | 531 malware_request->set_url(browse_info_->url.spec()); |
532 const GURL& referrer = browse_info_->referrer; | 532 const GURL& referrer = browse_info_->referrer; |
533 if (referrer.SchemeIs("http")) { // Only send http urls. | 533 if (referrer.SchemeIs("http")) { // Only send http urls. |
534 malware_request->set_referrer_url(referrer.spec()); | 534 malware_request->set_referrer_url(referrer.spec()); |
535 } | 535 } |
536 // This function doesn't expect browse_info_ to stay around after this | 536 // This function doesn't expect browse_info_ to stay around after this |
537 // function returns. | 537 // function returns. |
538 feature_extractor_->ExtractMalwareFeatures( | 538 feature_extractor_->ExtractMalwareFeatures( |
539 browse_info_.get(), | 539 browse_info_.get(), |
540 malware_request.release(), | 540 malware_request.release(), |
541 base::Bind(&ClientSideDetectionHost::MalwareFeatureExtractionDone, | 541 base::Bind(&ClientSideDetectionHost::MalwareFeatureExtractionDone, |
542 weak_factory_.GetWeakPtr())); | 542 weak_factory_.GetWeakPtr())); |
543 should_classify_for_malware_ = false; | 543 should_classify_for_malware_ = false; |
544 } | 544 } |
545 } | 545 } |
546 | 546 |
547 void ClientSideDetectionHost::OnPhishingDetectionDone( | 547 void ClientSideDetectionHost::OnPhishingDetectionDone( |
548 const std::string& verdict_str) { | 548 const std::string& verdict_str) { |
549 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 549 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
550 // There is something seriously wrong if there is no service class but | 550 // There is something seriously wrong if there is no service class but |
551 // this method is called. The renderer should not start phishing detection | 551 // this method is called. The renderer should not start phishing detection |
552 // if there isn't any service class in the browser. | 552 // if there isn't any service class in the browser. |
553 DCHECK(csd_service_); | 553 DCHECK(csd_service_); |
554 DCHECK(browse_info_.get()); | 554 DCHECK(browse_info_.get()); |
555 | 555 |
556 // We parse the protocol buffer here. If we're unable to parse it we won't | 556 // We parse the protocol buffer here. If we're unable to parse it we won't |
557 // send the verdict further. | 557 // send the verdict further. |
558 scoped_ptr<ClientPhishingRequest> verdict(new ClientPhishingRequest); | 558 scoped_ptr<ClientPhishingRequest> verdict(new ClientPhishingRequest); |
559 if (csd_service_ && | 559 if (csd_service_ && |
(...skipping 14 matching lines...) Expand all Loading... |
574 browse_info_.get(), | 574 browse_info_.get(), |
575 verdict.release(), | 575 verdict.release(), |
576 base::Bind(&ClientSideDetectionHost::FeatureExtractionDone, | 576 base::Bind(&ClientSideDetectionHost::FeatureExtractionDone, |
577 weak_factory_.GetWeakPtr())); | 577 weak_factory_.GetWeakPtr())); |
578 } | 578 } |
579 } | 579 } |
580 } | 580 } |
581 | 581 |
582 void ClientSideDetectionHost::MaybeShowPhishingWarning(GURL phishing_url, | 582 void ClientSideDetectionHost::MaybeShowPhishingWarning(GURL phishing_url, |
583 bool is_phishing) { | 583 bool is_phishing) { |
584 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 584 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
585 DVLOG(2) << "Received server phishing verdict for URL:" << phishing_url | 585 DVLOG(2) << "Received server phishing verdict for URL:" << phishing_url |
586 << " is_phishing:" << is_phishing; | 586 << " is_phishing:" << is_phishing; |
587 if (is_phishing) { | 587 if (is_phishing) { |
588 DCHECK(web_contents()); | 588 DCHECK(web_contents()); |
589 if (ui_manager_.get()) { | 589 if (ui_manager_.get()) { |
590 SafeBrowsingUIManager::UnsafeResource resource; | 590 SafeBrowsingUIManager::UnsafeResource resource; |
591 resource.url = phishing_url; | 591 resource.url = phishing_url; |
592 resource.original_url = phishing_url; | 592 resource.original_url = phishing_url; |
593 resource.is_subresource = false; | 593 resource.is_subresource = false; |
594 resource.threat_type = SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL; | 594 resource.threat_type = SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL; |
(...skipping 10 matching lines...) Expand all Loading... |
605 } | 605 } |
606 // If there is true phishing verdict, invalidate weakptr so that no longer | 606 // If there is true phishing verdict, invalidate weakptr so that no longer |
607 // consider the malware vedict. | 607 // consider the malware vedict. |
608 weak_factory_.InvalidateWeakPtrs(); | 608 weak_factory_.InvalidateWeakPtrs(); |
609 } | 609 } |
610 } | 610 } |
611 | 611 |
612 void ClientSideDetectionHost::MaybeShowMalwareWarning(GURL original_url, | 612 void ClientSideDetectionHost::MaybeShowMalwareWarning(GURL original_url, |
613 GURL malware_url, | 613 GURL malware_url, |
614 bool is_malware) { | 614 bool is_malware) { |
615 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 615 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
616 DVLOG(2) << "Received server malawre IP verdict for URL:" << malware_url | 616 DVLOG(2) << "Received server malawre IP verdict for URL:" << malware_url |
617 << " is_malware:" << is_malware; | 617 << " is_malware:" << is_malware; |
618 if (is_malware && malware_url.is_valid() && original_url.is_valid()) { | 618 if (is_malware && malware_url.is_valid() && original_url.is_valid()) { |
619 DCHECK(web_contents()); | 619 DCHECK(web_contents()); |
620 if (ui_manager_.get()) { | 620 if (ui_manager_.get()) { |
621 SafeBrowsingUIManager::UnsafeResource resource; | 621 SafeBrowsingUIManager::UnsafeResource resource; |
622 resource.url = malware_url; | 622 resource.url = malware_url; |
623 resource.original_url = original_url; | 623 resource.original_url = original_url; |
624 resource.is_subresource = (malware_url.host() != original_url.host()); | 624 resource.is_subresource = (malware_url.host() != original_url.host()); |
625 resource.threat_type = SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL; | 625 resource.threat_type = SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 } | 693 } |
694 } else if (it->second.size() < kMaxUrlsPerIP) { | 694 } else if (it->second.size() < kMaxUrlsPerIP) { |
695 it->second.push_back(IPUrlInfo(url, method, referrer, resource_type)); | 695 it->second.push_back(IPUrlInfo(url, method, referrer, resource_type)); |
696 } | 696 } |
697 } | 697 } |
698 | 698 |
699 void ClientSideDetectionHost::Observe( | 699 void ClientSideDetectionHost::Observe( |
700 int type, | 700 int type, |
701 const content::NotificationSource& source, | 701 const content::NotificationSource& source, |
702 const content::NotificationDetails& details) { | 702 const content::NotificationDetails& details) { |
703 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 703 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
704 DCHECK_EQ(type, content::NOTIFICATION_RESOURCE_RESPONSE_STARTED); | 704 DCHECK_EQ(type, content::NOTIFICATION_RESOURCE_RESPONSE_STARTED); |
705 const ResourceRequestDetails* req = content::Details<ResourceRequestDetails>( | 705 const ResourceRequestDetails* req = content::Details<ResourceRequestDetails>( |
706 details).ptr(); | 706 details).ptr(); |
707 if (req && browse_info_.get() && | 707 if (req && browse_info_.get() && |
708 should_extract_malware_features_ && req->url.is_valid()) { | 708 should_extract_malware_features_ && req->url.is_valid()) { |
709 UpdateIPUrlMap(req->socket_address.host() /* ip */, | 709 UpdateIPUrlMap(req->socket_address.host() /* ip */, |
710 req->url.spec() /* url */, | 710 req->url.spec() /* url */, |
711 req->method, | 711 req->method, |
712 req->referrer, | 712 req->referrer, |
713 req->resource_type); | 713 req->resource_type); |
(...skipping 21 matching lines...) Expand all Loading... |
735 ui_manager_->RemoveObserver(this); | 735 ui_manager_->RemoveObserver(this); |
736 | 736 |
737 ui_manager_ = ui_manager; | 737 ui_manager_ = ui_manager; |
738 if (ui_manager) | 738 if (ui_manager) |
739 ui_manager_->AddObserver(this); | 739 ui_manager_->AddObserver(this); |
740 | 740 |
741 database_manager_ = database_manager; | 741 database_manager_ = database_manager; |
742 } | 742 } |
743 | 743 |
744 } // namespace safe_browsing | 744 } // namespace safe_browsing |
OLD | NEW |