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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <queue> | 9 #include <queue> |
10 #include <utility> | 10 #include <utility> |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 int NavigationEntryImpl::kInvalidBindings = -1; | 93 int NavigationEntryImpl::kInvalidBindings = -1; |
94 | 94 |
95 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry) | 95 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry) |
96 : frame_entry(frame_entry) { | 96 : frame_entry(frame_entry) { |
97 } | 97 } |
98 | 98 |
99 NavigationEntryImpl::TreeNode::~TreeNode() { | 99 NavigationEntryImpl::TreeNode::~TreeNode() { |
100 } | 100 } |
101 | 101 |
102 bool NavigationEntryImpl::TreeNode::MatchesFrame( | 102 bool NavigationEntryImpl::TreeNode::MatchesFrame( |
103 FrameTreeNode* frame_tree_node) const { | 103 FrameTreeNode* frame_tree_node) { |
104 if (frame_tree_node->frame_tree_node_id() == | 104 if (frame_tree_node->frame_tree_node_id() == |
105 frame_entry->frame_tree_node_id()) | 105 frame_entry->frame_tree_node_id()) |
106 return true; | 106 return true; |
107 | 107 |
| 108 if (frame_tree_node->current_replication_state().unique_name == |
| 109 frame_entry->frame_unique_name()) { |
| 110 // If we find a match by unique name but not FrameTreeNode ID, then the |
| 111 // FrameTreeNode ID on the entry is stale and should be updated. |
| 112 frame_entry->set_frame_tree_node_id(frame_tree_node->frame_tree_node_id()); |
| 113 return true; |
| 114 } |
| 115 |
108 // For now, we set the root FNE's FrameTreeNode ID to -1. | 116 // For now, we set the root FNE's FrameTreeNode ID to -1. |
109 return frame_tree_node->IsMainFrame() && | 117 return frame_tree_node->IsMainFrame() && |
110 frame_entry->frame_tree_node_id() == -1; | 118 frame_entry->frame_tree_node_id() == -1; |
111 } | 119 } |
112 | 120 |
113 std::unique_ptr<NavigationEntryImpl::TreeNode> | 121 std::unique_ptr<NavigationEntryImpl::TreeNode> |
114 NavigationEntryImpl::TreeNode::CloneAndReplace( | 122 NavigationEntryImpl::TreeNode::CloneAndReplace( |
115 FrameTreeNode* frame_tree_node, | 123 FrameTreeNode* frame_tree_node, |
116 FrameNavigationEntry* frame_navigation_entry) const { | 124 FrameNavigationEntry* frame_navigation_entry) { |
117 if (frame_tree_node && MatchesFrame(frame_tree_node)) { | 125 if (frame_tree_node && MatchesFrame(frame_tree_node)) { |
118 // Replace this node in the cloned tree and prune its children. | 126 // Replace this node in the cloned tree and prune its children. |
119 return base::WrapUnique( | 127 return base::WrapUnique( |
120 new NavigationEntryImpl::TreeNode(frame_navigation_entry)); | 128 new NavigationEntryImpl::TreeNode(frame_navigation_entry)); |
121 } | 129 } |
122 | 130 |
123 // Clone the tree using a copy of the FrameNavigationEntry, without sharing. | 131 // Clone the tree using a copy of the FrameNavigationEntry, without sharing. |
124 // TODO(creis): Share FNEs unless it's for another tab. | 132 // TODO(creis): Share FNEs unless it's for another tab. |
125 std::unique_ptr<NavigationEntryImpl::TreeNode> copy( | 133 std::unique_ptr<NavigationEntryImpl::TreeNode> copy( |
126 new NavigationEntryImpl::TreeNode(frame_entry->Clone())); | 134 new NavigationEntryImpl::TreeNode(frame_entry->Clone())); |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 | 688 |
681 #if defined(OS_ANDROID) | 689 #if defined(OS_ANDROID) |
682 // Reset the time stamp so that the metrics are not reported if this entry is | 690 // Reset the time stamp so that the metrics are not reported if this entry is |
683 // loaded again in the future. | 691 // loaded again in the future. |
684 set_intent_received_timestamp(base::TimeTicks()); | 692 set_intent_received_timestamp(base::TimeTicks()); |
685 #endif | 693 #endif |
686 } | 694 } |
687 | 695 |
688 void NavigationEntryImpl::AddOrUpdateFrameEntry( | 696 void NavigationEntryImpl::AddOrUpdateFrameEntry( |
689 FrameTreeNode* frame_tree_node, | 697 FrameTreeNode* frame_tree_node, |
690 const std::string& frame_unique_name, | |
691 int64_t item_sequence_number, | 698 int64_t item_sequence_number, |
692 int64_t document_sequence_number, | 699 int64_t document_sequence_number, |
693 SiteInstanceImpl* site_instance, | 700 SiteInstanceImpl* site_instance, |
694 const GURL& url, | 701 const GURL& url, |
695 const Referrer& referrer, | 702 const Referrer& referrer, |
696 const PageState& page_state) { | 703 const PageState& page_state) { |
697 // We should already have a TreeNode for the parent node by the time this node | 704 // We should already have a TreeNode for the parent node by the time this node |
698 // commits. Find it first. | 705 // commits. Find it first. |
699 DCHECK(frame_tree_node->parent()); | 706 DCHECK(frame_tree_node->parent()); |
700 NavigationEntryImpl::TreeNode* parent_node = | 707 NavigationEntryImpl::TreeNode* parent_node = |
701 FindFrameEntry(frame_tree_node->parent()); | 708 FindFrameEntry(frame_tree_node->parent()); |
702 if (!parent_node) { | 709 if (!parent_node) { |
703 // The renderer should not send a commit for a subframe before its parent. | 710 // The renderer should not send a commit for a subframe before its parent. |
704 // TODO(creis): Kill the renderer if we get here. | 711 // TODO(creis): Kill the renderer if we get here. |
705 return; | 712 return; |
706 } | 713 } |
707 | 714 |
708 // Now check whether we have a TreeNode for the node itself. | 715 // Now check whether we have a TreeNode for the node itself. |
709 int frame_tree_node_id = frame_tree_node->frame_tree_node_id(); | 716 int frame_tree_node_id = frame_tree_node->frame_tree_node_id(); |
| 717 const std::string& unique_name = |
| 718 frame_tree_node->current_replication_state().unique_name; |
710 for (TreeNode* child : parent_node->children) { | 719 for (TreeNode* child : parent_node->children) { |
711 if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) { | 720 if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id || |
| 721 child->frame_entry->frame_unique_name() == unique_name) { |
712 // Update the existing FrameNavigationEntry (e.g., for replaceState). | 722 // Update the existing FrameNavigationEntry (e.g., for replaceState). |
713 child->frame_entry->UpdateEntry(frame_unique_name, item_sequence_number, | 723 child->frame_entry->UpdateEntry(unique_name, item_sequence_number, |
714 document_sequence_number, site_instance, | 724 document_sequence_number, site_instance, |
715 url, referrer, page_state); | 725 url, referrer, page_state); |
716 return; | 726 return; |
717 } | 727 } |
718 } | 728 } |
719 | 729 |
720 // No entry exists yet, so create a new one. | 730 // No entry exists yet, so create a new one. |
721 // Unordered list, since we expect to look up entries by frame sequence number | 731 // Unordered list, since we expect to look up entries by frame sequence number |
722 // or unique name. | 732 // or unique name. |
723 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( | 733 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( |
724 frame_tree_node_id, frame_unique_name, item_sequence_number, | 734 frame_tree_node_id, unique_name, item_sequence_number, |
725 document_sequence_number, site_instance, url, referrer); | 735 document_sequence_number, site_instance, url, referrer); |
726 frame_entry->set_page_state(page_state); | 736 frame_entry->set_page_state(page_state); |
727 parent_node->children.push_back( | 737 parent_node->children.push_back( |
728 new NavigationEntryImpl::TreeNode(frame_entry)); | 738 new NavigationEntryImpl::TreeNode(frame_entry)); |
729 } | 739 } |
730 | 740 |
731 FrameNavigationEntry* NavigationEntryImpl::GetFrameEntry( | 741 FrameNavigationEntry* NavigationEntryImpl::GetFrameEntry( |
732 FrameTreeNode* frame_tree_node) const { | 742 FrameTreeNode* frame_tree_node) { |
733 NavigationEntryImpl::TreeNode* tree_node = FindFrameEntry(frame_tree_node); | 743 NavigationEntryImpl::TreeNode* tree_node = FindFrameEntry(frame_tree_node); |
734 return tree_node ? tree_node->frame_entry.get() : nullptr; | 744 return tree_node ? tree_node->frame_entry.get() : nullptr; |
735 } | 745 } |
736 | 746 |
737 FrameNavigationEntry* NavigationEntryImpl::GetFrameEntryByUniqueName( | |
738 const std::string& unique_name) const { | |
739 NavigationEntryImpl::TreeNode* node = nullptr; | |
740 std::queue<NavigationEntryImpl::TreeNode*> work_queue; | |
741 work_queue.push(root_node()); | |
742 while (!work_queue.empty()) { | |
743 node = work_queue.front(); | |
744 work_queue.pop(); | |
745 if (node->frame_entry->frame_unique_name() == unique_name) | |
746 return node->frame_entry.get(); | |
747 | |
748 // Enqueue any children and keep looking. | |
749 for (auto& child : node->children) | |
750 work_queue.push(child); | |
751 } | |
752 return nullptr; | |
753 } | |
754 | |
755 void NavigationEntryImpl::SetScreenshotPNGData( | 747 void NavigationEntryImpl::SetScreenshotPNGData( |
756 scoped_refptr<base::RefCountedBytes> png_data) { | 748 scoped_refptr<base::RefCountedBytes> png_data) { |
757 screenshot_ = png_data; | 749 screenshot_ = png_data; |
758 if (screenshot_.get()) | 750 if (screenshot_.get()) |
759 UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); | 751 UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); |
760 } | 752 } |
761 | 753 |
762 GURL NavigationEntryImpl::GetHistoryURLForDataURL() const { | 754 GURL NavigationEntryImpl::GetHistoryURLForDataURL() const { |
763 return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL(); | 755 return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL(); |
764 } | 756 } |
765 | 757 |
766 NavigationEntryImpl::TreeNode* NavigationEntryImpl::FindFrameEntry( | 758 NavigationEntryImpl::TreeNode* NavigationEntryImpl::FindFrameEntry( |
767 FrameTreeNode* frame_tree_node) const { | 759 FrameTreeNode* frame_tree_node) { |
768 NavigationEntryImpl::TreeNode* node = nullptr; | 760 NavigationEntryImpl::TreeNode* node = nullptr; |
769 std::queue<NavigationEntryImpl::TreeNode*> work_queue; | 761 std::queue<NavigationEntryImpl::TreeNode*> work_queue; |
770 work_queue.push(root_node()); | 762 work_queue.push(root_node()); |
771 while (!work_queue.empty()) { | 763 while (!work_queue.empty()) { |
772 node = work_queue.front(); | 764 node = work_queue.front(); |
773 work_queue.pop(); | 765 work_queue.pop(); |
774 if (node->MatchesFrame(frame_tree_node)) { | 766 if (node->MatchesFrame(frame_tree_node)) { |
775 // Only the root TreeNode should have a FTN ID of -1. | 767 // Only the root TreeNode should have a FTN ID of -1. |
776 DCHECK(node->frame_entry->frame_tree_node_id() != -1 || | 768 DCHECK(node->frame_entry->frame_tree_node_id() != -1 || |
777 node == root_node()); | 769 node == root_node()); |
778 return node; | 770 return node; |
779 } | 771 } |
780 // Enqueue any children and keep looking. | 772 // Enqueue any children and keep looking. |
781 for (auto& child : node->children) | 773 for (auto& child : node->children) |
782 work_queue.push(child); | 774 work_queue.push(child); |
783 } | 775 } |
784 return nullptr; | 776 return nullptr; |
785 } | 777 } |
786 | 778 |
787 } // namespace content | 779 } // namespace content |
OLD | NEW |