Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7537)

Unified Diff: chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc

Issue 2302913003: Add SafeBrowsingNavigationObserver to listen to navigation events (Closed)
Patch Set: address creis's comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1b3ee5311727d1e959ec940ee0add238d09f533c
--- /dev/null
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
@@ -0,0 +1,142 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
+#include "chrome/browser/sessions/session_tab_helper.h"
+#include "chrome/browser/tab_contents/retargeting_details.h"
+#include "content/public/browser/navigation_details.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+
+using content::WebContents;
+namespace safe_browsing {
+
+static const double kUserGestureTTLInSecond = 0.5;
+
+// static
+bool SafeBrowsingNavigationObserverManager::IsUserGestureExpired(
+ const base::Time& timestamp) {
+ double now = base::Time::Now().ToDoubleT();
+ double timestamp_in_double = timestamp.ToDoubleT();
+ return now > timestamp_in_double
+ ? now - timestamp_in_double > kUserGestureTTLInSecond
+ : true;
+}
+
+// static
+GURL SafeBrowsingNavigationObserverManager::ClearURLRef(const GURL& url) {
+ if (!url.has_ref())
+ return url;
+ url::Replacements<char> replacements;
+ replacements.ClearRef();
+ return url.ReplaceComponents(replacements);
+}
+
+SafeBrowsingNavigationObserverManager::SafeBrowsingNavigationObserverManager() {
+ registrar_.Add(this, chrome::NOTIFICATION_RETARGETING,
+ content::NotificationService::AllSources());
+}
+
+void SafeBrowsingNavigationObserverManager::RecordNavigationEvent(
+ const GURL& nav_event_key,
+ NavigationEvent* nav_event) {
+ auto insertion_result = navigation_map_.insert(
+ std::make_pair(nav_event_key, std::vector<NavigationEvent>()));
+
+ insertion_result.first->second.push_back(std::move(*nav_event));
+}
+
+void SafeBrowsingNavigationObserverManager::RecordUserGestureForWebContents(
+ content::WebContents* web_contents,
+ const base::Time& timestamp) {
+ auto insertion_result =
+ user_gesture_map_.insert(std::make_pair(web_contents, timestamp));
+ if (!insertion_result.second)
+ insertion_result.first->second = timestamp;
+}
+
+void SafeBrowsingNavigationObserverManager::OnUserGestureConsumed(
+ content::WebContents* web_contents,
+ const base::Time& timestamp) {
+ auto it = user_gesture_map_.find(web_contents);
+ if (it == user_gesture_map_.end())
+ return;
+ if (timestamp >= it->second)
+ user_gesture_map_.erase(web_contents);
+}
+
+void SafeBrowsingNavigationObserverManager::OnWebContentDestroyed(
+ content::WebContents* web_contents) {
+ user_gesture_map_.erase(web_contents);
+ // TODO (jialiul): Will add other clean up tasks shortly.
+}
+
+SafeBrowsingNavigationObserverManager::
+ ~SafeBrowsingNavigationObserverManager() {}
+
+void SafeBrowsingNavigationObserverManager::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ if (type == chrome::NOTIFICATION_RETARGETING)
+ RecordRetargeting(details);
+}
+
+void SafeBrowsingNavigationObserverManager::RecordRetargeting(
+ const content::NotificationDetails& details) {
+ const RetargetingDetails* retargeting_detail =
+ content::Details<const RetargetingDetails>(details).ptr();
+ DCHECK(retargeting_detail);
+ content::WebContents* source_contents =
+ retargeting_detail->source_web_contents;
+ content::WebContents* target_contents =
+ retargeting_detail->target_web_contents;
+ DCHECK(source_contents);
+ DCHECK(target_contents);
+
+ // TODO(jialiul): This line would break with OOPIFs due to
+ // https://crbug.com/649855.
+ content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
+ source_contents->GetRenderProcessHost()->GetID(),
+ retargeting_detail->source_render_frame_id);
+ const GURL& target_url = SafeBrowsingNavigationObserverManager::ClearURLRef(
+ retargeting_detail->target_url);
+
+ navigation_map_.insert(
+ std::make_pair(target_url, std::vector<NavigationEvent>()));
+
+ NavigationEvent nav_event;
+ nav_event.source_url =
+ rfh ? SafeBrowsingNavigationObserverManager::ClearURLRef(
+ rfh->GetLastCommittedURL())
+ : GURL();
+ nav_event.source_tab_id = SessionTabHelper::IdForTab(source_contents);
+ nav_event.target_url = target_url;
+ nav_event.target_tab_id = SessionTabHelper::IdForTab(target_contents);
+ nav_event.frame_id = rfh ? rfh->GetFrameTreeNodeId() : -1;
+ nav_event.main_frame_url = SafeBrowsingNavigationObserverManager::ClearURLRef(
+ source_contents->GetLastCommittedURL());
+ nav_event.timestamp = base::Time::Now();
+ auto it = user_gesture_map_.find(source_contents);
+ if (it != user_gesture_map_.end() &&
+ !SafeBrowsingNavigationObserverManager::IsUserGestureExpired(
+ it->second)) {
+ nav_event.is_user_initiated = true;
+ OnUserGestureConsumed(it->first, it->second);
+ } else {
+ nav_event.is_user_initiated = false;
+ }
+
+ navigation_map_[target_url].push_back(std::move(nav_event));
+}
+
+} // namespace safe_browsing

Powered by Google App Engine
This is Rietveld 408576698