OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/frame_host/navigation_entry_impl.h" | 5 #include "content/browser/frame_host/navigation_entry_impl.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 | 8 |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 | 26 |
27 int NavigationEntryImpl::kInvalidBindings = -1; | 27 int NavigationEntryImpl::kInvalidBindings = -1; |
28 | 28 |
29 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry) | 29 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry) |
30 : frame_entry(frame_entry) { | 30 : frame_entry(frame_entry) { |
31 } | 31 } |
32 | 32 |
33 NavigationEntryImpl::TreeNode::~TreeNode() { | 33 NavigationEntryImpl::TreeNode::~TreeNode() { |
34 } | 34 } |
35 | 35 |
36 bool NavigationEntryImpl::TreeNode::MatchesFrame( | |
37 FrameTreeNode* frame_tree_node) const { | |
38 if (frame_tree_node->frame_tree_node_id() == | |
39 frame_entry->frame_tree_node_id()) | |
40 return true; | |
41 | |
42 // For now, we set the root FNE's FrameTreeNode ID to -1. | |
43 return frame_tree_node->IsMainFrame() && | |
44 frame_entry->frame_tree_node_id() == -1; | |
45 } | |
46 | |
47 NavigationEntryImpl::TreeNode* NavigationEntryImpl::TreeNode::Clone() const { | 36 NavigationEntryImpl::TreeNode* NavigationEntryImpl::TreeNode::Clone() const { |
48 // Clone the tree using a copy of the FrameNavigationEntry, without sharing. | 37 // Clone the tree using a copy of the FrameNavigationEntry, without sharing. |
49 NavigationEntryImpl::TreeNode* copy = | 38 NavigationEntryImpl::TreeNode* copy = |
50 new NavigationEntryImpl::TreeNode(frame_entry->Clone()); | 39 new NavigationEntryImpl::TreeNode(frame_entry->Clone()); |
51 | 40 |
52 // TODO(creis): Clone children once we add them. | 41 // TODO(creis): Clone children once we add them. |
53 return copy; | 42 return copy; |
54 } | 43 } |
55 | 44 |
56 NavigationEntry* NavigationEntry::Create() { | 45 NavigationEntry* NavigationEntry::Create() { |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 } | 412 } |
424 | 413 |
425 return StartNavigationParams( | 414 return StartNavigationParams( |
426 GetHasPostData(), extra_headers(), browser_initiated_post_data, | 415 GetHasPostData(), extra_headers(), browser_initiated_post_data, |
427 should_replace_entry(), transferred_global_request_id().child_id, | 416 should_replace_entry(), transferred_global_request_id().child_id, |
428 transferred_global_request_id().request_id); | 417 transferred_global_request_id().request_id); |
429 } | 418 } |
430 | 419 |
431 RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams( | 420 RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams( |
432 base::TimeTicks navigation_start, | 421 base::TimeTicks navigation_start, |
433 bool has_committed_real_load, | |
434 bool intended_as_new_entry, | 422 bool intended_as_new_entry, |
435 int pending_history_list_offset, | 423 int pending_history_list_offset, |
436 int current_history_list_offset, | 424 int current_history_list_offset, |
437 int current_history_list_length) const { | 425 int current_history_list_length) const { |
438 // Set the redirect chain to the navigation's redirects, unless returning to a | 426 // Set the redirect chain to the navigation's redirects, unless returning to a |
439 // completed navigation (whose previous redirects don't apply). | 427 // completed navigation (whose previous redirects don't apply). |
440 std::vector<GURL> redirects; | 428 std::vector<GURL> redirects; |
441 if (ui::PageTransitionIsNewNavigation(GetTransitionType())) { | 429 if (ui::PageTransitionIsNewNavigation(GetTransitionType())) { |
442 redirects = GetRedirectChain(); | 430 redirects = GetRedirectChain(); |
443 } | 431 } |
444 | 432 |
445 int pending_offset_to_send = pending_history_list_offset; | 433 int pending_offset_to_send = pending_history_list_offset; |
446 int current_offset_to_send = current_history_list_offset; | 434 int current_offset_to_send = current_history_list_offset; |
447 int current_length_to_send = current_history_list_length; | 435 int current_length_to_send = current_history_list_length; |
448 if (should_clear_history_list()) { | 436 if (should_clear_history_list()) { |
449 // Set the history list related parameters to the same values a | 437 // Set the history list related parameters to the same values a |
450 // NavigationController would return before its first navigation. This will | 438 // NavigationController would return before its first navigation. This will |
451 // fully clear the RenderView's view of the session history. | 439 // fully clear the RenderView's view of the session history. |
452 pending_offset_to_send = -1; | 440 pending_offset_to_send = -1; |
453 current_offset_to_send = -1; | 441 current_offset_to_send = -1; |
454 current_length_to_send = 0; | 442 current_length_to_send = 0; |
455 } | 443 } |
456 return RequestNavigationParams( | 444 return RequestNavigationParams( |
457 GetIsOverridingUserAgent(), navigation_start, redirects, | 445 GetIsOverridingUserAgent(), navigation_start, redirects, |
458 GetCanLoadLocalResources(), base::Time::Now(), GetPageState(), | 446 GetCanLoadLocalResources(), base::Time::Now(), GetPageState(), |
459 GetPageID(), GetUniqueID(), has_committed_real_load, | 447 GetPageID(), GetUniqueID(), intended_as_new_entry, pending_offset_to_send, |
460 intended_as_new_entry, pending_offset_to_send, current_offset_to_send, | 448 current_offset_to_send, current_length_to_send, |
461 current_length_to_send, should_clear_history_list()); | 449 should_clear_history_list()); |
462 } | 450 } |
463 | 451 |
464 void NavigationEntryImpl::ResetForCommit() { | 452 void NavigationEntryImpl::ResetForCommit() { |
465 // Any state that only matters when a navigation entry is pending should be | 453 // Any state that only matters when a navigation entry is pending should be |
466 // cleared here. | 454 // cleared here. |
467 // TODO(creis): This state should be moved to NavigationRequest once | 455 // TODO(creis): This state should be moved to NavigationRequest once |
468 // PlzNavigate is enabled. | 456 // PlzNavigate is enabled. |
469 SetBrowserInitiatedPostData(nullptr); | 457 SetBrowserInitiatedPostData(nullptr); |
470 set_source_site_instance(nullptr); | 458 set_source_site_instance(nullptr); |
471 set_is_renderer_initiated(false); | 459 set_is_renderer_initiated(false); |
(...skipping 10 matching lines...) Expand all Loading... |
482 #endif | 470 #endif |
483 } | 471 } |
484 | 472 |
485 void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node, | 473 void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node, |
486 SiteInstanceImpl* site_instance, | 474 SiteInstanceImpl* site_instance, |
487 const GURL& url, | 475 const GURL& url, |
488 const Referrer& referrer) { | 476 const Referrer& referrer) { |
489 // We should already have a TreeNode for the parent node by the time this node | 477 // We should already have a TreeNode for the parent node by the time this node |
490 // commits. Find it first. | 478 // commits. Find it first. |
491 DCHECK(frame_tree_node->parent()); | 479 DCHECK(frame_tree_node->parent()); |
492 NavigationEntryImpl::TreeNode* parent_node = | 480 int parent_ftn_id = frame_tree_node->parent()->frame_tree_node_id(); |
493 FindFrameEntry(frame_tree_node->parent()); | 481 bool found = false; |
494 if (!parent_node) { | 482 NavigationEntryImpl::TreeNode* parent_node = nullptr; |
| 483 std::queue<NavigationEntryImpl::TreeNode*> work_queue; |
| 484 work_queue.push(root_node()); |
| 485 while (!found && !work_queue.empty()) { |
| 486 parent_node = work_queue.front(); |
| 487 work_queue.pop(); |
| 488 // The root FNE will have an ID of -1, so check for that as well. |
| 489 if (parent_node->frame_entry->frame_tree_node_id() == parent_ftn_id || |
| 490 (parent_node->frame_entry->frame_tree_node_id() == -1 && |
| 491 parent_node == root_node() && |
| 492 frame_tree_node->parent()->IsMainFrame())) { |
| 493 found = true; |
| 494 break; |
| 495 } |
| 496 // Enqueue any children and keep looking. |
| 497 for (auto& child : parent_node->children) |
| 498 work_queue.push(child); |
| 499 } |
| 500 if (!found) { |
495 // The renderer should not send a commit for a subframe before its parent. | 501 // The renderer should not send a commit for a subframe before its parent. |
496 // TODO(creis): This can currently happen because we don't yet clone the | 502 // TODO(creis): This can currently happen because we don't yet clone the |
497 // FrameNavigationEntry tree on manual subframe navigations. Once that's | 503 // FrameNavigationEntry tree on manual subframe navigations. Once that's |
498 // added, we should kill the renderer if we get here. | 504 // added, we should kill the renderer if we get here. |
499 return; | 505 return; |
500 } | 506 } |
501 | 507 |
502 // Now check whether we have a TreeNode for the node itself. | 508 // Now check whether we have a TreeNode for the node itself. |
503 int frame_tree_node_id = frame_tree_node->frame_tree_node_id(); | 509 int frame_tree_node_id = frame_tree_node->frame_tree_node_id(); |
504 for (TreeNode* child : parent_node->children) { | 510 for (TreeNode* child : parent_node->children) { |
505 if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) { | 511 if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) { |
506 // Update the existing FrameNavigationEntry. | 512 // Update the existing FrameNavigationEntry. |
507 child->frame_entry->UpdateEntry(site_instance, url, referrer); | 513 child->frame_entry->UpdateEntry(site_instance, url, referrer); |
508 return; | 514 return; |
509 } | 515 } |
510 } | 516 } |
511 | 517 |
512 // No entry exists yet, so create a new one unless it's for about:blank. | 518 // No entry exists yet, so create a new one. Unordered list, since we expect |
513 // Unordered list, since we expect to look up entries by frame sequence number | 519 // to look up entries by frame sequence number or unique name. |
514 // or unique name. | |
515 if (url == GURL(url::kAboutBlankURL)) | |
516 return; | |
517 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( | 520 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( |
518 frame_tree_node_id, site_instance, url, referrer); | 521 frame_tree_node_id, site_instance, url, referrer); |
519 parent_node->children.push_back( | 522 parent_node->children.push_back( |
520 new NavigationEntryImpl::TreeNode(frame_entry)); | 523 new NavigationEntryImpl::TreeNode(frame_entry)); |
521 } | 524 } |
522 | 525 |
523 bool NavigationEntryImpl::HasFrameEntry(FrameTreeNode* frame_tree_node) const { | |
524 return FindFrameEntry(frame_tree_node) != nullptr; | |
525 } | |
526 | |
527 void NavigationEntryImpl::SetScreenshotPNGData( | 526 void NavigationEntryImpl::SetScreenshotPNGData( |
528 scoped_refptr<base::RefCountedBytes> png_data) { | 527 scoped_refptr<base::RefCountedBytes> png_data) { |
529 screenshot_ = png_data; | 528 screenshot_ = png_data; |
530 if (screenshot_.get()) | 529 if (screenshot_.get()) |
531 UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); | 530 UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); |
532 } | 531 } |
533 | 532 |
534 GURL NavigationEntryImpl::GetHistoryURLForDataURL() const { | 533 GURL NavigationEntryImpl::GetHistoryURLForDataURL() const { |
535 return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL(); | 534 return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL(); |
536 } | 535 } |
537 | 536 |
538 NavigationEntryImpl::TreeNode* NavigationEntryImpl::FindFrameEntry( | |
539 FrameTreeNode* frame_tree_node) const { | |
540 NavigationEntryImpl::TreeNode* node = nullptr; | |
541 std::queue<NavigationEntryImpl::TreeNode*> work_queue; | |
542 work_queue.push(root_node()); | |
543 while (!work_queue.empty()) { | |
544 node = work_queue.front(); | |
545 work_queue.pop(); | |
546 if (node->MatchesFrame(frame_tree_node)) { | |
547 // Only the root TreeNode should have a FTN ID of -1. | |
548 DCHECK_IMPLIES(node->frame_entry->frame_tree_node_id() == -1, | |
549 node == root_node()); | |
550 return node; | |
551 } | |
552 // Enqueue any children and keep looking. | |
553 for (auto& child : node->children) | |
554 work_queue.push(child); | |
555 } | |
556 return nullptr; | |
557 } | |
558 | |
559 } // namespace content | 537 } // namespace content |
OLD | NEW |