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

Side by Side 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 unified diff | Download patch
OLDNEW
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 <queue> 7 #include <queue>
8 8
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "components/url_formatter/url_formatter.h" 12 #include "components/url_formatter/url_formatter.h"
13 #include "content/common/navigation_params.h" 13 #include "content/common/navigation_params.h"
14 #include "content/common/page_state_serialization.h" 14 #include "content/common/page_state_serialization.h"
15 #include "content/common/site_isolation_policy.h" 15 #include "content/common/site_isolation_policy.h"
16 #include "content/public/common/content_constants.h" 16 #include "content/public/common/content_constants.h"
17 #include "content/public/common/url_constants.h" 17 #include "content/public/common/url_constants.h"
18 #include "ui/gfx/text_elider.h" 18 #include "ui/gfx/text_elider.h"
19 19
20 using base::UTF16ToUTF8;
21
22 namespace content {
23
24 namespace {
25
20 // Use this to get a new unique ID for a NavigationEntry during construction. 26 // Use this to get a new unique ID for a NavigationEntry during construction.
21 // The returned ID is guaranteed to be nonzero (which is the "no ID" indicator). 27 // The returned ID is guaranteed to be nonzero (which is the "no ID" indicator).
22 static int GetUniqueIDInConstructor() { 28 static int GetUniqueIDInConstructor() {
23 static int unique_id_counter = 0; 29 static int unique_id_counter = 0;
24 return ++unique_id_counter; 30 return ++unique_id_counter;
25 } 31 }
26 32
27 namespace content { 33 void RecursivelyGenerateFrameEntries(const ExplodedFrameState& state,
34 NavigationEntryImpl::TreeNode* node) {
35 node->frame_entry = new FrameNavigationEntry(
36 -1, UTF16ToUTF8(state.target.string()), state.item_sequence_number,
37 state.document_sequence_number, nullptr, GURL(state.url_string.string()),
38 Referrer(GURL(state.referrer.string()), state.referrer_policy));
39
40 node->frame_entry->set_frame_state(state);
41
42 for (const ExplodedFrameState& child_state : state.children) {
43 NavigationEntryImpl::TreeNode* child_node =
44 new NavigationEntryImpl::TreeNode(nullptr);
45 node->children.push_back(child_node);
46 RecursivelyGenerateFrameEntries(child_state, child_node);
47 }
48 }
49
50 void RecursivelyGenerateFrameState(
51 NavigationEntryImpl::TreeNode* node,
52 ExplodedFrameState* state,
53 std::vector<base::NullableString16>* referenced_files) {
54 // Copy the FrameNavigationEntry's frame state into the destination state.
55 *state = node->frame_entry->frame_state();
56
57 // TODO(creis): Copy the referenced files from frame_entry into
58 // referenced_files (which is from PageState). Need to implement helper.
59 // ToNullableString16Vector(node->frame_entry->referenced_files(),
60 // referenced_files);
61
62 state->children.resize(node->children.size());
63 for (size_t i = 0; i < node->children.size(); ++i) {
64 RecursivelyGenerateFrameState(node->children[i], &state->children[i],
65 referenced_files);
66 }
67 }
68
69 } // namespace
28 70
29 int NavigationEntryImpl::kInvalidBindings = -1; 71 int NavigationEntryImpl::kInvalidBindings = -1;
30 72
31 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry) 73 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry)
32 : frame_entry(frame_entry) { 74 : frame_entry(frame_entry) {
33 } 75 }
34 76
35 NavigationEntryImpl::TreeNode::~TreeNode() { 77 NavigationEntryImpl::TreeNode::~TreeNode() {
36 } 78 }
37 79
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 void NavigationEntryImpl::SetTitle(const base::string16& title) { 215 void NavigationEntryImpl::SetTitle(const base::string16& title) {
174 title_ = title; 216 title_ = title;
175 cached_display_title_.clear(); 217 cached_display_title_.clear();
176 } 218 }
177 219
178 const base::string16& NavigationEntryImpl::GetTitle() const { 220 const base::string16& NavigationEntryImpl::GetTitle() const {
179 return title_; 221 return title_;
180 } 222 }
181 223
182 void NavigationEntryImpl::SetPageState(const PageState& state) { 224 void NavigationEntryImpl::SetPageState(const PageState& state) {
183 frame_tree_->frame_entry->set_page_state(state); 225 page_state_ = state;
184 226
185 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { 227 if (!SiteIsolationPolicy::UseSubframeNavigationEntries())
186 // Also get the root ISN and DSN out of the PageState. 228 return;
187 ExplodedPageState exploded_state; 229
188 if (!DecodePageState(state.ToEncodedData(), &exploded_state)) 230 // This should only be called when restoring a NavigationEntry, so there
189 return; 231 // should be no subframe FrameNavigationEntries yet.
190 frame_tree_->frame_entry->set_item_sequence_number( 232 DCHECK_EQ(0U, frame_tree_->children.size());
191 exploded_state.top.item_sequence_number); 233
192 frame_tree_->frame_entry->set_document_sequence_number( 234 ExplodedPageState exploded_state;
193 exploded_state.top.document_sequence_number); 235 if (!DecodePageState(state.ToEncodedData(), &exploded_state)) {
236 // Give up and set an empty ExplodedFrameState on the main frame.
237 frame_tree_->frame_entry->set_frame_state(ExplodedFrameState());
238 return;
194 } 239 }
240
241 RecursivelyGenerateFrameEntries(exploded_state.top, frame_tree_.get());
195 } 242 }
196 243
197 const PageState& NavigationEntryImpl::GetPageState() const { 244 const PageState& NavigationEntryImpl::GetPageState() const {
198 return frame_tree_->frame_entry->page_state(); 245 return page_state_;
246 }
247
248 void NavigationEntryImpl::UpdatePageState() {
249 // When we're using subframe entries, each FrameNavigationEntry has a
250 // frame-specific PageState. We combine these into an ExplodedPageState tree
251 // and generate a full PageState from it.
252 DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
253 ExplodedPageState exploded_state;
254 RecursivelyGenerateFrameState(frame_tree_.get(), &exploded_state.top,
255 &exploded_state.referenced_files);
256
257 std::string encoded_data;
258 if (!EncodePageState(exploded_state, &encoded_data)) {
259 page_state_ = PageState();
260 return;
261 }
262
263 page_state_ = PageState::CreateFromEncodedData(encoded_data);
199 } 264 }
200 265
201 void NavigationEntryImpl::SetPageID(int page_id) { 266 void NavigationEntryImpl::SetPageID(int page_id) {
202 page_id_ = page_id; 267 page_id_ = page_id;
203 } 268 }
204 269
205 int32 NavigationEntryImpl::GetPageID() const { 270 int32 NavigationEntryImpl::GetPageID() const {
206 return page_id_; 271 return page_id_;
207 } 272 }
208 273
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 int current_offset_to_send = current_history_list_offset; 576 int current_offset_to_send = current_history_list_offset;
512 int current_length_to_send = current_history_list_length; 577 int current_length_to_send = current_history_list_length;
513 if (should_clear_history_list()) { 578 if (should_clear_history_list()) {
514 // Set the history list related parameters to the same values a 579 // Set the history list related parameters to the same values a
515 // NavigationController would return before its first navigation. This will 580 // NavigationController would return before its first navigation. This will
516 // fully clear the RenderView's view of the session history. 581 // fully clear the RenderView's view of the session history.
517 pending_offset_to_send = -1; 582 pending_offset_to_send = -1;
518 current_offset_to_send = -1; 583 current_offset_to_send = -1;
519 current_length_to_send = 0; 584 current_length_to_send = 0;
520 } 585 }
586
587 // Use the actual PageState in default Chrome, and only send the frame state
588 // in OOPIF modes.
589 PageState page_state = SiteIsolationPolicy::UseSubframeNavigationEntries()
590 ? PageState()
591 : GetPageState();
592
521 return RequestNavigationParams( 593 return RequestNavigationParams(
522 GetIsOverridingUserAgent(), redirects, GetCanLoadLocalResources(), 594 GetIsOverridingUserAgent(), redirects, GetCanLoadLocalResources(),
523 base::Time::Now(), frame_entry.page_state(), GetPageID(), GetUniqueID(), 595 base::Time::Now(), page_state, frame_entry.frame_state(), GetPageID(),
524 is_same_document_history_load, has_committed_real_load, 596 GetUniqueID(), is_same_document_history_load, has_committed_real_load,
525 intended_as_new_entry, pending_offset_to_send, current_offset_to_send, 597 intended_as_new_entry, pending_offset_to_send, current_offset_to_send,
526 current_length_to_send, should_clear_history_list()); 598 current_length_to_send, should_clear_history_list());
527 } 599 }
528 600
529 void NavigationEntryImpl::ResetForCommit() { 601 void NavigationEntryImpl::ResetForCommit() {
530 // Any state that only matters when a navigation entry is pending should be 602 // Any state that only matters when a navigation entry is pending should be
531 // cleared here. 603 // cleared here.
532 // TODO(creis): This state should be moved to NavigationRequest once 604 // TODO(creis): This state should be moved to NavigationRequest once
533 // PlzNavigate is enabled. 605 // PlzNavigate is enabled.
534 SetBrowserInitiatedPostData(nullptr); 606 SetBrowserInitiatedPostData(nullptr);
(...skipping 13 matching lines...) Expand all
548 } 620 }
549 621
550 void NavigationEntryImpl::AddOrUpdateFrameEntry( 622 void NavigationEntryImpl::AddOrUpdateFrameEntry(
551 FrameTreeNode* frame_tree_node, 623 FrameTreeNode* frame_tree_node,
552 const std::string& frame_unique_name, 624 const std::string& frame_unique_name,
553 int64 item_sequence_number, 625 int64 item_sequence_number,
554 int64 document_sequence_number, 626 int64 document_sequence_number,
555 SiteInstanceImpl* site_instance, 627 SiteInstanceImpl* site_instance,
556 const GURL& url, 628 const GURL& url,
557 const Referrer& referrer, 629 const Referrer& referrer,
558 const PageState& page_state) { 630 const ExplodedFrameState& frame_state) {
559 // We should already have a TreeNode for the parent node by the time this node 631 // We should already have a TreeNode for the parent node by the time this node
560 // commits. Find it first. 632 // commits. Find it first.
561 DCHECK(frame_tree_node->parent()); 633 DCHECK(frame_tree_node->parent());
562 NavigationEntryImpl::TreeNode* parent_node = 634 NavigationEntryImpl::TreeNode* parent_node =
563 FindFrameEntry(frame_tree_node->parent()); 635 FindFrameEntry(frame_tree_node->parent());
564 if (!parent_node) { 636 if (!parent_node) {
565 // The renderer should not send a commit for a subframe before its parent. 637 // The renderer should not send a commit for a subframe before its parent.
566 // TODO(creis): Kill the renderer if we get here. 638 // TODO(creis): Kill the renderer if we get here.
567 return; 639 return;
568 } 640 }
569 641
570 // Now check whether we have a TreeNode for the node itself. 642 // Now check whether we have a TreeNode for the node itself.
571 int frame_tree_node_id = frame_tree_node->frame_tree_node_id(); 643 int frame_tree_node_id = frame_tree_node->frame_tree_node_id();
572 for (TreeNode* child : parent_node->children) { 644 for (TreeNode* child : parent_node->children) {
573 if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) { 645 if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) {
574 // Update the existing FrameNavigationEntry (e.g., for replaceState). 646 // Update the existing FrameNavigationEntry (e.g., for replaceState).
575 child->frame_entry->UpdateEntry(frame_unique_name, item_sequence_number, 647 child->frame_entry->UpdateEntry(frame_unique_name, item_sequence_number,
576 document_sequence_number, site_instance, 648 document_sequence_number, site_instance,
577 url, referrer, page_state); 649 url, referrer, frame_state);
578 return; 650 return;
579 } 651 }
580 } 652 }
581 653
582 // No entry exists yet, so create a new one. 654 // No entry exists yet, so create a new one.
583 // Unordered list, since we expect to look up entries by frame sequence number 655 // Unordered list, since we expect to look up entries by frame sequence number
584 // or unique name. 656 // or unique name.
585 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( 657 FrameNavigationEntry* frame_entry = new FrameNavigationEntry(
586 frame_tree_node_id, frame_unique_name, item_sequence_number, 658 frame_tree_node_id, frame_unique_name, item_sequence_number,
587 document_sequence_number, site_instance, url, referrer); 659 document_sequence_number, site_instance, url, referrer);
588 frame_entry->set_page_state(page_state); 660 frame_entry->set_frame_state(frame_state);
589 parent_node->children.push_back( 661 parent_node->children.push_back(
590 new NavigationEntryImpl::TreeNode(frame_entry)); 662 new NavigationEntryImpl::TreeNode(frame_entry));
591 } 663 }
592 664
593 FrameNavigationEntry* NavigationEntryImpl::GetFrameEntry( 665 FrameNavigationEntry* NavigationEntryImpl::GetFrameEntry(
594 FrameTreeNode* frame_tree_node) const { 666 FrameTreeNode* frame_tree_node) const {
595 NavigationEntryImpl::TreeNode* tree_node = FindFrameEntry(frame_tree_node); 667 NavigationEntryImpl::TreeNode* tree_node = FindFrameEntry(frame_tree_node);
596 return tree_node ? tree_node->frame_entry.get() : nullptr; 668 return tree_node ? tree_node->frame_entry.get() : nullptr;
597 } 669 }
598 670
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 return node; 712 return node;
641 } 713 }
642 // Enqueue any children and keep looking. 714 // Enqueue any children and keep looking.
643 for (auto& child : node->children) 715 for (auto& child : node->children)
644 work_queue.push(child); 716 work_queue.push(child);
645 } 717 }
646 return nullptr; 718 return nullptr;
647 } 719 }
648 720
649 } // namespace content 721 } // namespace content
OLDNEW
« 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