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