OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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/safe_browsing_navigation_observer_manager
.h" | 5 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager
.h" |
6 | 6 |
7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 | 157 |
158 SafeBrowsingNavigationObserverManager::AttributionResult | 158 SafeBrowsingNavigationObserverManager::AttributionResult |
159 SafeBrowsingNavigationObserverManager::IdentifyReferrerChain( | 159 SafeBrowsingNavigationObserverManager::IdentifyReferrerChain( |
160 const GURL& target_url, | 160 const GURL& target_url, |
161 int target_tab_id, | 161 int target_tab_id, |
162 int user_gesture_count_limit, | 162 int user_gesture_count_limit, |
163 std::vector<ReferrerChainEntry>* out_referrer_chain) { | 163 std::vector<ReferrerChainEntry>* out_referrer_chain) { |
164 if (!target_url.is_valid()) | 164 if (!target_url.is_valid()) |
165 return INVALID_URL; | 165 return INVALID_URL; |
166 | 166 |
167 NavigationEvent* nav_event = FindNavigationEvent(target_url, target_tab_id); | 167 NavigationEvent* nav_event = FindNavigationEvent( |
| 168 target_url, |
| 169 GURL(), |
| 170 target_tab_id); |
168 if (!nav_event) { | 171 if (!nav_event) { |
169 // We cannot find a single navigation event related to this download. | 172 // We cannot find a single navigation event related to this download. |
170 return NAVIGATION_EVENT_NOT_FOUND; | 173 return NAVIGATION_EVENT_NOT_FOUND; |
171 } | 174 } |
172 | 175 |
173 AddToReferrerChain(out_referrer_chain, nav_event, | 176 AddToReferrerChain(out_referrer_chain, nav_event, |
174 ReferrerChainEntry::DOWNLOAD_URL); | 177 ReferrerChainEntry::DOWNLOAD_URL); |
175 AttributionResult result = SUCCESS; | 178 AttributionResult result = SUCCESS; |
176 int user_gesture_count = 0; | 179 int user_gesture_count = 0; |
177 while (user_gesture_count < user_gesture_count_limit) { | 180 while (user_gesture_count < user_gesture_count_limit) { |
178 // Back trace to the next nav_event that was initiated by the user. | 181 // Back trace to the next nav_event that was initiated by the user. |
179 while (!nav_event->is_user_initiated) { | 182 while (!nav_event->is_user_initiated) { |
180 nav_event = | 183 nav_event = |
181 FindNavigationEvent(nav_event->source_url, nav_event->source_tab_id); | 184 FindNavigationEvent(nav_event->source_url, |
| 185 nav_event->source_main_frame_url, |
| 186 nav_event->source_tab_id); |
182 if (!nav_event) | 187 if (!nav_event) |
183 return result; | 188 return result; |
184 AddToReferrerChain(out_referrer_chain, nav_event, | 189 AddToReferrerChain(out_referrer_chain, nav_event, |
185 nav_event->has_server_redirect | 190 nav_event->has_server_redirect |
186 ? ReferrerChainEntry::SERVER_REDIRECT | 191 ? ReferrerChainEntry::SERVER_REDIRECT |
187 : ReferrerChainEntry::CLIENT_REDIRECT); | 192 : ReferrerChainEntry::CLIENT_REDIRECT); |
188 } | 193 } |
189 | 194 |
190 user_gesture_count++; | 195 user_gesture_count++; |
191 | 196 |
192 // If the source_url and source_main_frame_url of current navigation event | 197 // If the source_url and source_main_frame_url of current navigation event |
193 // are empty, and is_user_initiated is true, this is a browser initiated | 198 // are empty, and is_user_initiated is true, this is a browser initiated |
194 // navigation (e.g. trigged by typing in address bar, clicking on bookmark, | 199 // navigation (e.g. trigged by typing in address bar, clicking on bookmark, |
195 // etc). We reached the end of the referrer chain. | 200 // etc). We reached the end of the referrer chain. |
196 if (nav_event->source_url.is_empty() && | 201 if (nav_event->source_url.is_empty() && |
197 nav_event->source_main_frame_url.is_empty()) { | 202 nav_event->source_main_frame_url.is_empty()) { |
198 DCHECK(nav_event->is_user_initiated); | 203 DCHECK(nav_event->is_user_initiated); |
199 return result; | 204 return result; |
200 } | 205 } |
201 | 206 |
202 nav_event = | 207 nav_event = |
203 FindNavigationEvent(nav_event->source_url, nav_event->source_tab_id); | 208 FindNavigationEvent(nav_event->source_url, |
| 209 nav_event->source_main_frame_url, |
| 210 nav_event->source_tab_id); |
204 if (!nav_event) | 211 if (!nav_event) |
205 return result; | 212 return result; |
206 | 213 |
207 // Landing page of a download refers to the page user directly interacts | 214 // Landing page of a download refers to the page user directly interacts |
208 // with to trigger this download (e.g. clicking on download button). Landing | 215 // with to trigger this download (e.g. clicking on download button). Landing |
209 // referrer page is the one user interacts with right before navigating to | 216 // referrer page is the one user interacts with right before navigating to |
210 // the landing page. | 217 // the landing page. |
211 // Since we are tracing navigations backwards, if we've encountered 1 user | 218 // Since we are tracing navigations backwards, if we've encountered 1 user |
212 // gesture before this navigation event, this is a navigation leading to the | 219 // gesture before this navigation event, this is a navigation leading to the |
213 // landing page. If we've encountered 2 user gestures, it leads to landing | 220 // landing page. If we've encountered 2 user gestures, it leads to landing |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 base::TimeDelta interval) { | 344 base::TimeDelta interval) { |
338 DCHECK_GT(interval, base::TimeDelta()); | 345 DCHECK_GT(interval, base::TimeDelta()); |
339 cleanup_timer_.Stop(); | 346 cleanup_timer_.Stop(); |
340 cleanup_timer_.Start( | 347 cleanup_timer_.Start( |
341 FROM_HERE, interval, this, | 348 FROM_HERE, interval, this, |
342 &SafeBrowsingNavigationObserverManager::CleanUpStaleNavigationFootprints); | 349 &SafeBrowsingNavigationObserverManager::CleanUpStaleNavigationFootprints); |
343 } | 350 } |
344 | 351 |
345 NavigationEvent* SafeBrowsingNavigationObserverManager::FindNavigationEvent( | 352 NavigationEvent* SafeBrowsingNavigationObserverManager::FindNavigationEvent( |
346 const GURL& target_url, | 353 const GURL& target_url, |
| 354 const GURL& target_main_frame_url, |
347 int target_tab_id) { | 355 int target_tab_id) { |
348 auto it = navigation_map_.find(target_url); | 356 if (target_url.is_empty() && target_main_frame_url.is_empty()) |
| 357 return nullptr; |
| 358 |
| 359 // If target_url is empty, we should back trace navigation based on its |
| 360 // main frame URL instead. |
| 361 const GURL& search_url = |
| 362 target_url.is_empty() ? target_main_frame_url : target_url; |
| 363 |
| 364 auto it = navigation_map_.find(search_url); |
349 if (it == navigation_map_.end()) { | 365 if (it == navigation_map_.end()) { |
350 return nullptr; | 366 return nullptr; |
351 } | 367 } |
352 // Since navigation events are recorded in chronological order, we traverse | 368 // Since navigation events are recorded in chronological order, we traverse |
353 // the vector in reverse order to get the latest match. | 369 // the vector in reverse order to get the latest match. |
354 for (auto rit = it->second.rbegin(); rit != it->second.rend(); ++rit) { | 370 for (auto rit = it->second.rbegin(); rit != it->second.rend(); ++rit) { |
355 // If tab id is not valid, we only compare url, otherwise we compare both. | 371 // If tab id is not valid, we only compare url, otherwise we compare both. |
356 if (rit->destination_url == target_url && | 372 if (rit->destination_url == search_url && |
357 (target_tab_id == -1 || rit->target_tab_id == target_tab_id)) { | 373 (target_tab_id == -1 || rit->target_tab_id == target_tab_id)) { |
358 // If both source_url and source_main_frame_url are empty, and this | 374 // If both source_url and source_main_frame_url are empty, and this |
359 // navigation is not triggered by user, a retargeting navigation probably | 375 // navigation is not triggered by user, a retargeting navigation probably |
360 // causes this navigation. In this case, we skip this navigation event and | 376 // causes this navigation. In this case, we skip this navigation event and |
361 // looks for the retargeting navigation event. | 377 // looks for the retargeting navigation event. |
362 if (rit->source_url.is_empty() && rit->source_main_frame_url.is_empty() && | 378 if (rit->source_url.is_empty() && rit->source_main_frame_url.is_empty() && |
363 !rit->is_user_initiated) { | 379 !rit->is_user_initiated) { |
364 continue; | 380 continue; |
365 } else { | 381 } else { |
366 return &*rit; | 382 return &*rit; |
(...skipping 24 matching lines...) Expand all Loading... |
391 nav_event->source_main_frame_url.spec()); | 407 nav_event->source_main_frame_url.spec()); |
392 } | 408 } |
393 referrer_chain_entry.set_is_retargeting(nav_event->source_tab_id != | 409 referrer_chain_entry.set_is_retargeting(nav_event->source_tab_id != |
394 nav_event->target_tab_id); | 410 nav_event->target_tab_id); |
395 referrer_chain_entry.set_navigation_time_msec( | 411 referrer_chain_entry.set_navigation_time_msec( |
396 nav_event->last_updated.ToJavaTime()); | 412 nav_event->last_updated.ToJavaTime()); |
397 referrer_chain->push_back(std::move(referrer_chain_entry)); | 413 referrer_chain->push_back(std::move(referrer_chain_entry)); |
398 } | 414 } |
399 | 415 |
400 } // namespace safe_browsing | 416 } // namespace safe_browsing |
OLD | NEW |