summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcreis <creis@chromium.org>2015-06-19 17:46:30 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-20 00:48:17 +0000
commit4e2ecb71332584b846862653ac1b8ea2490b29b7 (patch)
treeddbd0ed22a53497a6053be63e9636f7824e50180
parentf679b9b026720f58d4e922e911a05506cfa38ee7 (diff)
downloadchromium_src-4e2ecb71332584b846862653ac1b8ea2490b29b7.zip
chromium_src-4e2ecb71332584b846862653ac1b8ea2490b29b7.tar.gz
chromium_src-4e2ecb71332584b846862653ac1b8ea2490b29b7.tar.bz2
Support simple back/forward in out-of-process iframes.
This moves HistoryController::GoToEntry to the browser process for --site-per-process mode, allowing NavigationController to identify all the frames that need to be navigated directly. So far, this only supports navigating a leaf node and not subframes with subtrees of their own. TBR=jam@chromium.org BUG=236848 TEST=In --site-per-process, go back cross-site in a subframe. Review URL: https://codereview.chromium.org/1181983009 Cr-Commit-Position: refs/heads/master@{#335404}
-rw-r--r--content/browser/frame_host/navigation_controller_delegate.h2
-rw-r--r--content/browser/frame_host/navigation_controller_impl.cc193
-rw-r--r--content/browser/frame_host/navigation_controller_impl.h26
-rw-r--r--content/browser/frame_host/navigation_controller_impl_browsertest.cc145
-rw-r--r--content/browser/frame_host/navigation_entry_impl.cc18
-rw-r--r--content/browser/frame_host/navigation_entry_impl.h3
-rw-r--r--content/browser/frame_host/navigation_request.cc8
-rw-r--r--content/browser/frame_host/navigation_request.h3
-rw-r--r--content/browser/frame_host/navigator.cc4
-rw-r--r--content/browser/frame_host/navigator.h5
-rw-r--r--content/browser/frame_host/navigator_impl.cc54
-rw-r--r--content/browser/frame_host/navigator_impl.h18
-rw-r--r--content/browser/frame_host/render_frame_host_manager.cc6
-rw-r--r--content/browser/frame_host/render_frame_host_manager.h4
-rw-r--r--content/browser/frame_host/render_frame_host_manager_unittest.cc9
-rw-r--r--content/browser/web_contents/web_contents_impl.cc21
-rw-r--r--content/browser/web_contents/web_contents_impl.h13
-rw-r--r--content/common/frame_messages.h1
-rw-r--r--content/common/navigation_params.cc3
-rw-r--r--content/common/navigation_params.h5
-rw-r--r--content/renderer/history_controller.cc2
-rw-r--r--content/renderer/history_controller.h4
-rw-r--r--content/renderer/render_frame_impl.cc51
-rw-r--r--testing/buildbot/chromium.fyi.json14
-rw-r--r--tools/copyright_scanner/third_party_files_whitelist.txt3
25 files changed, 494 insertions, 121 deletions
diff --git a/content/browser/frame_host/navigation_controller_delegate.h b/content/browser/frame_host/navigation_controller_delegate.h
index 9789689..2532d25 100644
--- a/content/browser/frame_host/navigation_controller_delegate.h
+++ b/content/browser/frame_host/navigation_controller_delegate.h
@@ -51,8 +51,6 @@ class NavigationControllerDelegate {
virtual void NotifyBeforeFormRepostWarningShow() = 0;
virtual void NotifyNavigationEntryCommitted(
const LoadCommittedDetails& load_details) = 0;
- virtual bool NavigateToPendingEntry(
- NavigationController::ReloadType reload_type) = 0;
virtual void SetHistoryOffsetAndLength(int history_offset,
int history_length) = 0;
virtual void CopyMaxPageIDsFrom(WebContents* web_contents) = 0;
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index 182e54a..739ca2b 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -2,6 +2,37 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
+ * (http://www.torchmobile.com/)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "base/bind.h"
@@ -24,6 +55,7 @@
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/navigation_entry_screenshot_manager.h"
+#include "content/browser/frame_host/navigator.h"
#include "content/browser/renderer_host/render_view_host_impl.h" // Temporary
#include "content/browser/site_instance_impl.h"
#include "content/common/frame_messages.h"
@@ -695,23 +727,41 @@ void NavigationControllerImpl::LoadURLWithParams(const LoadURLParams& params) {
break;
}
- NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
- CreateNavigationEntry(
- params.url,
- params.referrer,
- params.transition_type,
- params.is_renderer_initiated,
- params.extra_headers,
- browser_context_));
- if (!params.frame_name.empty()) {
- // This is only used for navigating subframes in tests.
- FrameTreeNode* named_frame =
- delegate_->GetFrameTree()->FindByName(params.frame_name);
- if (named_frame)
- entry->set_frame_tree_node_id(named_frame->frame_tree_node_id());
- }
- if (params.frame_tree_node_id != -1)
- entry->set_frame_tree_node_id(params.frame_tree_node_id);
+ NavigationEntryImpl* entry = nullptr;
+
+ // For subframes, create a pending entry with a corresponding frame entry.
+ int frame_tree_node_id = params.frame_tree_node_id;
+ if (frame_tree_node_id != -1 || !params.frame_name.empty()) {
+ FrameTreeNode* node =
+ params.frame_tree_node_id != -1
+ ? delegate_->GetFrameTree()->FindByID(params.frame_tree_node_id)
+ : delegate_->GetFrameTree()->FindByName(params.frame_name);
+ if (node && !node->IsMainFrame()) {
+ DCHECK(GetLastCommittedEntry());
+
+ // Update the FTN ID to use below in case we found a named frame.
+ frame_tree_node_id = node->frame_tree_node_id();
+
+ // In --site-per-process, create an identical NavigationEntry with a
+ // new FrameNavigationEntry for the target subframe.
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSitePerProcess)) {
+ entry = GetLastCommittedEntry()->Clone();
+ entry->SetPageID(-1);
+ entry->AddOrUpdateFrameEntry(node, -1, -1, nullptr, params.url,
+ params.referrer, PageState());
+ }
+ }
+ }
+
+ // Otherwise, create a pending entry for the main frame.
+ if (!entry) {
+ entry = NavigationEntryImpl::FromNavigationEntry(CreateNavigationEntry(
+ params.url, params.referrer, params.transition_type,
+ params.is_renderer_initiated, params.extra_headers, browser_context_));
+ }
+ // Set the FTN ID (only used in non-site-per-process, for tests).
+ entry->set_frame_tree_node_id(frame_tree_node_id);
entry->set_source_site_instance(
static_cast<SiteInstanceImpl*>(params.source_site_instance.get()));
if (params.redirect_chain.size() > 0)
@@ -808,8 +858,9 @@ bool NavigationControllerImpl::RendererDidNavigate(
new_type == NAVIGATION_TYPE_AUTO_SUBFRAME;
ignore_mismatch |= details->type == NAVIGATION_TYPE_NAV_IGNORE &&
new_type == NAVIGATION_TYPE_AUTO_SUBFRAME;
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kSitePerProcess)) {
+ bool is_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSitePerProcess);
+ if (is_site_per_process) {
// We know that the old classifier is wrong for OOPIFs, so use the new one
// in --site-per-process mode.
details->type = new_type;
@@ -877,9 +928,14 @@ bool NavigationControllerImpl::RendererDidNavigate(
NavigationEntryImpl* active_entry = GetLastCommittedEntry();
active_entry->SetTimestamp(timestamp);
active_entry->SetHttpStatusCode(params.http_status_code);
- // TODO(creis): Do this on the frame entry instead, once we have them for
- // manual subframe navigations in --site-per-process.
- active_entry->SetPageState(params.page_state);
+ if (is_site_per_process) {
+ // Update the frame-specific PageState.
+ FrameNavigationEntry* frame_entry =
+ active_entry->GetFrameEntry(rfh->frame_tree_node());
+ frame_entry->set_page_state(params.page_state);
+ } else {
+ active_entry->SetPageState(params.page_state);
+ }
active_entry->SetRedirectChain(params.redirects);
// Use histogram to track memory impact of redirect chain because it's now
@@ -1851,7 +1907,7 @@ void NavigationControllerImpl::NavigateToPendingEntry(ReloadType reload_type) {
// This call does not support re-entrancy. See http://crbug.com/347742.
CHECK(!in_navigate_to_pending_entry_);
in_navigate_to_pending_entry_ = true;
- bool success = delegate_->NavigateToPendingEntry(reload_type);
+ bool success = NavigateToPendingEntryInternal(reload_type);
in_navigate_to_pending_entry_ = false;
if (!success)
@@ -1867,6 +1923,97 @@ void NavigationControllerImpl::NavigateToPendingEntry(ReloadType reload_type) {
}
}
+bool NavigationControllerImpl::NavigateToPendingEntryInternal(
+ ReloadType reload_type) {
+ DCHECK(pending_entry_);
+ FrameTreeNode* root = delegate_->GetFrameTree()->root();
+
+ // In default Chrome, there are no subframe FrameNavigationEntries. Either
+ // navigate the main frame or use the main frame's FrameNavigationEntry to
+ // tell the indicated frame where to go.
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSitePerProcess)) {
+ FrameNavigationEntry* frame_entry = GetPendingEntry()->GetFrameEntry(root);
+ FrameTreeNode* frame = root;
+ int ftn_id = GetPendingEntry()->frame_tree_node_id();
+ if (ftn_id != -1) {
+ frame = delegate_->GetFrameTree()->FindByID(ftn_id);
+ DCHECK(frame);
+ }
+ return frame->navigator()->NavigateToPendingEntry(frame, *frame_entry,
+ reload_type, false);
+ }
+
+ // In --site-per-process, we compare FrameNavigationEntries to see which
+ // frames in the tree need to be navigated.
+ FrameLoadVector same_document_loads;
+ FrameLoadVector different_document_loads;
+ if (GetLastCommittedEntry()) {
+ FindFramesToNavigate(root, &same_document_loads, &different_document_loads);
+ }
+
+ if (same_document_loads.empty() && different_document_loads.empty()) {
+ // If we don't have any frames to navigate at this point, either
+ // (1) there is no previous history entry to compare against, or
+ // (2) we were unable to match any frames by name. In the first case,
+ // doing a different document navigation to the root item is the only valid
+ // thing to do. In the second case, we should have been able to find a
+ // frame to navigate based on names if this were a same document
+ // navigation, so we can safely assume this is the different document case.
+ different_document_loads.push_back(
+ std::make_pair(root, pending_entry_->GetFrameEntry(root)));
+ }
+
+ // If all the frame loads fail, we will discard the pending entry.
+ bool success = false;
+
+ // Send all the same document frame loads before the different document loads.
+ for (const auto& item : same_document_loads) {
+ FrameTreeNode* frame = item.first;
+ success |= frame->navigator()->NavigateToPendingEntry(frame, *item.second,
+ reload_type, true);
+ }
+ for (const auto& item : different_document_loads) {
+ FrameTreeNode* frame = item.first;
+ success |= frame->navigator()->NavigateToPendingEntry(frame, *item.second,
+ reload_type, false);
+ }
+ return success;
+}
+
+void NavigationControllerImpl::FindFramesToNavigate(
+ FrameTreeNode* frame,
+ FrameLoadVector* same_document_loads,
+ FrameLoadVector* different_document_loads) {
+ DCHECK(pending_entry_);
+ DCHECK_GE(last_committed_entry_index_, 0);
+ FrameNavigationEntry* new_item = pending_entry_->GetFrameEntry(frame);
+ FrameNavigationEntry* old_item =
+ GetLastCommittedEntry()->GetFrameEntry(frame);
+ if (!new_item)
+ return;
+
+ // Schedule a load in this frame if the new item isn't for the same item
+ // sequence number in the same SiteInstance.
+ if (!old_item ||
+ new_item->item_sequence_number() != old_item->item_sequence_number() ||
+ new_item->site_instance() != old_item->site_instance()) {
+ if (old_item &&
+ new_item->document_sequence_number() ==
+ old_item->document_sequence_number()) {
+ same_document_loads->push_back(std::make_pair(frame, new_item));
+ } else {
+ different_document_loads->push_back(std::make_pair(frame, new_item));
+ }
+ return;
+ }
+
+ for (size_t i = 0; i < frame->child_count(); i++) {
+ FindFramesToNavigate(frame->child_at(i), same_document_loads,
+ different_document_loads);
+ }
+}
+
void NavigationControllerImpl::NotifyNavigationEntryCommitted(
LoadCommittedDetails* details) {
details->entry = GetLastCommittedEntry();
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h
index 91fb27d..d1f6760 100644
--- a/content/browser/frame_host/navigation_controller_impl.h
+++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -221,6 +221,10 @@ class CONTENT_EXPORT NavigationControllerImpl
FRIEND_TEST_ALL_PREFIXES(TimeSmoother, ManyDuplicates);
FRIEND_TEST_ALL_PREFIXES(TimeSmoother, ClockBackwardsJump);
+ // Used for identifying which frames need to navigate.
+ using FrameLoadVector =
+ std::vector<std::pair<FrameTreeNode*, FrameNavigationEntry*>>;
+
// Helper class to smooth out runs of duplicate timestamps while still
// allowing time to jump backwards.
class CONTENT_EXPORT TimeSmoother {
@@ -235,6 +239,23 @@ class CONTENT_EXPORT NavigationControllerImpl
base::Time high_water_mark_;
};
+ // Causes the controller to load the specified entry. The function assumes
+ // ownership of the pointer since it is put in the navigation list.
+ // NOTE: Do not pass an entry that the controller already owns!
+ void LoadEntry(NavigationEntryImpl* entry);
+
+ // Identifies which frames need to be navigated for the pending
+ // NavigationEntry and instructs their Navigator to navigate them. Returns
+ // whether any frame successfully started a navigation.
+ bool NavigateToPendingEntryInternal(ReloadType reload_type);
+
+ // Recursively identifies which frames need to be navigated for the pending
+ // NavigationEntry, starting at |frame| and exploring its children. Only used
+ // in --site-per-process.
+ void FindFramesToNavigate(FrameTreeNode* frame,
+ FrameLoadVector* sameDocumentLoads,
+ FrameLoadVector* differentDocumentLoads);
+
// Classifies the given renderer navigation (see the NavigationType enum).
NavigationType ClassifyNavigation(
RenderFrameHostImpl* rfh,
@@ -246,11 +267,6 @@ class CONTENT_EXPORT NavigationControllerImpl
RenderFrameHostImpl* rfh,
const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const;
- // Causes the controller to load the specified entry. The function assumes
- // ownership of the pointer since it is put in the navigation list.
- // NOTE: Do not pass an entry that the controller already owns!
- void LoadEntry(NavigationEntryImpl* entry);
-
// Handlers for the different types of navigation types. They will actually
// handle the navigations corresponding to the different NavClasses above.
// They will NOT broadcast the commit notification, that should be handled by
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
index 96fc602..f589ece 100644
--- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -1547,6 +1547,150 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
}
}
+// Verify the tree of FrameNavigationEntries after back/forward navigations in a
+// cross-site subframe.
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ FrameNavigationEntry_SubframeBackForward) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "/navigation_controller/simple_page_1.html"));
+ NavigateToURL(shell(), main_url);
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ // 1. Create a same-site iframe.
+ GURL frame_url(embedded_test_server()->GetURL(
+ "/navigation_controller/simple_page_2.html"));
+ {
+ LoadCommittedCapturer capturer(shell()->web_contents());
+ std::string script = "var iframe = document.createElement('iframe');"
+ "iframe.src = '" + frame_url.spec() + "';"
+ "document.body.appendChild(iframe);";
+ EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), script));
+ capturer.Wait();
+ }
+ NavigationEntryImpl* entry1 = controller.GetLastCommittedEntry();
+
+ // 2. Navigate in the subframe cross-site.
+ GURL frame_url2(embedded_test_server()->GetURL(
+ "foo.com", "/navigation_controller/page_with_links.html"));
+ {
+ FrameNavigateParamsCapturer capturer(root->child_at(0));
+ NavigateFrameToURL(root->child_at(0), frame_url2);
+ capturer.Wait();
+ }
+ EXPECT_EQ(2, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry2 = controller.GetLastCommittedEntry();
+
+ // 3. Navigate in the subframe cross-site again.
+ GURL frame_url3(embedded_test_server()->GetURL(
+ "bar.com", "/navigation_controller/page_with_links.html"));
+ {
+ FrameNavigateParamsCapturer capturer(root->child_at(0));
+ NavigateFrameToURL(root->child_at(0), frame_url3);
+ capturer.Wait();
+ }
+ EXPECT_EQ(3, controller.GetEntryCount());
+ EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+ NavigationEntryImpl* entry3 = controller.GetLastCommittedEntry();
+
+ // 4. Go back in the subframe.
+ {
+ FrameNavigateParamsCapturer capturer(root->child_at(0));
+ shell()->web_contents()->GetController().GoBack();
+ capturer.Wait();
+ EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.params().transition);
+ EXPECT_EQ(NAVIGATION_TYPE_AUTO_SUBFRAME, capturer.details().type);
+ }
+ EXPECT_EQ(3, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(entry2, controller.GetLastCommittedEntry());
+
+ // Verify subframe entries if we're in --site-per-process mode.
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSitePerProcess)) {
+ // The entry should have a new FrameNavigationEntries for the subframe.
+ ASSERT_EQ(1U, entry2->root_node()->children.size());
+ EXPECT_EQ(frame_url2, entry2->root_node()->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry2->root_node()->children.size());
+ }
+
+ // 5. Go back in the subframe again to the parent page's site.
+ {
+ FrameNavigateParamsCapturer capturer(root->child_at(0));
+ shell()->web_contents()->GetController().GoBack();
+ capturer.Wait();
+ EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.params().transition);
+ EXPECT_EQ(NAVIGATION_TYPE_AUTO_SUBFRAME, capturer.details().type);
+ }
+ EXPECT_EQ(3, controller.GetEntryCount());
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(entry1, controller.GetLastCommittedEntry());
+
+ // Verify subframe entries if we're in --site-per-process mode.
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSitePerProcess)) {
+ // The entry should have a new FrameNavigationEntries for the subframe.
+ ASSERT_EQ(1U, entry1->root_node()->children.size());
+ EXPECT_EQ(frame_url, entry1->root_node()->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry1->root_node()->children.size());
+ }
+
+ // 6. Go forward in the subframe cross-site.
+ {
+ FrameNavigateParamsCapturer capturer(root->child_at(0));
+ shell()->web_contents()->GetController().GoForward();
+ capturer.Wait();
+ EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.params().transition);
+ EXPECT_EQ(NAVIGATION_TYPE_AUTO_SUBFRAME, capturer.details().type);
+ }
+ EXPECT_EQ(3, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(entry2, controller.GetLastCommittedEntry());
+
+ // Verify subframe entries if we're in --site-per-process mode.
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSitePerProcess)) {
+ // The entry should have a new FrameNavigationEntries for the subframe.
+ ASSERT_EQ(1U, entry2->root_node()->children.size());
+ EXPECT_EQ(frame_url2, entry2->root_node()->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry2->root_node()->children.size());
+ }
+
+ // 7. Go forward in the subframe again, cross-site.
+ {
+ FrameNavigateParamsCapturer capturer(root->child_at(0));
+ shell()->web_contents()->GetController().GoForward();
+ capturer.Wait();
+ EXPECT_EQ(ui::PAGE_TRANSITION_AUTO_SUBFRAME, capturer.params().transition);
+ EXPECT_EQ(NAVIGATION_TYPE_AUTO_SUBFRAME, capturer.details().type);
+ }
+ EXPECT_EQ(3, controller.GetEntryCount());
+ EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(entry3, controller.GetLastCommittedEntry());
+
+ // Verify subframe entries if we're in --site-per-process mode.
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSitePerProcess)) {
+ // The entry should have a new FrameNavigationEntries for the subframe.
+ ASSERT_EQ(1U, entry3->root_node()->children.size());
+ EXPECT_EQ(frame_url3, entry3->root_node()->children[0]->frame_entry->url());
+ } else {
+ // There are no subframe FrameNavigationEntries by default.
+ EXPECT_EQ(0U, entry3->root_node()->children.size());
+ }
+}
+
// Verifies that item sequence numbers and document sequence numbers update
// properly for main frames and subframes.
IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
@@ -1736,6 +1880,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// Ensure the renderer process does not get confused about the current entry
// due to subframes and replaced entries. See https://crbug.com/480201.
+// TODO(creis): Re-enable for Site Isolation FYI bots: https://crbug.com/502317.
IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
PreventSpoofFromSubframeAndReplace) {
// Start at an initial URL.
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc
index dd9a97d..e62903a 100644
--- a/content/browser/frame_host/navigation_entry_impl.cc
+++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -417,6 +417,7 @@ NavigationEntryImpl* NavigationEntryImpl::CloneAndReplace(
}
CommonNavigationParams NavigationEntryImpl::ConstructCommonNavigationParams(
+ const FrameNavigationEntry& frame_entry,
FrameMsg_Navigate_Type::Value navigation_type) const {
FrameMsg_UILoadMetricsReportType::Value report_type =
FrameMsg_UILoadMetricsReportType::NO_REPORT;
@@ -428,9 +429,9 @@ CommonNavigationParams NavigationEntryImpl::ConstructCommonNavigationParams(
#endif
return CommonNavigationParams(
- GetURL(), GetReferrer(), GetTransitionType(), navigation_type,
- !IsViewSourceMode(), ui_timestamp, report_type, GetBaseURLForDataURL(),
- GetHistoryURLForDataURL());
+ frame_entry.url(), frame_entry.referrer(), GetTransitionType(),
+ navigation_type, !IsViewSourceMode(), ui_timestamp, report_type,
+ GetBaseURLForDataURL(), GetHistoryURLForDataURL());
}
StartNavigationParams NavigationEntryImpl::ConstructStartNavigationParams()
@@ -450,7 +451,9 @@ StartNavigationParams NavigationEntryImpl::ConstructStartNavigationParams()
}
RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
+ const FrameNavigationEntry& frame_entry,
base::TimeTicks navigation_start,
+ bool is_same_document_history_load,
bool has_committed_real_load,
bool intended_as_new_entry,
int pending_history_list_offset,
@@ -476,10 +479,11 @@ RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
}
return RequestNavigationParams(
GetIsOverridingUserAgent(), navigation_start, redirects,
- GetCanLoadLocalResources(), base::Time::Now(), GetPageState(),
- GetPageID(), GetUniqueID(), has_committed_real_load,
- intended_as_new_entry, pending_offset_to_send, current_offset_to_send,
- current_length_to_send, should_clear_history_list());
+ GetCanLoadLocalResources(), base::Time::Now(), frame_entry.page_state(),
+ GetPageID(), GetUniqueID(), is_same_document_history_load,
+ has_committed_real_load, intended_as_new_entry, pending_offset_to_send,
+ current_offset_to_send, current_length_to_send,
+ should_clear_history_list());
}
void NavigationEntryImpl::ResetForCommit() {
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h
index 63fa5e0..816a2e5 100644
--- a/content/browser/frame_host/navigation_entry_impl.h
+++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -142,10 +142,13 @@ class CONTENT_EXPORT NavigationEntryImpl
// Helper functions to construct NavigationParameters for a navigation to this
// NavigationEntry.
CommonNavigationParams ConstructCommonNavigationParams(
+ const FrameNavigationEntry& frame_entry,
FrameMsg_Navigate_Type::Value navigation_type) const;
StartNavigationParams ConstructStartNavigationParams() const;
RequestNavigationParams ConstructRequestNavigationParams(
+ const FrameNavigationEntry& frame_entry,
base::TimeTicks navigation_start,
+ bool is_same_document_history_load,
bool has_committed_real_load,
bool intended_as_new_entry,
int pending_offset_to_send,
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 8d9a206..c78a995 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -61,8 +61,10 @@ bool NavigationRequest::ShouldMakeNetworkRequest(const GURL& url) {
// static
scoped_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
FrameTreeNode* frame_tree_node,
+ const FrameNavigationEntry& frame_entry,
const NavigationEntryImpl& entry,
FrameMsg_Navigate_Type::Value navigation_type,
+ bool is_same_document_history_load,
base::TimeTicks navigation_start,
NavigationControllerImpl* controller) {
std::string method = entry.GetHasPostData() ? "POST" : "GET";
@@ -87,11 +89,13 @@ scoped_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
}
scoped_ptr<NavigationRequest> navigation_request(new NavigationRequest(
- frame_tree_node, entry.ConstructCommonNavigationParams(navigation_type),
+ frame_tree_node,
+ entry.ConstructCommonNavigationParams(frame_entry, navigation_type),
BeginNavigationParams(method, headers.ToString(),
LoadFlagFromNavigationType(navigation_type), false),
entry.ConstructRequestNavigationParams(
- navigation_start, controller->HasCommittedRealLoad(frame_tree_node),
+ frame_entry, navigation_start, is_same_document_history_load,
+ controller->HasCommittedRealLoad(frame_tree_node),
controller->GetPendingEntryIndex() == -1,
controller->GetIndexOfEntry(&entry),
controller->GetLastCommittedEntryIndex(),
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 6cc7dc8..e6f1191 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -16,6 +16,7 @@
namespace content {
+class FrameNavigationEntry;
class FrameTreeNode;
class NavigationControllerImpl;
class NavigationURLLoader;
@@ -61,8 +62,10 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// Creates a request for a browser-intiated navigation.
static scoped_ptr<NavigationRequest> CreateBrowserInitiated(
FrameTreeNode* frame_tree_node,
+ const FrameNavigationEntry& frame_entry,
const NavigationEntryImpl& entry,
FrameMsg_Navigate_Type::Value navigation_type,
+ bool is_same_document_history_load,
base::TimeTicks navigation_start,
NavigationControllerImpl* controller);
diff --git a/content/browser/frame_host/navigator.cc b/content/browser/frame_host/navigator.cc
index 1ca9dfc..de1e0c7 100644
--- a/content/browser/frame_host/navigator.cc
+++ b/content/browser/frame_host/navigator.cc
@@ -20,7 +20,9 @@ NavigationController* Navigator::GetController() {
bool Navigator::NavigateToPendingEntry(
FrameTreeNode* frame_tree_node,
- NavigationController::ReloadType reload_type) {
+ const FrameNavigationEntry& frame_entry,
+ NavigationController::ReloadType reload_type,
+ bool is_same_document_history_load) {
return false;
}
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h
index 986f731..2fbbf11 100644
--- a/content/browser/frame_host/navigator.h
+++ b/content/browser/frame_host/navigator.h
@@ -23,6 +23,7 @@ class TimeTicks;
namespace content {
+class FrameNavigationEntry;
class FrameTreeNode;
class NavigationControllerImpl;
class NavigationEntryImpl;
@@ -88,7 +89,9 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
// initialization of Navigator and NavigationController is properly done.
virtual bool NavigateToPendingEntry(
FrameTreeNode* frame_tree_node,
- NavigationController::ReloadType reload_type);
+ const FrameNavigationEntry& frame_entry,
+ NavigationController::ReloadType reload_type,
+ bool is_same_document_history_load);
// Navigation requests -------------------------------------------------------
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 4b3143d..e5e70ad 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -224,13 +224,15 @@ void NavigatorImpl::DidFailLoadWithError(
bool NavigatorImpl::NavigateToEntry(
FrameTreeNode* frame_tree_node,
+ const FrameNavigationEntry& frame_entry,
const NavigationEntryImpl& entry,
- NavigationController::ReloadType reload_type) {
+ NavigationController::ReloadType reload_type,
+ bool is_same_document_history_load) {
TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry");
// The renderer will reject IPC messages with URLs longer than
// this limit, so don't attempt to navigate with a longer URL.
- if (entry.GetURL().spec().size() > GetMaxURLChars()) {
+ if (frame_entry.url().spec().size() > GetMaxURLChars()) {
LOG(WARNING) << "Refusing to load URL as it exceeds " << GetMaxURLChars()
<< " characters.";
return false;
@@ -248,17 +250,21 @@ bool NavigatorImpl::NavigateToEntry(
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBrowserSideNavigation)) {
navigation_data_.reset(new NavigationMetricsData(
- navigation_start, entry.GetURL(), entry.restore_type()));
- RequestNavigation(frame_tree_node, entry, reload_type, navigation_start);
+ navigation_start, frame_entry.url(), entry.restore_type()));
+ RequestNavigation(frame_tree_node, frame_entry, entry, reload_type,
+ is_same_document_history_load, navigation_start);
// Notify observers about navigation.
- if (delegate_)
- delegate_->DidStartNavigationToPendingEntry(entry.GetURL(), reload_type);
+ if (delegate_) {
+ delegate_->DidStartNavigationToPendingEntry(frame_entry.url(),
+ reload_type);
+ }
return true;
}
- RenderFrameHostImpl* dest_render_frame_host = manager->Navigate(entry);
+ RenderFrameHostImpl* dest_render_frame_host =
+ manager->Navigate(frame_entry, entry);
if (!dest_render_frame_host)
return false; // Unable to create the desired RenderFrameHost.
@@ -267,8 +273,8 @@ bool NavigatorImpl::NavigateToEntry(
// For security, we should never send non-Web-UI URLs to a Web UI renderer.
// Double check that here.
- CheckWebUIRendererDoesNotDisplayNormalURL(
- dest_render_frame_host, entry.GetURL());
+ CheckWebUIRendererDoesNotDisplayNormalURL(dest_render_frame_host,
+ frame_entry.url());
// Notify observers that we will navigate in this RenderFrame.
if (delegate_) {
@@ -286,17 +292,17 @@ bool NavigatorImpl::NavigateToEntry(
dest_render_frame_host->GetProcess()->GetID();
if (!is_transfer_to_same) {
navigation_data_.reset(new NavigationMetricsData(
- navigation_start, entry.GetURL(), entry.restore_type()));
+ navigation_start, frame_entry.url(), entry.restore_type()));
// Create the navigation parameters.
// TODO(vitalybuka): Move this before AboutToNavigateRenderFrame once
// http://crbug.com/408684 is fixed.
FrameMsg_Navigate_Type::Value navigation_type =
GetNavigationType(controller_->GetBrowserContext(), entry, reload_type);
dest_render_frame_host->Navigate(
- entry.ConstructCommonNavigationParams(navigation_type),
+ entry.ConstructCommonNavigationParams(frame_entry, navigation_type),
entry.ConstructStartNavigationParams(),
entry.ConstructRequestNavigationParams(
- navigation_start,
+ frame_entry, navigation_start, is_same_document_history_load,
controller_->HasCommittedRealLoad(frame_tree_node),
controller_->GetPendingEntryIndex() == -1,
controller_->GetIndexOfEntry(&entry),
@@ -317,22 +323,26 @@ bool NavigatorImpl::NavigateToEntry(
// do not generate content. What we really need is a message from the
// renderer telling us that a new page was not created. The same message
// could be used for mailto: URLs and the like.
- if (entry.GetURL().SchemeIs(url::kJavaScriptScheme))
+ if (frame_entry.url().SchemeIs(url::kJavaScriptScheme))
return false;
}
// Notify observers about navigation.
- if (delegate_)
- delegate_->DidStartNavigationToPendingEntry(entry.GetURL(), reload_type);
+ if (delegate_) {
+ delegate_->DidStartNavigationToPendingEntry(frame_entry.url(), reload_type);
+ }
return true;
}
bool NavigatorImpl::NavigateToPendingEntry(
FrameTreeNode* frame_tree_node,
- NavigationController::ReloadType reload_type) {
- return NavigateToEntry(frame_tree_node, *controller_->GetPendingEntry(),
- reload_type);
+ const FrameNavigationEntry& frame_entry,
+ NavigationController::ReloadType reload_type,
+ bool is_same_document_history_load) {
+ return NavigateToEntry(frame_tree_node, frame_entry,
+ *controller_->GetPendingEntry(), reload_type,
+ is_same_document_history_load);
}
void NavigatorImpl::DidNavigate(
@@ -798,8 +808,10 @@ void NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(
// PlzNavigate
void NavigatorImpl::RequestNavigation(
FrameTreeNode* frame_tree_node,
+ const FrameNavigationEntry& frame_entry,
const NavigationEntryImpl& entry,
NavigationController::ReloadType reload_type,
+ bool is_same_document_history_load,
base::TimeTicks navigation_start) {
CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBrowserSideNavigation));
@@ -812,9 +824,9 @@ void NavigatorImpl::RequestNavigation(
FrameMsg_Navigate_Type::Value navigation_type =
GetNavigationType(controller_->GetBrowserContext(), entry, reload_type);
frame_tree_node->CreatedNavigationRequest(
- NavigationRequest::CreateBrowserInitiated(frame_tree_node, entry,
- navigation_type,
- navigation_start, controller_));
+ NavigationRequest::CreateBrowserInitiated(
+ frame_tree_node, frame_entry, entry, navigation_type,
+ is_same_document_history_load, navigation_start, controller_));
NavigationRequest* navigation_request = frame_tree_node->navigation_request();
// Have the current renderer execute its beforeunload event if needed. If it
diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h
index 05573a4..6402a55 100644
--- a/content/browser/frame_host/navigator_impl.h
+++ b/content/browser/frame_host/navigator_impl.h
@@ -49,9 +49,10 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
void DidNavigate(RenderFrameHostImpl* render_frame_host,
const FrameHostMsg_DidCommitProvisionalLoad_Params&
input_params) override;
- bool NavigateToPendingEntry(
- FrameTreeNode* frame_tree_node,
- NavigationController::ReloadType reload_type) override;
+ bool NavigateToPendingEntry(FrameTreeNode* frame_tree_node,
+ const FrameNavigationEntry& frame_entry,
+ NavigationController::ReloadType reload_type,
+ bool is_same_document_history_load) override;
void RequestOpenURL(RenderFrameHostImpl* render_frame_host,
const GURL& url,
SiteInstance* source_site_instance,
@@ -97,10 +98,11 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
// Navigates to the given entry, which must be the pending entry. Private
// because all callers should use NavigateToPendingEntry.
- bool NavigateToEntry(
- FrameTreeNode* frame_tree_node,
- const NavigationEntryImpl& entry,
- NavigationController::ReloadType reload_type);
+ bool NavigateToEntry(FrameTreeNode* frame_tree_node,
+ const FrameNavigationEntry& frame_entry,
+ const NavigationEntryImpl& entry,
+ NavigationController::ReloadType reload_type,
+ bool is_same_document_history_load);
bool ShouldAssignSiteForURL(const GURL& url);
@@ -112,8 +114,10 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
// to execute the beforeUnload event. Otherwise, the navigation request will
// be started.
void RequestNavigation(FrameTreeNode* frame_tree_node,
+ const FrameNavigationEntry& frame_entry,
const NavigationEntryImpl& entry,
NavigationController::ReloadType reload_type,
+ bool is_same_document_history_load,
base::TimeTicks navigation_start);
void RecordNavigationMetrics(
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index 6489f69..7bf1733 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -14,6 +14,7 @@
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
#include "content/browser/frame_host/cross_site_transferring_request.h"
#include "content/browser/frame_host/debug_urls.h"
+#include "content/browser/frame_host/frame_navigation_entry.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
@@ -182,12 +183,15 @@ scoped_ptr<WebUIImpl> RenderFrameHostManager::CreateWebUI(const GURL& url,
}
RenderFrameHostImpl* RenderFrameHostManager::Navigate(
+ const FrameNavigationEntry& frame_entry,
const NavigationEntryImpl& entry) {
TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate",
"FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
// Create a pending RenderFrameHost to use for the navigation.
RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate(
- entry.GetURL(), entry.source_site_instance(), entry.site_instance(),
+ frame_entry.url(),
+ // TODO(creis): Move source_site_instance to FNE.
+ entry.source_site_instance(), frame_entry.site_instance(),
entry.GetTransitionType(),
entry.restore_type() != NavigationEntryImpl::RESTORE_NONE,
entry.IsViewSourceMode(), entry.transferred_global_request_id(),
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h
index fd65394..6a5bc8b 100644
--- a/content/browser/frame_host/render_frame_host_manager.h
+++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -25,6 +25,7 @@ namespace content {
class BrowserContext;
class CrossProcessFrameConnector;
class CrossSiteTransferringRequest;
+class FrameNavigationEntry;
class FrameTreeNode;
class InterstitialPageImpl;
class NavigationControllerImpl;
@@ -251,7 +252,8 @@ class CONTENT_EXPORT RenderFrameHostManager : public NotificationObserver {
// navigation entry. It may create a new RenderFrameHost or re-use an existing
// one. The RenderFrameHost to navigate will be returned. Returns NULL if one
// could not be created.
- RenderFrameHostImpl* Navigate(const NavigationEntryImpl& entry);
+ RenderFrameHostImpl* Navigate(const FrameNavigationEntry& frame_entry,
+ const NavigationEntryImpl& entry);
// Instructs the various live views to stop. Called when the user directed the
// page to stop loading.
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index 6bf1476..41d4716 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -419,12 +419,14 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
RenderFrameHostImpl* NavigateToEntry(
RenderFrameHostManager* manager,
const NavigationEntryImpl& entry) {
+ // Tests currently only navigate using main frame FrameNavigationEntries.
+ FrameNavigationEntry* frame_entry = entry.root_node()->frame_entry.get();
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBrowserSideNavigation)) {
scoped_ptr<NavigationRequest> navigation_request =
NavigationRequest::CreateBrowserInitiated(
- manager->frame_tree_node_, entry, FrameMsg_Navigate_Type::NORMAL,
- base::TimeTicks::Now(),
+ manager->frame_tree_node_, *frame_entry, entry,
+ FrameMsg_Navigate_Type::NORMAL, false, base::TimeTicks::Now(),
static_cast<NavigationControllerImpl*>(&controller()));
TestRenderFrameHost* frame_host = static_cast<TestRenderFrameHost*>(
manager->GetFrameHostForNavigation(*navigation_request));
@@ -432,7 +434,8 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
frame_host->set_pending_commit(true);
return frame_host;
}
- return manager->Navigate(entry);
+
+ return manager->Navigate(*frame_entry, entry);
}
// Returns the pending RenderFrameHost.
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 59a443a..390121b 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1991,27 +1991,6 @@ bool WebContentsImpl::Send(IPC::Message* message) {
return GetRenderViewHost()->Send(message);
}
-bool WebContentsImpl::NavigateToPendingEntry(
- NavigationController::ReloadType reload_type) {
- FrameTreeNode* node = frame_tree_.root();
-
- // Navigate in the FrameTreeNode specified in the pending entry, if any. This
- // is currently only used in --site-per-process and tests
- // (e.g., NavigateFrameToURL).
- // TODO(creis): Remove this method and NavigationEntryImpl::frame_tree_node_id
- // by using FrameNavigationEntries instead. See https://crbug.com/236848.
- NavigationEntryImpl* pending_entry = controller_.GetPendingEntry();
- if (pending_entry->frame_tree_node_id() != -1) {
- FrameTreeNode* subframe =
- frame_tree_.FindByID(pending_entry->frame_tree_node_id());
- DCHECK(subframe);
- if (subframe)
- node = subframe;
- }
-
- return node->navigator()->NavigateToPendingEntry(node, reload_type);
-}
-
void WebContentsImpl::RenderFrameForInterstitialPageCreated(
RenderFrameHost* render_frame_host) {
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 75f3e63..eb2cb6e 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -631,19 +631,6 @@ class CONTENT_EXPORT WebContentsImpl
// |web_contents|.
void CopyMaxPageIDsFrom(WebContents* web_contents) override;
- // Called by the NavigationController to cause the WebContentsImpl to navigate
- // to the current pending entry. The NavigationController should be called
- // back with RendererDidNavigate on success or DiscardPendingEntry on failure.
- // The callbacks can be inside of this function, or at some future time.
- //
- // The entry has a PageID of -1 if newly created (corresponding to navigation
- // to a new URL).
- //
- // If this method returns false, then the navigation is discarded (equivalent
- // to calling DiscardPendingEntry on the NavigationController).
- bool NavigateToPendingEntry(
- NavigationController::ReloadType reload_type) override;
-
// Sets the history for this WebContentsImpl to |history_length| entries, with
// an offset of |history_offset|.
void SetHistoryOffsetAndLength(int history_offset,
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 1db78bf..999c3e5 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -290,6 +290,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::RequestNavigationParams)
IPC_STRUCT_TRAITS_MEMBER(page_state)
IPC_STRUCT_TRAITS_MEMBER(page_id)
IPC_STRUCT_TRAITS_MEMBER(nav_entry_id)
+ IPC_STRUCT_TRAITS_MEMBER(is_same_document_history_load)
IPC_STRUCT_TRAITS_MEMBER(has_committed_real_load)
IPC_STRUCT_TRAITS_MEMBER(intended_as_new_entry)
IPC_STRUCT_TRAITS_MEMBER(pending_history_list_offset)
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc
index 33d1c8e..8b70c8f 100644
--- a/content/common/navigation_params.cc
+++ b/content/common/navigation_params.cc
@@ -85,6 +85,7 @@ RequestNavigationParams::RequestNavigationParams()
request_time(base::Time::Now()),
page_id(-1),
nav_entry_id(0),
+ is_same_document_history_load(false),
has_committed_real_load(false),
intended_as_new_entry(false),
pending_history_list_offset(-1),
@@ -102,6 +103,7 @@ RequestNavigationParams::RequestNavigationParams(
const PageState& page_state,
int32 page_id,
int nav_entry_id,
+ bool is_same_document_history_load,
bool has_committed_real_load,
bool intended_as_new_entry,
int pending_history_list_offset,
@@ -116,6 +118,7 @@ RequestNavigationParams::RequestNavigationParams(
page_state(page_state),
page_id(page_id),
nav_entry_id(nav_entry_id),
+ is_same_document_history_load(is_same_document_history_load),
has_committed_real_load(has_committed_real_load),
intended_as_new_entry(intended_as_new_entry),
pending_history_list_offset(pending_history_list_offset),
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h
index 8059471..86e5e06 100644
--- a/content/common/navigation_params.h
+++ b/content/common/navigation_params.h
@@ -170,6 +170,7 @@ struct CONTENT_EXPORT RequestNavigationParams {
const PageState& page_state,
int32 page_id,
int nav_entry_id,
+ bool is_same_document_history_load,
bool has_committed_real_load,
bool intended_as_new_entry,
int pending_history_list_offset,
@@ -212,6 +213,10 @@ struct CONTENT_EXPORT RequestNavigationParams {
// the resulting FrameHostMsg_DidCommitProvisionalLoad message.
int nav_entry_id;
+ // For history navigations, this indicates whether the load will stay within
+ // the same document. Defaults to false.
+ bool is_same_document_history_load;
+
// Whether the frame being navigated has already committed a real page, which
// affects how new navigations are classified in the renderer process.
// This currently is only ever set to true in --site-per-process mode.
diff --git a/content/renderer/history_controller.cc b/content/renderer/history_controller.cc
index fd56623..0eb220b 100644
--- a/content/renderer/history_controller.cc
+++ b/content/renderer/history_controller.cc
@@ -62,7 +62,7 @@ void HistoryController::GoToEntry(
HistoryFrameLoadVector same_document_loads;
HistoryFrameLoadVector different_document_loads;
- provisional_entry_ = target_entry.Pass();
+ set_provisional_entry(target_entry.Pass());
navigation_params_ = navigation_params.Pass();
WebFrame* main_frame = render_view_->GetMainRenderFrame()->GetWebFrame();
diff --git a/content/renderer/history_controller.h b/content/renderer/history_controller.h
index 0a46eef..095836c 100644
--- a/content/renderer/history_controller.h
+++ b/content/renderer/history_controller.h
@@ -110,6 +110,10 @@ class CONTENT_EXPORT HistoryController {
explicit HistoryController(RenderViewImpl* render_view);
~HistoryController();
+ void set_provisional_entry(scoped_ptr<HistoryEntry> entry) {
+ provisional_entry_ = entry.Pass();
+ }
+
void GoToEntry(scoped_ptr<HistoryEntry> entry,
scoped_ptr<NavigationParams> navigation_params,
blink::WebURLRequest::CachePolicy cache_policy);
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 36ed29a..f43d444 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -3868,10 +3868,18 @@ void RenderFrameImpl::SendDidCommitProvisionalLoad(
// Make navigation state a part of the DidCommitProvisionalLoad message so
// that committed entry has it at all times.
HistoryEntry* entry = render_view_->history_controller()->GetCurrentEntry();
- if (entry)
- params.page_state = HistoryEntryToPageState(entry);
- else
- params.page_state = PageState::CreateFromURL(request.url());
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSitePerProcess)) {
+ if (entry)
+ params.page_state = HistoryEntryToPageState(entry);
+ else
+ params.page_state = PageState::CreateFromURL(request.url());
+ } else {
+ // In --site-per-process, just send a single HistoryItem for this frame,
+ // rather than the whole tree. It will be stored in the corresponding
+ // FrameNavigationEntry.
+ params.page_state = SingleHistoryItemToPageState(item);
+ }
params.item_sequence_number = item.itemSequenceNumber();
params.document_sequence_number = item.documentSequenceNumber();
@@ -4424,8 +4432,39 @@ void RenderFrameImpl::NavigateInternal(
if (!browser_side_navigation) {
scoped_ptr<NavigationParams> navigation_params(
new NavigationParams(*pending_navigation_params_.get()));
- render_view_->history_controller()->GoToEntry(
- entry.Pass(), navigation_params.Pass(), cache_policy);
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSitePerProcess)) {
+ // By default, tell the HistoryController to go the deserialized
+ // HistoryEntry. This only works if all frames are in the same
+ // process.
+ DCHECK(!frame_->parent());
+ render_view_->history_controller()->GoToEntry(
+ entry.Pass(), navigation_params.Pass(), cache_policy);
+ } else {
+ // In --site-per-process, the browser process sends a single
+ // WebHistoryItem destined for this frame.
+ // TODO(creis): Change PageState to FrameState. In the meantime, we
+ // store the relevant frame's WebHistoryItem in the root of the
+ // PageState.
+ SetPendingNavigationParams(navigation_params.Pass());
+ blink::WebHistoryItem history_item = entry->root();
+ blink::WebHistoryLoadType load_type =
+ request_params.is_same_document_history_load
+ ? blink::WebHistorySameDocumentLoad
+ : blink::WebHistoryDifferentDocumentLoad;
+
+ // Let the history controller know the provisional entry, since it is
+ // used at commit time. Otherwise skip GoToEntry and navigate the
+ // frame directly.
+ // TODO(creis): Consider cloning the current entry to handle subframe
+ // cases. Changes to SendUpdateState might affect this.
+ render_view_->history_controller()->set_provisional_entry(
+ entry.Pass());
+ WebURLRequest request =
+ frame_->requestFromHistoryItem(history_item, cache_policy);
+ frame_->load(request, blink::WebFrameLoadType::BackForward,
+ history_item, load_type);
+ }
} else {
// TODO(clamy): this should be set to the HistoryItem sent by the
// browser once the HistoryController has moved to the browser.
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 4991552..9cb0b24 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -3454,20 +3454,21 @@
{
"args": [
"--site-per-process",
- "--gtest_filter=-AppApiTest.*:BlockedAppApiTest.*:BrowserTest.ClearPendingOnFailUnlessNTP:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeAppAPITest.*:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:DevToolsExperimentalExtensionTest.*:DevToolsExtensionTest.*:DnsProbeBrowserTest.*:ErrorPageTest.*:ExtensionApiTest.ActiveTab:ExtensionApiTest.ContentScriptExtensionIframe:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.ContentScriptExtensionProcess:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionApiTest.WindowOpenPopupIframe:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:ExtensionViewTest.*:InlineLoginUISafeIframeBrowserTest.*:IsolatedAppTest.*:LaunchWebAuthFlowFunctionTest.*:MimeHandlerViewTest.*:*.NewAvatarMenuEnabledInGuestMode:OptionsUIBrowserTest.*:*PDFExtensionTest.*:PhishingClassifierTest.*:PhishingDOMFeatureExtractorTest.*:PlatformAppUrlRedirectorBrowserTest.*:PopupBlockerBrowserTest.*:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.*:ReferrerPolicyTest.*:SSLUITest.*:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewCommonTest.*:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.*:ZoomControllerBrowserTest.*:*.NavigateFromNTPToOptionsInSameTab:*.ProfilesWithoutPagesNotLaunched:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs"
+ "--gtest_filter=-AppApiTest.*:BlockedAppApiTest.*:BrowserTest.ClearPendingOnFailUnlessNTP:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeAppAPITest.*:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:DevToolsExperimentalExtensionTest.*:DevToolsExtensionTest.*:DnsProbeBrowserTest.*:ErrorPageTest.*:ExtensionApiTest.ActiveTab:ExtensionApiTest.ContentScriptExtensionIframe:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.ContentScriptExtensionProcess:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionApiTest.WindowOpenPopupIframe:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:ExtensionViewTest.*:InlineLoginUISafeIframeBrowserTest.*:IsolatedAppTest.*:LaunchWebAuthFlowFunctionTest.*:MimeHandlerViewTest.*:*.NewAvatarMenuEnabledInGuestMode:OptionsUIBrowserTest.*:*PDFExtensionTest.*:PhishingClassifierTest.*:PhishingDOMFeatureExtractorTest.*:PlatformAppUrlRedirectorBrowserTest.*:PopupBlockerBrowserTest.*:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.*:ReferrerPolicyTest.*:*.RestoreCrossSiteWithExistingSiteInstance:*.RestoreTabWithSpecialURLOnBack:SSLUITest.*:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewCommonTest.*:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.*:ZoomControllerBrowserTest.*:*.NavigateFromNTPToOptionsInSameTab:*.ProfilesWithoutPagesNotLaunched:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs"
],
"test": "browser_tests"
},
{
"args": [
"--site-per-process",
- "--gtest_filter=-*.AllowTargetedNavigationsAfterSwap:*.DisownOpener:*.SupportCrossProcessPostMessageWithMessagePort"
+ "--gtest_filter=-*.AllowTargetedNavigationsAfterSwap:*.DisownOpener:*.PreventSpoofFromSubframeAndReplace:SessionHistoryTest.CrossFrameFormBackForward:SessionHistoryTest.FrameBackForward:*.SupportCrossProcessPostMessageWithMessagePort"
],
"test": "content_browsertests"
},
{
"args": [
- "--site-per-process"
+ "--site-per-process",
+ "--gtest_filter=-NavigatorTestWithBrowserSideNavigation.BeginNavigation"
],
"test": "content_unittests"
},
@@ -3484,20 +3485,21 @@
{
"args": [
"--site-per-process",
- "--gtest_filter=-AppApiTest.*:BlockedAppApiTest.*:BrowserTest.ClearPendingOnFailUnlessNTP:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeAppAPITest.*:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:DevToolsExperimentalExtensionTest.*:DevToolsExtensionTest.*:DnsProbeBrowserTest.*:ErrorPageTest.*:ExtensionApiTest.ActiveTab:ExtensionApiTest.ContentScriptExtensionIframe:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.ContentScriptExtensionProcess:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionApiTest.WindowOpenPopupIframe:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:ExtensionViewTest.*:InlineLoginUISafeIframeBrowserTest.*:IsolatedAppTest.*:LaunchWebAuthFlowFunctionTest.*:MimeHandlerViewTest.*:*.NewAvatarMenuEnabledInGuestMode:OptionsUIBrowserTest.*:*PDFExtensionTest.*:PhishingClassifierTest.*:PhishingDOMFeatureExtractorTest.*:PlatformAppUrlRedirectorBrowserTest.*:PopupBlockerBrowserTest.*:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.*:ReferrerPolicyTest.*:SSLUITest.*:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewCommonTest.*:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.*:ZoomControllerBrowserTest.*:*.NavigateFromNTPToOptionsInSameTab:*.ProfilesWithoutPagesNotLaunched:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs"
+ "--gtest_filter=-AppApiTest.*:BlockedAppApiTest.*:BrowserTest.ClearPendingOnFailUnlessNTP:BrowserTest.OtherRedirectsDontForkProcess:BrowserTest.WindowOpenClose:ChromeAppAPITest.*:ChromeRenderProcessHostTest.*:ChromeRenderProcessHostTestWithCommandLine.*:DevToolsExperimentalExtensionTest.*:DevToolsExtensionTest.*:DnsProbeBrowserTest.*:ErrorPageTest.*:ExtensionApiTest.ActiveTab:ExtensionApiTest.ContentScriptExtensionIframe:ExtensionApiTest.ContentScriptOtherExtensions:ExtensionApiTest.ContentScriptExtensionProcess:ExtensionApiTest.Tabs2:ExtensionApiTest.TabsOnUpdated:ExtensionApiTest.WindowOpenPopupIframe:ExtensionOptionsApiTest.ExtensionCanEmbedOwnOptions:ExtensionViewTest.*:InlineLoginUISafeIframeBrowserTest.*:IsolatedAppTest.*:LaunchWebAuthFlowFunctionTest.*:MimeHandlerViewTest.*:*.NewAvatarMenuEnabledInGuestMode:OptionsUIBrowserTest.*:*PDFExtensionTest.*:PhishingClassifierTest.*:PhishingDOMFeatureExtractorTest.*:PlatformAppUrlRedirectorBrowserTest.*:PopupBlockerBrowserTest.*:PrerenderBrowserTest.*:ProcessManagementTest.*:RedirectTest.*:ReferrerPolicyTest.*:*.RestoreCrossSiteWithExistingSiteInstance:*.RestoreTabWithSpecialURLOnBack:SSLUITest.*:WebNavigationApiTest.CrossProcessFragment:WebNavigationApiTest.ServerRedirectSingleProcess:WebNavigationApiTest.CrossProcessHistory:WebViewCommonTest.*:WebViewDPITest.*:WebViewPluginTest.*:WebViewTest.*:ZoomControllerBrowserTest.*:*.NavigateFromNTPToOptionsInSameTab:*.ProfilesWithoutPagesNotLaunched:*.TabMove:*.WhitelistedExtension:*.NewTabPageURL:*.HomepageLocation:RestoreOnStartupPolicyTest*:PhishingClassifierDelegateTest.*:WebUIWebViewBrowserTest*:WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabs"
],
"test": "browser_tests"
},
{
"args": [
"--site-per-process",
- "--gtest_filter=-*.AllowTargetedNavigationsAfterSwap:*.DisownOpener:*.SupportCrossProcessPostMessageWithMessagePort"
+ "--gtest_filter=-*.AllowTargetedNavigationsAfterSwap:*.DisownOpener:*.PreventSpoofFromSubframeAndReplace:SessionHistoryTest.CrossFrameFormBackForward:SessionHistoryTest.FrameBackForward:*.SupportCrossProcessPostMessageWithMessagePort"
],
"test": "content_browsertests"
},
{
"args": [
- "--site-per-process"
+ "--site-per-process",
+ "--gtest_filter=-NavigatorTestWithBrowserSideNavigation.BeginNavigation"
],
"test": "content_unittests"
},
diff --git a/tools/copyright_scanner/third_party_files_whitelist.txt b/tools/copyright_scanner/third_party_files_whitelist.txt
index 16037eb..cfd438a 100644
--- a/tools/copyright_scanner/third_party_files_whitelist.txt
+++ b/tools/copyright_scanner/third_party_files_whitelist.txt
@@ -53,6 +53,9 @@ chrome/utility/importer/nss_decryptor_system_nss.cc
chrome/utility/importer/nss_decryptor_win.h
# Copyright Google Inc; BSD license. Test code only.
chrome/tools/test/generate_mime_tests.pl
+# Copyright Apple Inc, Nokia Corporation and Torch Mobile Inc; BSD license.
+# Contains code moved from third_party/WebKit/.
+content/browser/frame_host/navigation_controller_impl.cc
# Copyright Alf Watt; BSD license. Not used on Android.
content/browser/geolocation/osx_wifi.h
# Copyright Apple Inc and Torch Mobile Inc; BSD license. Moved from