Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(610)

Unified Diff: content/browser/frame_host/navigation_entry_impl.cc

Issue 1415603018: OOPIF: Support session restore by combining/splitting frame states. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Clean up and fix bugs Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/frame_host/navigation_entry_impl.cc
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc
index 694985aca8d0ad0a52054082f2eea5f4edd0f5db..44e479ec33c9550a3d11840cc65537753df94395 100644
--- a/content/browser/frame_host/navigation_entry_impl.cc
+++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -17,6 +17,12 @@
#include "content/public/common/url_constants.h"
#include "ui/gfx/text_elider.h"
+using base::UTF16ToUTF8;
+
+namespace content {
+
+namespace {
+
// Use this to get a new unique ID for a NavigationEntry during construction.
// The returned ID is guaranteed to be nonzero (which is the "no ID" indicator).
static int GetUniqueIDInConstructor() {
@@ -24,7 +30,43 @@ static int GetUniqueIDInConstructor() {
return ++unique_id_counter;
}
-namespace content {
+void RecursivelyGenerateFrameEntries(const ExplodedFrameState& state,
+ NavigationEntryImpl::TreeNode* node) {
+ node->frame_entry = new FrameNavigationEntry(
+ -1, UTF16ToUTF8(state.target.string()), state.item_sequence_number,
+ state.document_sequence_number, nullptr, GURL(state.url_string.string()),
+ Referrer(GURL(state.referrer.string()), state.referrer_policy));
+
+ node->frame_entry->set_frame_state(state);
+
+ for (const ExplodedFrameState& child_state : state.children) {
+ NavigationEntryImpl::TreeNode* child_node =
+ new NavigationEntryImpl::TreeNode(nullptr);
+ node->children.push_back(child_node);
+ RecursivelyGenerateFrameEntries(child_state, child_node);
+ }
+}
+
+void RecursivelyGenerateFrameState(
+ NavigationEntryImpl::TreeNode* node,
+ ExplodedFrameState* state,
+ std::vector<base::NullableString16>* referenced_files) {
+ // Copy the FrameNavigationEntry's frame state into the destination state.
+ *state = node->frame_entry->frame_state();
+
+ // TODO(creis): Copy the referenced files from frame_entry into
+ // referenced_files (which is from PageState). Need to implement helper.
+ // ToNullableString16Vector(node->frame_entry->referenced_files(),
+ // referenced_files);
+
+ state->children.resize(node->children.size());
+ for (size_t i = 0; i < node->children.size(); ++i) {
+ RecursivelyGenerateFrameState(node->children[i], &state->children[i],
+ referenced_files);
+ }
+}
+
+} // namespace
int NavigationEntryImpl::kInvalidBindings = -1;
@@ -180,22 +222,45 @@ const base::string16& NavigationEntryImpl::GetTitle() const {
}
void NavigationEntryImpl::SetPageState(const PageState& state) {
- frame_tree_->frame_entry->set_page_state(state);
+ page_state_ = state;
- if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
- // Also get the root ISN and DSN out of the PageState.
- ExplodedPageState exploded_state;
- if (!DecodePageState(state.ToEncodedData(), &exploded_state))
- return;
- frame_tree_->frame_entry->set_item_sequence_number(
- exploded_state.top.item_sequence_number);
- frame_tree_->frame_entry->set_document_sequence_number(
- exploded_state.top.document_sequence_number);
+ if (!SiteIsolationPolicy::UseSubframeNavigationEntries())
+ return;
+
+ // This should only be called when restoring a NavigationEntry, so there
+ // should be no subframe FrameNavigationEntries yet.
+ DCHECK_EQ(0U, frame_tree_->children.size());
+
+ ExplodedPageState exploded_state;
+ if (!DecodePageState(state.ToEncodedData(), &exploded_state)) {
+ // Give up and set an empty ExplodedFrameState on the main frame.
+ frame_tree_->frame_entry->set_frame_state(ExplodedFrameState());
+ return;
}
+
+ RecursivelyGenerateFrameEntries(exploded_state.top, frame_tree_.get());
}
const PageState& NavigationEntryImpl::GetPageState() const {
- return frame_tree_->frame_entry->page_state();
+ return page_state_;
+}
+
+void NavigationEntryImpl::UpdatePageState() {
+ // When we're using subframe entries, each FrameNavigationEntry has a
+ // frame-specific PageState. We combine these into an ExplodedPageState tree
+ // and generate a full PageState from it.
+ DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
+ ExplodedPageState exploded_state;
+ RecursivelyGenerateFrameState(frame_tree_.get(), &exploded_state.top,
+ &exploded_state.referenced_files);
+
+ std::string encoded_data;
+ if (!EncodePageState(exploded_state, &encoded_data)) {
+ page_state_ = PageState();
+ return;
+ }
+
+ page_state_ = PageState::CreateFromEncodedData(encoded_data);
}
void NavigationEntryImpl::SetPageID(int page_id) {
@@ -518,10 +583,17 @@ RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
current_offset_to_send = -1;
current_length_to_send = 0;
}
+
+ // Use the actual PageState in default Chrome, and only send the frame state
+ // in OOPIF modes.
+ PageState page_state = SiteIsolationPolicy::UseSubframeNavigationEntries()
+ ? PageState()
+ : GetPageState();
+
return RequestNavigationParams(
GetIsOverridingUserAgent(), redirects, GetCanLoadLocalResources(),
- base::Time::Now(), frame_entry.page_state(), GetPageID(), GetUniqueID(),
- is_same_document_history_load, has_committed_real_load,
+ base::Time::Now(), page_state, frame_entry.frame_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());
}
@@ -555,7 +627,7 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(
SiteInstanceImpl* site_instance,
const GURL& url,
const Referrer& referrer,
- const PageState& page_state) {
+ const ExplodedFrameState& frame_state) {
// We should already have a TreeNode for the parent node by the time this node
// commits. Find it first.
DCHECK(frame_tree_node->parent());
@@ -574,7 +646,7 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(
// Update the existing FrameNavigationEntry (e.g., for replaceState).
child->frame_entry->UpdateEntry(frame_unique_name, item_sequence_number,
document_sequence_number, site_instance,
- url, referrer, page_state);
+ url, referrer, frame_state);
return;
}
}
@@ -585,7 +657,7 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(
FrameNavigationEntry* frame_entry = new FrameNavigationEntry(
frame_tree_node_id, frame_unique_name, item_sequence_number,
document_sequence_number, site_instance, url, referrer);
- frame_entry->set_page_state(page_state);
+ frame_entry->set_frame_state(frame_state);
parent_node->children.push_back(
new NavigationEntryImpl::TreeNode(frame_entry));
}
« no previous file with comments | « content/browser/frame_host/navigation_entry_impl.h ('k') | content/browser/frame_host/navigation_request.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698