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

Side by Side Diff: chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc

Issue 2302913003: Add SafeBrowsingNavigationObserver to listen to navigation events (Closed)
Patch Set: resolve final nit Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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.
4
5 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager .h"
6
7 #include "base/memory/ptr_util.h"
8 #include "base/time/time.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
11 #include "chrome/browser/sessions/session_tab_helper.h"
12 #include "chrome/browser/tab_contents/retargeting_details.h"
13 #include "content/public/browser/navigation_details.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/notification_types.h"
16 #include "content/public/browser/render_frame_host.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/web_contents.h"
19
20 using content::WebContents;
21
22 namespace safe_browsing {
23
24 // The expiration period of a user gesture. Any user gesture that happened 1.0
25 // second ago will be considered as expired and not relevant to upcoming
26 // navigation events.
27 static const double kUserGestureTTLInSecond = 1.0;
28
29 // static
30 bool SafeBrowsingNavigationObserverManager::IsUserGestureExpired(
31 const base::Time& timestamp) {
32 double now = base::Time::Now().ToDoubleT();
33 double timestamp_in_double = timestamp.ToDoubleT();
34
35 if (now <= timestamp_in_double)
36 return true;
37 return (now - timestamp_in_double) > kUserGestureTTLInSecond;
38 }
39
40 // static
41 GURL SafeBrowsingNavigationObserverManager::ClearEmptyRef(const GURL& url) {
42 if (url.has_ref() && url.ref().empty()) {
43 url::Replacements<char> replacements;
44 replacements.ClearRef();
45 return url.ReplaceComponents(replacements);
46 }
47 return url;
48 }
49
50 SafeBrowsingNavigationObserverManager::SafeBrowsingNavigationObserverManager() {
51 registrar_.Add(this, chrome::NOTIFICATION_RETARGETING,
52 content::NotificationService::AllSources());
53 }
54
55 void SafeBrowsingNavigationObserverManager::RecordNavigationEvent(
56 const GURL& nav_event_key,
57 NavigationEvent* nav_event) {
58 auto insertion_result = navigation_map_.insert(
59 std::make_pair(nav_event_key, std::vector<NavigationEvent>()));
60
61 insertion_result.first->second.push_back(std::move(*nav_event));
62 }
63
64 void SafeBrowsingNavigationObserverManager::RecordUserGestureForWebContents(
65 content::WebContents* web_contents,
66 const base::Time& timestamp) {
67 auto insertion_result =
68 user_gesture_map_.insert(std::make_pair(web_contents, timestamp));
69 // Update the timestamp if entry already exists.
70 if (!insertion_result.second)
71 insertion_result.first->second = timestamp;
72 }
73
74 void SafeBrowsingNavigationObserverManager::OnUserGestureConsumed(
75 content::WebContents* web_contents,
76 const base::Time& timestamp) {
77 auto it = user_gesture_map_.find(web_contents);
78 // Remove entry from |user_gesture_map_| as a user_gesture is consumed by
79 // a navigation event.
80 if (it != user_gesture_map_.end() && timestamp >= it->second)
81 user_gesture_map_.erase(it);
82 }
83
84 void SafeBrowsingNavigationObserverManager::RecordHostToIpMapping(
85 const std::string& host,
86 const std::string& ip) {
87 auto insert_result = host_to_ip_map_.insert(
88 std::make_pair(host, std::vector<ResolvedIPAddress>()));
89 if (!insert_result.second) {
90 // host_to_ip_map already contains this key.
91 // If this IP is already in the vector, we update its timestamp.
92 for (auto& vector_entry : insert_result.first->second) {
93 if (vector_entry.ip == host) {
94 vector_entry.timestamp = base::Time::Now();
95 return;
96 }
97 }
98 }
99 // If this is a new IP of this host, and we added to the end of the vector.
100 insert_result.first->second.push_back(
101 ResolvedIPAddress(base::Time::Now(), ip));
102 }
103
104 void SafeBrowsingNavigationObserverManager::OnWebContentDestroyed(
105 content::WebContents* web_contents) {
106 user_gesture_map_.erase(web_contents);
107 // TODO (jialiul): Will add other clean up tasks shortly.
108 }
109
110 SafeBrowsingNavigationObserverManager::
111 ~SafeBrowsingNavigationObserverManager() {}
112
113 void SafeBrowsingNavigationObserverManager::Observe(
114 int type,
115 const content::NotificationSource& source,
116 const content::NotificationDetails& details) {
117 if (type == chrome::NOTIFICATION_RETARGETING)
118 RecordRetargeting(details);
119 }
120
121 void SafeBrowsingNavigationObserverManager::RecordRetargeting(
122 const content::NotificationDetails& details) {
123 const RetargetingDetails* retargeting_detail =
124 content::Details<const RetargetingDetails>(details).ptr();
125 DCHECK(retargeting_detail);
126 content::WebContents* source_contents =
127 retargeting_detail->source_web_contents;
128 content::WebContents* target_contents =
129 retargeting_detail->target_web_contents;
130 DCHECK(source_contents);
131 DCHECK(target_contents);
132
133 content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
134 retargeting_detail->source_render_process_id,
135 retargeting_detail->source_render_frame_id);
136 // Remove the "#" at the end of URL, since it does not point to any actual
137 // page fragment ID.
138 GURL target_url = SafeBrowsingNavigationObserverManager::ClearEmptyRef(
139 retargeting_detail->target_url);
140
141 NavigationEvent nav_event;
142 if (rfh) {
143 nav_event.source_url = SafeBrowsingNavigationObserverManager::ClearEmptyRef(
144 rfh->GetLastCommittedURL());
145 }
146 nav_event.source_tab_id = SessionTabHelper::IdForTab(source_contents);
147 nav_event.source_main_frame_url =
148 SafeBrowsingNavigationObserverManager::ClearEmptyRef(
149 source_contents->GetLastCommittedURL());
150 nav_event.original_request_url = target_url;
151 nav_event.destination_url = target_url;
152 nav_event.target_tab_id = SessionTabHelper::IdForTab(target_contents);
153 nav_event.frame_id = rfh ? rfh->GetFrameTreeNodeId() : -1;
154 auto it = user_gesture_map_.find(source_contents);
155 if (it != user_gesture_map_.end() &&
156 !SafeBrowsingNavigationObserverManager::IsUserGestureExpired(
157 it->second)) {
158 nav_event.is_user_initiated = true;
159 OnUserGestureConsumed(it->first, it->second);
160 } else {
161 nav_event.is_user_initiated = false;
162 }
163
164 auto insertion_result = navigation_map_.insert(
165 std::make_pair(target_url, std::vector<NavigationEvent>()));
166 insertion_result.first->second.push_back(std::move(nav_event));
167 }
168
169 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698