| 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 | 168 |
| 169 void SafeBrowsingNavigationObserverManager::RecordHostToIpMapping( | 169 void SafeBrowsingNavigationObserverManager::RecordHostToIpMapping( |
| 170 const std::string& host, | 170 const std::string& host, |
| 171 const std::string& ip) { | 171 const std::string& ip) { |
| 172 auto insert_result = host_to_ip_map_.insert( | 172 auto insert_result = host_to_ip_map_.insert( |
| 173 std::make_pair(host, std::vector<ResolvedIPAddress>())); | 173 std::make_pair(host, std::vector<ResolvedIPAddress>())); |
| 174 if (!insert_result.second) { | 174 if (!insert_result.second) { |
| 175 // host_to_ip_map already contains this key. | 175 // host_to_ip_map already contains this key. |
| 176 // If this IP is already in the vector, we update its timestamp. | 176 // If this IP is already in the vector, we update its timestamp. |
| 177 for (auto& vector_entry : insert_result.first->second) { | 177 for (auto& vector_entry : insert_result.first->second) { |
| 178 if (vector_entry.ip == host) { | 178 if (vector_entry.ip == ip) { |
| 179 vector_entry.timestamp = base::Time::Now(); | 179 vector_entry.timestamp = base::Time::Now(); |
| 180 return; | 180 return; |
| 181 } | 181 } |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 // If this is a new IP of this host, and we added to the end of the vector. | 184 // If this is a new IP of this host, and we added to the end of the vector. |
| 185 insert_result.first->second.push_back( | 185 insert_result.first->second.push_back( |
| 186 ResolvedIPAddress(base::Time::Now(), ip)); | 186 ResolvedIPAddress(base::Time::Now(), ip)); |
| 187 } | 187 } |
| 188 | 188 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 210 | 210 |
| 211 NavigationEvent* nav_event = FindNavigationEvent( | 211 NavigationEvent* nav_event = FindNavigationEvent( |
| 212 target_url, | 212 target_url, |
| 213 GURL(), | 213 GURL(), |
| 214 target_tab_id); | 214 target_tab_id); |
| 215 if (!nav_event) { | 215 if (!nav_event) { |
| 216 // We cannot find a single navigation event related to this download. | 216 // We cannot find a single navigation event related to this download. |
| 217 return NAVIGATION_EVENT_NOT_FOUND; | 217 return NAVIGATION_EVENT_NOT_FOUND; |
| 218 } | 218 } |
| 219 AttributionResult result = SUCCESS; | 219 AttributionResult result = SUCCESS; |
| 220 AddToReferrerChain(out_referrer_chain, nav_event, | 220 AddToReferrerChain(out_referrer_chain, nav_event, GURL(), |
| 221 ReferrerChainEntry::DOWNLOAD_URL); | 221 ReferrerChainEntry::DOWNLOAD_URL); |
| 222 int user_gesture_count = 0; | 222 int user_gesture_count = 0; |
| 223 GetRemainingReferrerChain( | 223 GetRemainingReferrerChain( |
| 224 nav_event, | 224 nav_event, |
| 225 user_gesture_count, | 225 user_gesture_count, |
| 226 user_gesture_count_limit, | 226 user_gesture_count_limit, |
| 227 out_referrer_chain, | 227 out_referrer_chain, |
| 228 &result); | 228 &result); |
| 229 return result; | 229 return result; |
| 230 } | 230 } |
| 231 | 231 |
| 232 SafeBrowsingNavigationObserverManager::AttributionResult | 232 SafeBrowsingNavigationObserverManager::AttributionResult |
| 233 SafeBrowsingNavigationObserverManager::IdentifyReferrerChainForPPAPIDownload( | 233 SafeBrowsingNavigationObserverManager::IdentifyReferrerChainForPPAPIDownload( |
| 234 const GURL& initiating_frame_url, | 234 const GURL& initiating_frame_url, |
| 235 const GURL& initiating_main_frame_url, |
| 235 int tab_id, | 236 int tab_id, |
| 236 bool has_user_gesture, | 237 bool has_user_gesture, |
| 237 int user_gesture_count_limit, | 238 int user_gesture_count_limit, |
| 238 ReferrerChain* out_referrer_chain) { | 239 ReferrerChain* out_referrer_chain) { |
| 239 if (!initiating_frame_url.is_valid()) | 240 if (!initiating_frame_url.is_valid()) |
| 240 return INVALID_URL; | 241 return INVALID_URL; |
| 241 | 242 |
| 242 NavigationEvent* nav_event = | 243 NavigationEvent* nav_event = |
| 243 FindNavigationEvent(initiating_frame_url, GURL(), tab_id); | 244 FindNavigationEvent(initiating_frame_url, GURL(), tab_id); |
| 244 if (!nav_event) { | 245 if (!nav_event) { |
| 245 // We cannot find a single navigation event related to this download. | 246 // We cannot find a single navigation event related to this download. |
| 246 return NAVIGATION_EVENT_NOT_FOUND; | 247 return NAVIGATION_EVENT_NOT_FOUND; |
| 247 } | 248 } |
| 248 | 249 |
| 249 AttributionResult result = SUCCESS; | 250 AttributionResult result = SUCCESS; |
| 250 | 251 |
| 251 int user_gesture_count = 0; | 252 int user_gesture_count = 0; |
| 252 // If this initiating_frame has user gesture, we consider this as the landing | 253 // If this initiating_frame has user gesture, we consider this as the landing |
| 253 // page of the PPAPI download. | 254 // page of the PPAPI download. |
| 254 if (has_user_gesture) { | 255 if (has_user_gesture) { |
| 255 user_gesture_count = 1; | 256 user_gesture_count = 1; |
| 256 AddToReferrerChain(out_referrer_chain, nav_event, | 257 AddToReferrerChain( |
| 257 GetURLTypeAndAdjustAttributionResult( | 258 out_referrer_chain, nav_event, initiating_main_frame_url, |
| 258 user_gesture_count == user_gesture_count_limit, | 259 GetURLTypeAndAdjustAttributionResult( |
| 259 &result)); | 260 user_gesture_count == user_gesture_count_limit, &result)); |
| 260 } else { | 261 } else { |
| 261 AddToReferrerChain(out_referrer_chain, nav_event, | 262 AddToReferrerChain(out_referrer_chain, nav_event, initiating_main_frame_url, |
| 262 nav_event->has_server_redirect | 263 ReferrerChainEntry::CLIENT_REDIRECT); |
| 263 ? ReferrerChainEntry::SERVER_REDIRECT | |
| 264 : ReferrerChainEntry::CLIENT_REDIRECT); | |
| 265 } | 264 } |
| 266 | 265 |
| 267 GetRemainingReferrerChain( | 266 GetRemainingReferrerChain( |
| 268 nav_event, | 267 nav_event, |
| 269 user_gesture_count, | 268 user_gesture_count, |
| 270 user_gesture_count_limit, | 269 user_gesture_count_limit, |
| 271 out_referrer_chain, | 270 out_referrer_chain, |
| 272 &result); | 271 &result); |
| 273 return result; | 272 return result; |
| 274 } | 273 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 NavigationEvent nav_event; | 306 NavigationEvent nav_event; |
| 308 if (rfh) { | 307 if (rfh) { |
| 309 nav_event.source_url = SafeBrowsingNavigationObserverManager::ClearEmptyRef( | 308 nav_event.source_url = SafeBrowsingNavigationObserverManager::ClearEmptyRef( |
| 310 rfh->GetLastCommittedURL()); | 309 rfh->GetLastCommittedURL()); |
| 311 } | 310 } |
| 312 nav_event.source_tab_id = SessionTabHelper::IdForTab(source_contents); | 311 nav_event.source_tab_id = SessionTabHelper::IdForTab(source_contents); |
| 313 nav_event.source_main_frame_url = | 312 nav_event.source_main_frame_url = |
| 314 SafeBrowsingNavigationObserverManager::ClearEmptyRef( | 313 SafeBrowsingNavigationObserverManager::ClearEmptyRef( |
| 315 source_contents->GetLastCommittedURL()); | 314 source_contents->GetLastCommittedURL()); |
| 316 nav_event.original_request_url = target_url; | 315 nav_event.original_request_url = target_url; |
| 317 nav_event.destination_url = target_url; | |
| 318 nav_event.target_tab_id = SessionTabHelper::IdForTab(target_contents); | 316 nav_event.target_tab_id = SessionTabHelper::IdForTab(target_contents); |
| 319 nav_event.frame_id = rfh ? rfh->GetFrameTreeNodeId() : -1; | 317 nav_event.frame_id = rfh ? rfh->GetFrameTreeNodeId() : -1; |
| 320 auto it = user_gesture_map_.find(source_contents); | 318 auto it = user_gesture_map_.find(source_contents); |
| 321 if (it != user_gesture_map_.end() && | 319 if (it != user_gesture_map_.end() && |
| 322 !SafeBrowsingNavigationObserverManager::IsUserGestureExpired( | 320 !SafeBrowsingNavigationObserverManager::IsUserGestureExpired( |
| 323 it->second)) { | 321 it->second)) { |
| 324 nav_event.is_user_initiated = true; | 322 nav_event.is_user_initiated = true; |
| 325 OnUserGestureConsumed(it->first, it->second); | 323 OnUserGestureConsumed(it->first, it->second); |
| 326 } else { | 324 } else { |
| 327 nav_event.is_user_initiated = false; | 325 nav_event.is_user_initiated = false; |
| 328 } | 326 } |
| 329 | 327 |
| 330 auto insertion_result = navigation_map_.insert( | 328 auto insertion_result = navigation_map_.insert( |
| 331 std::make_pair(target_url, std::vector<NavigationEvent>())); | 329 std::make_pair(target_url, std::vector<NavigationEvent>())); |
| 332 insertion_result.first->second.push_back(std::move(nav_event)); | 330 insertion_result.first->second.push_back(std::move(nav_event)); |
| 333 } | 331 } |
| 334 | 332 |
| 335 void SafeBrowsingNavigationObserverManager::CleanUpNavigationEvents() { | 333 void SafeBrowsingNavigationObserverManager::CleanUpNavigationEvents() { |
| 336 // Remove any stale NavigationEnvent, if it is older than | 334 // Remove any stale NavigationEnvent, if it is older than |
| 337 // kNavigationFootprintTTLInSecond. | 335 // kNavigationFootprintTTLInSecond. |
| 336 std::size_t remove_count = 0; |
| 338 for (auto it = navigation_map_.begin(); it != navigation_map_.end();) { | 337 for (auto it = navigation_map_.begin(); it != navigation_map_.end();) { |
| 338 std::size_t size_before_removal = it->second.size(); |
| 339 it->second.erase(std::remove_if(it->second.begin(), it->second.end(), | 339 it->second.erase(std::remove_if(it->second.begin(), it->second.end(), |
| 340 [](const NavigationEvent& nav_event) { | 340 [](const NavigationEvent& nav_event) { |
| 341 return IsEventExpired( | 341 return IsEventExpired( |
| 342 nav_event.last_updated, | 342 nav_event.last_updated, |
| 343 kNavigationFootprintTTLInSecond); | 343 kNavigationFootprintTTLInSecond); |
| 344 }), | 344 }), |
| 345 it->second.end()); | 345 it->second.end()); |
| 346 if (it->second.size() == 0) | 346 std::size_t size_after_removal = it->second.size(); |
| 347 remove_count += (size_before_removal - size_after_removal); |
| 348 if (size_after_removal == 0) |
| 347 it = navigation_map_.erase(it); | 349 it = navigation_map_.erase(it); |
| 348 else | 350 else |
| 349 ++it; | 351 ++it; |
| 350 } | 352 } |
| 353 UMA_HISTOGRAM_COUNTS_10000( |
| 354 "SafeBrowsing.NavigationObserver.NavigationEventCleanUpCount", |
| 355 remove_count); |
| 351 } | 356 } |
| 352 | 357 |
| 353 void SafeBrowsingNavigationObserverManager::CleanUpUserGestures() { | 358 void SafeBrowsingNavigationObserverManager::CleanUpUserGestures() { |
| 354 for (auto it = user_gesture_map_.begin(); it != user_gesture_map_.end();) { | 359 for (auto it = user_gesture_map_.begin(); it != user_gesture_map_.end();) { |
| 355 if (IsEventExpired(it->second, kUserGestureTTLInSecond)) | 360 if (IsEventExpired(it->second, kUserGestureTTLInSecond)) |
| 356 it = user_gesture_map_.erase(it); | 361 it = user_gesture_map_.erase(it); |
| 357 else | 362 else |
| 358 ++it; | 363 ++it; |
| 359 } | 364 } |
| 360 } | 365 } |
| 361 | 366 |
| 362 void SafeBrowsingNavigationObserverManager::CleanUpIpAddresses() { | 367 void SafeBrowsingNavigationObserverManager::CleanUpIpAddresses() { |
| 368 std::size_t remove_count = 0; |
| 363 for (auto it = host_to_ip_map_.begin(); it != host_to_ip_map_.end();) { | 369 for (auto it = host_to_ip_map_.begin(); it != host_to_ip_map_.end();) { |
| 370 std::size_t size_before_removal = it->second.size(); |
| 364 it->second.erase(std::remove_if(it->second.begin(), it->second.end(), | 371 it->second.erase(std::remove_if(it->second.begin(), it->second.end(), |
| 365 [](const ResolvedIPAddress& resolved_ip) { | 372 [](const ResolvedIPAddress& resolved_ip) { |
| 366 return IsEventExpired( | 373 return IsEventExpired( |
| 367 resolved_ip.timestamp, | 374 resolved_ip.timestamp, |
| 368 kNavigationFootprintTTLInSecond); | 375 kNavigationFootprintTTLInSecond); |
| 369 }), | 376 }), |
| 370 it->second.end()); | 377 it->second.end()); |
| 371 if (it->second.size() == 0) | 378 std::size_t size_after_removal = it->second.size(); |
| 379 remove_count += (size_before_removal - size_after_removal); |
| 380 if (size_after_removal == 0) |
| 372 it = host_to_ip_map_.erase(it); | 381 it = host_to_ip_map_.erase(it); |
| 373 else | 382 else |
| 374 ++it; | 383 ++it; |
| 375 } | 384 } |
| 385 UMA_HISTOGRAM_COUNTS_10000( |
| 386 "SafeBrowsing.NavigationObserver.IPAddressCleanUpCount", remove_count); |
| 376 } | 387 } |
| 377 | 388 |
| 378 bool SafeBrowsingNavigationObserverManager::IsCleanUpScheduled() const { | 389 bool SafeBrowsingNavigationObserverManager::IsCleanUpScheduled() const { |
| 379 return cleanup_timer_.IsRunning(); | 390 return cleanup_timer_.IsRunning(); |
| 380 } | 391 } |
| 381 | 392 |
| 382 void SafeBrowsingNavigationObserverManager::ScheduleNextCleanUpAfterInterval( | 393 void SafeBrowsingNavigationObserverManager::ScheduleNextCleanUpAfterInterval( |
| 383 base::TimeDelta interval) { | 394 base::TimeDelta interval) { |
| 384 DCHECK_GT(interval, base::TimeDelta()); | 395 DCHECK_GT(interval, base::TimeDelta()); |
| 385 cleanup_timer_.Stop(); | 396 cleanup_timer_.Stop(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 400 GURL search_url = | 411 GURL search_url = |
| 401 target_url.is_empty() ? target_main_frame_url : target_url; | 412 target_url.is_empty() ? target_main_frame_url : target_url; |
| 402 auto it = navigation_map_.find(search_url); | 413 auto it = navigation_map_.find(search_url); |
| 403 if (it == navigation_map_.end()) | 414 if (it == navigation_map_.end()) |
| 404 return nullptr; | 415 return nullptr; |
| 405 | 416 |
| 406 // Since navigation events are recorded in chronological order, we traverse | 417 // Since navigation events are recorded in chronological order, we traverse |
| 407 // the vector in reverse order to get the latest match. | 418 // the vector in reverse order to get the latest match. |
| 408 for (auto rit = it->second.rbegin(); rit != it->second.rend(); ++rit) { | 419 for (auto rit = it->second.rbegin(); rit != it->second.rend(); ++rit) { |
| 409 // If tab id is not valid, we only compare url, otherwise we compare both. | 420 // If tab id is not valid, we only compare url, otherwise we compare both. |
| 410 if (rit->destination_url == search_url && | 421 if (rit->GetDestinationUrl() == search_url && |
| 411 (target_tab_id == -1 || rit->target_tab_id == target_tab_id)) { | 422 (target_tab_id == -1 || rit->target_tab_id == target_tab_id)) { |
| 412 // If both source_url and source_main_frame_url are empty, and this | 423 // If both source_url and source_main_frame_url are empty, and this |
| 413 // navigation is not triggered by user, a retargeting navigation probably | 424 // navigation is not triggered by user, a retargeting navigation probably |
| 414 // causes this navigation. In this case, we skip this navigation event and | 425 // causes this navigation. In this case, we skip this navigation event and |
| 415 // looks for the retargeting navigation event. | 426 // looks for the retargeting navigation event. |
| 416 if (rit->source_url.is_empty() && rit->source_main_frame_url.is_empty() && | 427 if (rit->source_url.is_empty() && rit->source_main_frame_url.is_empty() && |
| 417 !rit->is_user_initiated) { | 428 !rit->is_user_initiated) { |
| 418 // If there is a server redirection immediately after retargeting, we | 429 // If there is a server redirection immediately after retargeting, we |
| 419 // need to adjust our search url to the original request. | 430 // need to adjust our search url to the original request. |
| 420 if (rit->has_server_redirect){ | 431 if (!rit->server_redirect_urls.empty()) { |
| 421 NavigationEvent* retargeting_nav_event = | 432 NavigationEvent* retargeting_nav_event = |
| 422 FindNavigationEvent(rit->original_request_url, | 433 FindNavigationEvent(rit->original_request_url, |
| 423 GURL(), | 434 GURL(), |
| 424 rit->target_tab_id); | 435 rit->target_tab_id); |
| 425 if (!retargeting_nav_event) | 436 if (!retargeting_nav_event) |
| 426 return nullptr; | 437 return nullptr; |
| 427 // Adjust retargeting navigation event's attributes. | 438 // Adjust retargeting navigation event's attributes. |
| 428 retargeting_nav_event->has_server_redirect = true; | 439 retargeting_nav_event->server_redirect_urls.push_back( |
| 429 retargeting_nav_event->destination_url = search_url; | 440 std::move(search_url)); |
| 430 return retargeting_nav_event; | 441 return retargeting_nav_event; |
| 431 } else { | 442 } else { |
| 432 continue; | 443 continue; |
| 433 } | 444 } |
| 434 } else { | 445 } else { |
| 435 return &*rit; | 446 return &*rit; |
| 436 } | 447 } |
| 437 } | 448 } |
| 438 } | 449 } |
| 439 return nullptr; | 450 return nullptr; |
| 440 } | 451 } |
| 441 | 452 |
| 442 void SafeBrowsingNavigationObserverManager::AddToReferrerChain( | 453 void SafeBrowsingNavigationObserverManager::AddToReferrerChain( |
| 443 ReferrerChain* referrer_chain, | 454 ReferrerChain* referrer_chain, |
| 444 NavigationEvent* nav_event, | 455 NavigationEvent* nav_event, |
| 456 const GURL& destination_main_frame_url, |
| 445 ReferrerChainEntry::URLType type) { | 457 ReferrerChainEntry::URLType type) { |
| 446 ReferrerChainEntry referrer_chain_entry; | 458 std::unique_ptr<ReferrerChainEntry> referrer_chain_entry = |
| 447 referrer_chain_entry.set_url(nav_event->destination_url.spec()); | 459 base::MakeUnique<ReferrerChainEntry>(); |
| 448 referrer_chain_entry.set_type(type); | 460 const GURL destination_url = nav_event->GetDestinationUrl(); |
| 449 auto ip_it = host_to_ip_map_.find(nav_event->destination_url.host()); | 461 referrer_chain_entry->set_url(destination_url.spec()); |
| 462 if (destination_main_frame_url.is_valid() && |
| 463 destination_url != destination_main_frame_url) |
| 464 referrer_chain_entry->set_main_frame_url(destination_main_frame_url.spec()); |
| 465 referrer_chain_entry->set_type(type); |
| 466 auto ip_it = host_to_ip_map_.find(destination_url.host()); |
| 450 if (ip_it != host_to_ip_map_.end()) { | 467 if (ip_it != host_to_ip_map_.end()) { |
| 451 for (ResolvedIPAddress entry : ip_it->second) { | 468 for (ResolvedIPAddress entry : ip_it->second) { |
| 452 referrer_chain_entry.add_ip_addresses(entry.ip); | 469 referrer_chain_entry->add_ip_addresses(entry.ip); |
| 453 } | 470 } |
| 454 } | 471 } |
| 455 // Since we only track navigation to landing referrer, we will not log the | 472 // Since we only track navigation to landing referrer, we will not log the |
| 456 // referrer of the landing referrer page. | 473 // referrer of the landing referrer page. |
| 457 if (type != ReferrerChainEntry::LANDING_REFERRER) { | 474 if (type != ReferrerChainEntry::LANDING_REFERRER) { |
| 458 referrer_chain_entry.set_referrer_url(nav_event->source_url.spec()); | 475 referrer_chain_entry->set_referrer_url(nav_event->source_url.spec()); |
| 459 referrer_chain_entry.set_referrer_main_frame_url( | 476 // Only set |referrer_main_frame_url| if it is diff from |referrer_url|. |
| 460 nav_event->source_main_frame_url.spec()); | 477 if (nav_event->source_main_frame_url.is_valid() && |
| 478 nav_event->source_url != nav_event->source_main_frame_url) { |
| 479 referrer_chain_entry->set_referrer_main_frame_url( |
| 480 nav_event->source_main_frame_url.spec()); |
| 481 } |
| 461 } | 482 } |
| 462 referrer_chain_entry.set_is_retargeting(nav_event->source_tab_id != | 483 referrer_chain_entry->set_is_retargeting(nav_event->source_tab_id != |
| 463 nav_event->target_tab_id); | 484 nav_event->target_tab_id); |
| 464 referrer_chain_entry.set_navigation_time_msec( | 485 referrer_chain_entry->set_navigation_time_msec( |
| 465 nav_event->last_updated.ToJavaTime()); | 486 nav_event->last_updated.ToJavaTime()); |
| 466 referrer_chain->Add()->Swap(&referrer_chain_entry); | 487 if (!nav_event->server_redirect_urls.empty()) { |
| 488 // The first entry in |server_redirect_chain| should be the original request |
| 489 // url. |
| 490 ReferrerChainEntry::ServerRedirect* server_redirect = |
| 491 referrer_chain_entry->add_server_redirect_chain(); |
| 492 server_redirect->set_url(nav_event->original_request_url.spec()); |
| 493 for (const GURL& redirect : nav_event->server_redirect_urls) { |
| 494 server_redirect = referrer_chain_entry->add_server_redirect_chain(); |
| 495 server_redirect->set_url(redirect.spec()); |
| 496 } |
| 497 } |
| 498 referrer_chain->Add()->Swap(referrer_chain_entry.get()); |
| 467 } | 499 } |
| 468 | 500 |
| 469 void SafeBrowsingNavigationObserverManager::GetRemainingReferrerChain( | 501 void SafeBrowsingNavigationObserverManager::GetRemainingReferrerChain( |
| 470 NavigationEvent* last_nav_event_traced, | 502 NavigationEvent* last_nav_event_traced, |
| 471 int current_user_gesture_count, | 503 int current_user_gesture_count, |
| 472 int user_gesture_count_limit, | 504 int user_gesture_count_limit, |
| 473 ReferrerChain* out_referrer_chain, | 505 ReferrerChain* out_referrer_chain, |
| 474 SafeBrowsingNavigationObserverManager::AttributionResult* out_result) { | 506 SafeBrowsingNavigationObserverManager::AttributionResult* out_result) { |
| 475 | 507 GURL last_main_frame_url_traced(last_nav_event_traced->source_main_frame_url); |
| 476 while (current_user_gesture_count < user_gesture_count_limit) { | 508 while (current_user_gesture_count < user_gesture_count_limit) { |
| 477 // Back trace to the next nav_event that was initiated by the user. | 509 // Back trace to the next nav_event that was initiated by the user. |
| 478 while (!last_nav_event_traced->is_user_initiated) { | 510 while (!last_nav_event_traced->is_user_initiated) { |
| 479 last_nav_event_traced = | 511 last_nav_event_traced = |
| 480 FindNavigationEvent(last_nav_event_traced->source_url, | 512 FindNavigationEvent(last_nav_event_traced->source_url, |
| 481 last_nav_event_traced->source_main_frame_url, | 513 last_nav_event_traced->source_main_frame_url, |
| 482 last_nav_event_traced->source_tab_id); | 514 last_nav_event_traced->source_tab_id); |
| 483 if (!last_nav_event_traced) | 515 if (!last_nav_event_traced) |
| 484 return; | 516 return; |
| 485 AddToReferrerChain(out_referrer_chain, last_nav_event_traced, | 517 AddToReferrerChain(out_referrer_chain, last_nav_event_traced, |
| 486 last_nav_event_traced->has_server_redirect | 518 last_main_frame_url_traced, |
| 487 ? ReferrerChainEntry::SERVER_REDIRECT | 519 ReferrerChainEntry::CLIENT_REDIRECT); |
| 488 : ReferrerChainEntry::CLIENT_REDIRECT); | 520 last_main_frame_url_traced = last_nav_event_traced->source_main_frame_url; |
| 489 } | 521 } |
| 490 | 522 |
| 491 current_user_gesture_count++; | 523 current_user_gesture_count++; |
| 492 | 524 |
| 493 | 525 |
| 494 // If the source_url and source_main_frame_url of current navigation event | 526 // If the source_url and source_main_frame_url of current navigation event |
| 495 // are empty, and is_user_initiated is true, this is a browser initiated | 527 // are empty, and is_user_initiated is true, this is a browser initiated |
| 496 // navigation (e.g. trigged by typing in address bar, clicking on bookmark, | 528 // navigation (e.g. trigged by typing in address bar, clicking on bookmark, |
| 497 // etc). We reached the end of the referrer chain. | 529 // etc). We reached the end of the referrer chain. |
| 498 if (last_nav_event_traced->source_url.is_empty() && | 530 if (last_nav_event_traced->source_url.is_empty() && |
| 499 last_nav_event_traced->source_main_frame_url.is_empty()) { | 531 last_nav_event_traced->source_main_frame_url.is_empty()) { |
| 500 DCHECK(last_nav_event_traced->is_user_initiated); | 532 DCHECK(last_nav_event_traced->is_user_initiated); |
| 501 return; | 533 return; |
| 502 } | 534 } |
| 503 | 535 |
| 504 last_nav_event_traced = | 536 last_nav_event_traced = |
| 505 FindNavigationEvent(last_nav_event_traced->source_url, | 537 FindNavigationEvent(last_nav_event_traced->source_url, |
| 506 last_nav_event_traced->source_main_frame_url, | 538 last_nav_event_traced->source_main_frame_url, |
| 507 last_nav_event_traced->source_tab_id); | 539 last_nav_event_traced->source_tab_id); |
| 508 if (!last_nav_event_traced) | 540 if (!last_nav_event_traced) |
| 509 return; | 541 return; |
| 510 | 542 |
| 511 AddToReferrerChain(out_referrer_chain, last_nav_event_traced, | 543 AddToReferrerChain( |
| 512 GetURLTypeAndAdjustAttributionResult( | 544 out_referrer_chain, last_nav_event_traced, last_main_frame_url_traced, |
| 513 current_user_gesture_count == | 545 GetURLTypeAndAdjustAttributionResult( |
| 514 user_gesture_count_limit, | 546 current_user_gesture_count == user_gesture_count_limit, |
| 515 out_result)); | 547 out_result)); |
| 548 last_main_frame_url_traced = last_nav_event_traced->source_main_frame_url; |
| 516 } | 549 } |
| 517 } | 550 } |
| 518 | 551 |
| 519 } // namespace safe_browsing | 552 } // namespace safe_browsing |
| OLD | NEW |