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

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

Issue 2302913003: Add SafeBrowsingNavigationObserver to listen to navigation events (Closed)
Patch Set: address creis@ comments Created 4 years, 2 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 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.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "base/time/time.h"
9 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager .h"
10 #include "chrome/browser/sessions/session_tab_helper.h"
11 #include "content/public/browser/navigation_handle.h"
12 #include "content/public/browser/render_frame_host.h"
13 #include "content/public/browser/resource_request_details.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/common/resource_type.h"
16
17 using content::WebContents;
18
19 namespace {
20 const char kWebContentsUserDataKey[] =
21 "web_contents_safe_browsing_navigation_observer";
22 } // namespace
23
24 namespace safe_browsing {
25
26 // SafeBrowsingNavigationObserver::NavigationEvent-----------------------------
27 NavigationEvent::NavigationEvent()
28 : source_url(),
29 source_tab_id(-1),
30 source_main_frame_url(),
31 original_request_url(),
32 target_tab_id(-1),
33 frame_id(-1),
34 timestamp(base::Time::Now()),
35 is_user_initiated(false),
36 has_committed(false),
37 has_server_redirect(false),
38 actual_target_url() {}
39
40 NavigationEvent::NavigationEvent(NavigationEvent&& nav_event)
41 : source_url(std::move(nav_event.source_url)),
42 source_tab_id(std::move(nav_event.source_tab_id)),
43 source_main_frame_url(std::move(nav_event.source_main_frame_url)),
44 original_request_url(std::move(nav_event.original_request_url)),
45 target_tab_id(std::move(nav_event.target_tab_id)),
46 frame_id(nav_event.frame_id),
47 timestamp(nav_event.timestamp),
48 is_user_initiated(nav_event.is_user_initiated),
49 has_committed(nav_event.has_committed),
50 has_server_redirect(nav_event.has_server_redirect),
51 actual_target_url(std::move(nav_event.actual_target_url)) {}
52
53 NavigationEvent& NavigationEvent::operator=(NavigationEvent&& nav_event) {
54 source_url = std::move(nav_event.source_url);
55 source_tab_id = std::move(nav_event.source_tab_id);
56 source_main_frame_url = std::move(nav_event.source_main_frame_url);
57 original_request_url = std::move(nav_event.original_request_url);
58 target_tab_id = std::move(nav_event.target_tab_id);
59 frame_id = nav_event.frame_id;
60 timestamp = nav_event.timestamp;
61 is_user_initiated = nav_event.is_user_initiated;
62 has_committed = nav_event.has_committed;
63 has_server_redirect = nav_event.has_server_redirect;
64 actual_target_url = std::move(nav_event.actual_target_url);
65 return *this;
66 }
67
68 NavigationEvent::~NavigationEvent() {}
69
70 // SafeBrowsingNavigationObserver --------------------------------------------
71
72 // static
73 void SafeBrowsingNavigationObserver::MaybeCreateForWebContents(
74 content::WebContents* web_contents) {
75 if (FromWebContents(web_contents))
76 return;
77 NOTIMPLEMENTED();
78 // TODO(jialiul): This method will be called by TabHelpers::AttachTabHelpers.
79 // Complete this method when the entire class is ready.
80 }
81
82 // static
83 SafeBrowsingNavigationObserver* SafeBrowsingNavigationObserver::FromWebContents(
84 content::WebContents* web_contents) {
85 return static_cast<SafeBrowsingNavigationObserver*>(
86 web_contents->GetUserData(kWebContentsUserDataKey));
87 }
88
89 SafeBrowsingNavigationObserver::SafeBrowsingNavigationObserver(
90 content::WebContents* contents,
91 const scoped_refptr<SafeBrowsingNavigationObserverManager>& manager)
92 : content::WebContentsObserver(contents),
93 manager_(manager),
94 has_user_gesture_(false),
95 last_user_gesture_timestamp_(base::Time()) {}
96
97 SafeBrowsingNavigationObserver::~SafeBrowsingNavigationObserver() {}
98
99 // Called when a navigation started in the WebContents. |navigation_handle| in
100 // parameter is unique to this navigation, which will appear in the following
101 // DidRedirectNavigation, and DidFinishNavigation too.
102 void SafeBrowsingNavigationObserver::DidStartNavigation(
103 content::NavigationHandle* navigation_handle) {
104 // If we already seen this navigation_handle before, no need to do anything.
105 // TODO(jialiul): Need to handle cases where two DidStartNavigation() called
106 // by the same navigation.
107 if (navigation_handle_map_.find(navigation_handle) !=
108 navigation_handle_map_.end())
109 return;
110
111 // Construct a NavigationEvent based on available information in
112 // navigation_handle.
113 NavigationEvent nav_event;
114 content::RenderFrameHost* host =
115 navigation_handle->GetWebContents()->FindFrameByFrameTreeNodeId(
116 navigation_handle->GetFrameTreeNodeId());
117
118 // If there was URL previously committed in this render frame host,
Charlie Reis 2016/10/19 17:10:46 nit: in the current RenderFrameHost
Jialiu Lin 2016/10/21 02:38:38 Done.
119 // set it as the source url of this navigation. Otherwise, this is the
120 // first url going to commit in this frame. We set navigation_handle's URL as
121 // the source url.
122 // TODO(jialiul): source_url will be inccorect when another frame is targeting
123 // this frame. Need to refine this logic after the true initiator details are
124 // added to NavigationHandle.
Charlie Reis 2016/10/19 17:10:45 Thanks. Can you add a reference to https://crbug.
Jialiu Lin 2016/10/21 02:38:38 Sure. Done.
125 if (host && host->GetLastCommittedURL().is_valid()) {
126 nav_event.source_url = SafeBrowsingNavigationObserverManager::ClearEmptyRef(
127 host->GetLastCommittedURL());
128 } else {
129 nav_event.source_url = SafeBrowsingNavigationObserverManager::ClearEmptyRef(
130 navigation_handle->GetURL());
131 }
132 nav_event.original_request_url =
133 SafeBrowsingNavigationObserverManager::ClearEmptyRef(
134 navigation_handle->GetURL());
135 nav_event.actual_target_url = nav_event.original_request_url;
136
137 nav_event.source_tab_id =
138 SessionTabHelper::IdForTab(navigation_handle->GetWebContents());
139 nav_event.timestamp = base::Time::Now();
140 nav_event.frame_id = navigation_handle->GetFrameTreeNodeId();
141
142 if (navigation_handle->IsInMainFrame()) {
143 nav_event.source_main_frame_url = nav_event.source_url;
144 } else {
145 nav_event.source_main_frame_url =
146 SafeBrowsingNavigationObserverManager::ClearEmptyRef(
147 navigation_handle->GetWebContents()->GetLastCommittedURL());
148 }
149 if ((has_user_gesture_ &&
150 !SafeBrowsingNavigationObserverManager::IsUserGestureExpired(
151 last_user_gesture_timestamp_)) ||
152 !navigation_handle->IsRendererInitiated()) {
153 nav_event.is_user_initiated = has_user_gesture_;
154 manager_->OnUserGestureConsumed(web_contents(),
155 last_user_gesture_timestamp_);
156 }
157 has_user_gesture_ = false;
158 navigation_handle_map_.insert(
159 std::make_pair(navigation_handle, std::move(nav_event)));
160 }
161
162 void SafeBrowsingNavigationObserver::DidRedirectNavigation(
163 content::NavigationHandle* navigation_handle) {
164 // We should have already seen this navigation_handle in DidStartNavigation.
165 if (navigation_handle_map_.find(navigation_handle) ==
Nathan Parker 2016/10/19 22:56:14 I'm not sure if this gets compiled out on release
Jialiu Lin 2016/10/21 02:38:38 Done.
166 navigation_handle_map_.end())
167 NOTREACHED();
168
169 NavigationEvent* nav_event = &navigation_handle_map_[navigation_handle];
170 nav_event->has_server_redirect = true;
171 nav_event->actual_target_url =
172 SafeBrowsingNavigationObserverManager::ClearEmptyRef(
173 navigation_handle->GetURL());
174 nav_event->timestamp = base::Time::Now();
175 }
176
177 void SafeBrowsingNavigationObserver::DidFinishNavigation(
178 content::NavigationHandle* navigation_handle) {
179 if (navigation_handle_map_.find(navigation_handle) ==
180 navigation_handle_map_.end())
181 NOTREACHED();
182
183 // If it is an error page, we ignore this navigation.
184 if (navigation_handle->IsErrorPage()) {
185 navigation_handle_map_.erase(navigation_handle);
186 return;
187 }
188 NavigationEvent* nav_event = &navigation_handle_map_[navigation_handle];
189
190 nav_event->has_committed = navigation_handle->HasCommitted();
191 nav_event->target_tab_id =
192 SessionTabHelper::IdForTab(navigation_handle->GetWebContents());
193 nav_event->timestamp = base::Time::Now();
194
195 GURL nav_event_key = nav_event->actual_target_url;
196 manager_->RecordNavigationEvent(nav_event_key, nav_event);
197 navigation_handle_map_.erase(navigation_handle);
198 }
199
200 void SafeBrowsingNavigationObserver::DidGetResourceResponseStart(
201 const content::ResourceRequestDetails& details) {
202 // We only care about main frame and sub frame.
203 if (details.resource_type != content::RESOURCE_TYPE_MAIN_FRAME &&
204 details.resource_type != content::RESOURCE_TYPE_SUB_FRAME) {
205 return;
206 }
207 if (!details.url.is_valid() || details.socket_address.IsEmpty())
208 return;
209
210 manager_->RecordHostToIpMapping(details.url.host(),
211 details.socket_address.host());
212 }
213
214 void SafeBrowsingNavigationObserver::DidGetUserInteraction(
215 const blink::WebInputEvent::Type type) {
216 last_user_gesture_timestamp_ = base::Time::Now();
217 has_user_gesture_ = true;
218 // TODO (jialiul): Refine user gesture logic when DidOpenRequestedURL
219 // covers all retargetting cases.
220 manager_->RecordUserGestureForWebContents(web_contents(),
221 last_user_gesture_timestamp_);
222 }
223
224 void SafeBrowsingNavigationObserver::WebContentsDestroyed() {
225 manager_->OnWebContentDestroyed(web_contents());
226 web_contents()->RemoveUserData(kWebContentsUserDataKey);
227 // web_contents is null after this function.
228 }
229
230 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698