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