| 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 |