Index: chrome/renderer/safe_browsing/phishing_classifier_delegate.cc |
=================================================================== |
--- chrome/renderer/safe_browsing/phishing_classifier_delegate.cc (revision 73993) |
+++ chrome/renderer/safe_browsing/phishing_classifier_delegate.cc (working copy) |
@@ -4,38 +4,101 @@ |
#include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" |
+#include <set> |
+ |
#include "base/callback.h" |
+#include "base/lazy_instance.h" |
#include "base/logging.h" |
+#include "base/scoped_callback_factory.h" |
#include "chrome/common/render_messages.h" |
#include "chrome/renderer/navigation_state.h" |
+#include "chrome/renderer/render_thread.h" |
#include "chrome/renderer/render_view.h" |
#include "chrome/renderer/safe_browsing/feature_extractor_clock.h" |
#include "chrome/renderer/safe_browsing/phishing_classifier.h" |
+#include "chrome/renderer/safe_browsing/scorer.h" |
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" |
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
namespace safe_browsing { |
+typedef std::set<PhishingClassifierDelegate*> PhishingClassifierDelegates; |
+static base::LazyInstance<PhishingClassifierDelegates> |
+ g_delegates(base::LINKER_INITIALIZED); |
+ |
+static base::LazyInstance<scoped_ptr<const safe_browsing::Scorer> > |
+ g_phishing_scorer(base::LINKER_INITIALIZED); |
+ |
+class ScorerCallback { |
+ public: |
+ static Scorer::CreationCallback* CreateCallback() { |
+ ScorerCallback* scorer_callback = new ScorerCallback(); |
+ return scorer_callback->callback_factory_->NewCallback( |
+ &ScorerCallback::PhishingScorerCreated); |
+ } |
+ |
+ private: |
+ ScorerCallback() { |
+ callback_factory_.reset( |
+ new base::ScopedCallbackFactory<ScorerCallback>(this)); |
+ } |
+ |
+ // Callback to be run once the phishing Scorer has been created. |
+ void PhishingScorerCreated(safe_browsing::Scorer* scorer) { |
+ if (!scorer) { |
+ DLOG(ERROR) << "Unable to create a PhishingScorer - corrupt model?"; |
+ return; |
+ } |
+ |
+ g_phishing_scorer.Get().reset(scorer); |
+ |
+ PhishingClassifierDelegates::iterator i; |
+ for (i = g_delegates.Get().begin(); i != g_delegates.Get().end(); ++i) |
+ (*i)->SetPhishingScorer(scorer); |
+ |
+ delete this; |
+ } |
+ |
+ scoped_ptr<base::ScopedCallbackFactory<ScorerCallback> > callback_factory_; |
+}; |
+ |
+void PhishingClassifierDelegate::SetPhishingModel( |
+ IPC::PlatformFileForTransit model_file) { |
+ safe_browsing::Scorer::CreateFromFile( |
+ IPC::PlatformFileForTransitToPlatformFile(model_file), |
+ RenderThread::current()->GetFileThreadMessageLoopProxy(), |
+ ScorerCallback::CreateCallback()); |
+} |
+ |
PhishingClassifierDelegate::PhishingClassifierDelegate( |
RenderView* render_view, |
PhishingClassifier* classifier) |
- : render_view_(render_view), |
+ : RenderViewObserver(render_view), |
last_page_id_sent_to_classifier_(-1), |
pending_classification_(false) { |
+ g_delegates.Get().insert(this); |
if (!classifier) { |
- classifier = new PhishingClassifier(render_view_, |
+ classifier = new PhishingClassifier(render_view, |
new FeatureExtractorClock()); |
} |
+ |
classifier_.reset(classifier); |
+ |
+ if (g_phishing_scorer.Get().get()) |
+ SetPhishingScorer(g_phishing_scorer.Get().get()); |
} |
PhishingClassifierDelegate::~PhishingClassifierDelegate() { |
CancelPendingClassification(); |
+ g_delegates.Get().erase(this); |
} |
void PhishingClassifierDelegate::SetPhishingScorer( |
const safe_browsing::Scorer* scorer) { |
+ if (!render_view()->webview()) |
+ return; // RenderView is tearing down. |
+ |
classifier_->set_phishing_scorer(scorer); |
if (pending_classification_) { |
@@ -45,15 +108,18 @@ |
// classification. This is because we stop any pending classification on |
// main frame loads in RenderView::didCommitProvisionalLoad(). |
DCHECK_EQ(StripToplevelUrl(), last_url_sent_to_classifier_); |
- DCHECK_EQ(render_view_->page_id(), last_page_id_sent_to_classifier_); |
+ DCHECK_EQ(render_view()->page_id(), last_page_id_sent_to_classifier_); |
classifier_->BeginClassification( |
&classifier_page_text_, |
NewCallback(this, &PhishingClassifierDelegate::ClassificationDone)); |
} |
} |
-void PhishingClassifierDelegate::CommittedLoadInFrame( |
- WebKit::WebFrame* frame) { |
+void PhishingClassifierDelegate::DidCommitProvisionalLoad( |
+ WebKit::WebFrame* frame, bool is_new_navigation) { |
+ if (!is_new_navigation) |
+ return; |
+ |
// A new page is starting to load. Unless the load is a navigation within |
// the same page, we need to cancel classification since the content will |
// now be inconsistent with the phishing model. |
@@ -64,12 +130,12 @@ |
} |
} |
-void PhishingClassifierDelegate::FinishedLoad(string16* page_text) { |
+void PhishingClassifierDelegate::PageCaptured(const string16& page_text) { |
// We check that the page id has incremented so that we don't reclassify |
// pages as the user moves back and forward in session history. Note: we |
// don't send every page id to the classifier, only those where the toplevel |
// URL changed. |
- int load_id = render_view_->page_id(); |
+ int load_id = render_view()->page_id(); |
if (load_id <= last_page_id_sent_to_classifier_) { |
return; |
} |
@@ -84,7 +150,7 @@ |
last_url_sent_to_classifier_ = url_without_ref; |
last_page_id_sent_to_classifier_ = load_id; |
- classifier_page_text_.swap(*page_text); |
+ classifier_page_text_ = page_text; |
if (classifier_->is_ready()) { |
classifier_->BeginClassification( |
@@ -105,6 +171,18 @@ |
pending_classification_ = false; |
} |
+bool PhishingClassifierDelegate::OnMessageReceived( |
+ const IPC::Message& message) { |
+ /* |
+ bool handled = true; |
+ IPC_BEGIN_MESSAGE_MAP(PhishingClassifierDelegate, message) |
+ IPC_MESSAGE_UNHANDLED(handled = false) |
+ IPC_END_MESSAGE_MAP() |
+ return handled; |
+ */ |
+ return false; |
+} |
+ |
void PhishingClassifierDelegate::ClassificationDone(bool is_phishy, |
double phishy_score) { |
// We no longer need the page text. |
@@ -114,14 +192,14 @@ |
return; |
} |
- render_view_->Send(new ViewHostMsg_DetectedPhishingSite( |
- render_view_->routing_id(), |
+ render_view()->Send(new ViewHostMsg_DetectedPhishingSite( |
+ render_view()->routing_id(), |
last_url_sent_to_classifier_, |
phishy_score)); |
} |
GURL PhishingClassifierDelegate::StripToplevelUrl() { |
- GURL toplevel_url = render_view_->webview()->mainFrame()->url(); |
+ GURL toplevel_url = render_view()->webview()->mainFrame()->url(); |
GURL::Replacements replacements; |
replacements.ClearRef(); |
return toplevel_url.ReplaceComponents(replacements); |