| 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 <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" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 int NavigationEntryImpl::kInvalidBindings = -1; | 27 int NavigationEntryImpl::kInvalidBindings = -1; |
| 28 | 28 |
| 29 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry) | 29 NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry) |
| 30 : frame_entry(frame_entry) { | 30 : frame_entry(frame_entry) { |
| 31 } | 31 } |
| 32 | 32 |
| 33 NavigationEntryImpl::TreeNode::~TreeNode() { | 33 NavigationEntryImpl::TreeNode::~TreeNode() { |
| 34 } | 34 } |
| 35 | 35 |
| 36 bool NavigationEntryImpl::TreeNode::MatchesFrame( |
| 37 FrameTreeNode* frame_tree_node) const { |
| 38 if (frame_tree_node->frame_tree_node_id() == |
| 39 frame_entry->frame_tree_node_id()) |
| 40 return true; |
| 41 |
| 42 // For now, we set the root FNE's FrameTreeNode ID to -1. |
| 43 return frame_tree_node->IsMainFrame() && |
| 44 frame_entry->frame_tree_node_id() == -1; |
| 45 } |
| 46 |
| 36 NavigationEntryImpl::TreeNode* NavigationEntryImpl::TreeNode::Clone() const { | 47 NavigationEntryImpl::TreeNode* NavigationEntryImpl::TreeNode::Clone() const { |
| 37 // Clone the tree using a copy of the FrameNavigationEntry, without sharing. | 48 // Clone the tree using a copy of the FrameNavigationEntry, without sharing. |
| 38 NavigationEntryImpl::TreeNode* copy = | 49 NavigationEntryImpl::TreeNode* copy = |
| 39 new NavigationEntryImpl::TreeNode(frame_entry->Clone()); | 50 new NavigationEntryImpl::TreeNode(frame_entry->Clone()); |
| 40 | 51 |
| 41 // TODO(creis): Clone children once we add them. | 52 // TODO(creis): Clone children once we add them. |
| 42 return copy; | 53 return copy; |
| 43 } | 54 } |
| 44 | 55 |
| 45 NavigationEntry* NavigationEntry::Create() { | 56 NavigationEntry* NavigationEntry::Create() { |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 } | 423 } |
| 413 | 424 |
| 414 return StartNavigationParams( | 425 return StartNavigationParams( |
| 415 GetHasPostData(), extra_headers(), browser_initiated_post_data, | 426 GetHasPostData(), extra_headers(), browser_initiated_post_data, |
| 416 should_replace_entry(), transferred_global_request_id().child_id, | 427 should_replace_entry(), transferred_global_request_id().child_id, |
| 417 transferred_global_request_id().request_id); | 428 transferred_global_request_id().request_id); |
| 418 } | 429 } |
| 419 | 430 |
| 420 RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams( | 431 RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams( |
| 421 base::TimeTicks navigation_start, | 432 base::TimeTicks navigation_start, |
| 433 bool has_committed_real_load, |
| 422 bool intended_as_new_entry, | 434 bool intended_as_new_entry, |
| 423 int pending_history_list_offset, | 435 int pending_history_list_offset, |
| 424 int current_history_list_offset, | 436 int current_history_list_offset, |
| 425 int current_history_list_length) const { | 437 int current_history_list_length) const { |
| 426 // Set the redirect chain to the navigation's redirects, unless returning to a | 438 // Set the redirect chain to the navigation's redirects, unless returning to a |
| 427 // completed navigation (whose previous redirects don't apply). | 439 // completed navigation (whose previous redirects don't apply). |
| 428 std::vector<GURL> redirects; | 440 std::vector<GURL> redirects; |
| 429 if (ui::PageTransitionIsNewNavigation(GetTransitionType())) { | 441 if (ui::PageTransitionIsNewNavigation(GetTransitionType())) { |
| 430 redirects = GetRedirectChain(); | 442 redirects = GetRedirectChain(); |
| 431 } | 443 } |
| 432 | 444 |
| 433 int pending_offset_to_send = pending_history_list_offset; | 445 int pending_offset_to_send = pending_history_list_offset; |
| 434 int current_offset_to_send = current_history_list_offset; | 446 int current_offset_to_send = current_history_list_offset; |
| 435 int current_length_to_send = current_history_list_length; | 447 int current_length_to_send = current_history_list_length; |
| 436 if (should_clear_history_list()) { | 448 if (should_clear_history_list()) { |
| 437 // Set the history list related parameters to the same values a | 449 // Set the history list related parameters to the same values a |
| 438 // NavigationController would return before its first navigation. This will | 450 // NavigationController would return before its first navigation. This will |
| 439 // fully clear the RenderView's view of the session history. | 451 // fully clear the RenderView's view of the session history. |
| 440 pending_offset_to_send = -1; | 452 pending_offset_to_send = -1; |
| 441 current_offset_to_send = -1; | 453 current_offset_to_send = -1; |
| 442 current_length_to_send = 0; | 454 current_length_to_send = 0; |
| 443 } | 455 } |
| 444 return RequestNavigationParams( | 456 return RequestNavigationParams( |
| 445 GetIsOverridingUserAgent(), navigation_start, redirects, | 457 GetIsOverridingUserAgent(), navigation_start, redirects, |
| 446 GetCanLoadLocalResources(), base::Time::Now(), GetPageState(), | 458 GetCanLoadLocalResources(), base::Time::Now(), GetPageState(), |
| 447 GetPageID(), GetUniqueID(), intended_as_new_entry, pending_offset_to_send, | 459 GetPageID(), GetUniqueID(), has_committed_real_load, |
| 448 current_offset_to_send, current_length_to_send, | 460 intended_as_new_entry, pending_offset_to_send, current_offset_to_send, |
| 449 should_clear_history_list()); | 461 current_length_to_send, should_clear_history_list()); |
| 450 } | 462 } |
| 451 | 463 |
| 452 void NavigationEntryImpl::ResetForCommit() { | 464 void NavigationEntryImpl::ResetForCommit() { |
| 453 // Any state that only matters when a navigation entry is pending should be | 465 // Any state that only matters when a navigation entry is pending should be |
| 454 // cleared here. | 466 // cleared here. |
| 455 // TODO(creis): This state should be moved to NavigationRequest once | 467 // TODO(creis): This state should be moved to NavigationRequest once |
| 456 // PlzNavigate is enabled. | 468 // PlzNavigate is enabled. |
| 457 SetBrowserInitiatedPostData(nullptr); | 469 SetBrowserInitiatedPostData(nullptr); |
| 458 set_source_site_instance(nullptr); | 470 set_source_site_instance(nullptr); |
| 459 set_is_renderer_initiated(false); | 471 set_is_renderer_initiated(false); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 470 #endif | 482 #endif |
| 471 } | 483 } |
| 472 | 484 |
| 473 void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node, | 485 void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node, |
| 474 SiteInstanceImpl* site_instance, | 486 SiteInstanceImpl* site_instance, |
| 475 const GURL& url, | 487 const GURL& url, |
| 476 const Referrer& referrer) { | 488 const Referrer& referrer) { |
| 477 // We should already have a TreeNode for the parent node by the time this node | 489 // We should already have a TreeNode for the parent node by the time this node |
| 478 // commits. Find it first. | 490 // commits. Find it first. |
| 479 DCHECK(frame_tree_node->parent()); | 491 DCHECK(frame_tree_node->parent()); |
| 480 int parent_ftn_id = frame_tree_node->parent()->frame_tree_node_id(); | 492 NavigationEntryImpl::TreeNode* parent_node = |
| 481 bool found = false; | 493 FindFrameEntry(frame_tree_node->parent()); |
| 482 NavigationEntryImpl::TreeNode* parent_node = nullptr; | 494 if (!parent_node) { |
| 483 std::queue<NavigationEntryImpl::TreeNode*> work_queue; | |
| 484 work_queue.push(root_node()); | |
| 485 while (!found && !work_queue.empty()) { | |
| 486 parent_node = work_queue.front(); | |
| 487 work_queue.pop(); | |
| 488 // The root FNE will have an ID of -1, so check for that as well. | |
| 489 if (parent_node->frame_entry->frame_tree_node_id() == parent_ftn_id || | |
| 490 (parent_node->frame_entry->frame_tree_node_id() == -1 && | |
| 491 parent_node == root_node() && | |
| 492 frame_tree_node->parent()->IsMainFrame())) { | |
| 493 found = true; | |
| 494 break; | |
| 495 } | |
| 496 // Enqueue any children and keep looking. | |
| 497 for (auto& child : parent_node->children) | |
| 498 work_queue.push(child); | |
| 499 } | |
| 500 if (!found) { | |
| 501 // The renderer should not send a commit for a subframe before its parent. | 495 // The renderer should not send a commit for a subframe before its parent. |
| 502 // TODO(creis): This can currently happen because we don't yet clone the | 496 // TODO(creis): This can currently happen because we don't yet clone the |
| 503 // FrameNavigationEntry tree on manual subframe navigations. Once that's | 497 // FrameNavigationEntry tree on manual subframe navigations. Once that's |
| 504 // added, we should kill the renderer if we get here. | 498 // added, we should kill the renderer if we get here. |
| 505 return; | 499 return; |
| 506 } | 500 } |
| 507 | 501 |
| 508 // Now check whether we have a TreeNode for the node itself. | 502 // Now check whether we have a TreeNode for the node itself. |
| 509 int frame_tree_node_id = frame_tree_node->frame_tree_node_id(); | 503 int frame_tree_node_id = frame_tree_node->frame_tree_node_id(); |
| 510 for (TreeNode* child : parent_node->children) { | 504 for (TreeNode* child : parent_node->children) { |
| 511 if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) { | 505 if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) { |
| 512 // Update the existing FrameNavigationEntry. | 506 // Update the existing FrameNavigationEntry. |
| 513 child->frame_entry->UpdateEntry(site_instance, url, referrer); | 507 child->frame_entry->UpdateEntry(site_instance, url, referrer); |
| 514 return; | 508 return; |
| 515 } | 509 } |
| 516 } | 510 } |
| 517 | 511 |
| 518 // No entry exists yet, so create a new one. Unordered list, since we expect | 512 // No entry exists yet, so create a new one unless it's for about:blank. |
| 519 // to look up entries by frame sequence number or unique name. | 513 // Unordered list, since we expect to look up entries by frame sequence number |
| 514 // or unique name. |
| 515 if (url == GURL(url::kAboutBlankURL)) |
| 516 return; |
| 520 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( | 517 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( |
| 521 frame_tree_node_id, site_instance, url, referrer); | 518 frame_tree_node_id, site_instance, url, referrer); |
| 522 parent_node->children.push_back( | 519 parent_node->children.push_back( |
| 523 new NavigationEntryImpl::TreeNode(frame_entry)); | 520 new NavigationEntryImpl::TreeNode(frame_entry)); |
| 524 } | 521 } |
| 525 | 522 |
| 523 bool NavigationEntryImpl::HasFrameEntry(FrameTreeNode* frame_tree_node) const { |
| 524 return FindFrameEntry(frame_tree_node) != nullptr; |
| 525 } |
| 526 |
| 526 void NavigationEntryImpl::SetScreenshotPNGData( | 527 void NavigationEntryImpl::SetScreenshotPNGData( |
| 527 scoped_refptr<base::RefCountedBytes> png_data) { | 528 scoped_refptr<base::RefCountedBytes> png_data) { |
| 528 screenshot_ = png_data; | 529 screenshot_ = png_data; |
| 529 if (screenshot_.get()) | 530 if (screenshot_.get()) |
| 530 UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); | 531 UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); |
| 531 } | 532 } |
| 532 | 533 |
| 533 GURL NavigationEntryImpl::GetHistoryURLForDataURL() const { | 534 GURL NavigationEntryImpl::GetHistoryURLForDataURL() const { |
| 534 return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL(); | 535 return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL(); |
| 535 } | 536 } |
| 536 | 537 |
| 538 NavigationEntryImpl::TreeNode* NavigationEntryImpl::FindFrameEntry( |
| 539 FrameTreeNode* frame_tree_node) const { |
| 540 NavigationEntryImpl::TreeNode* node = nullptr; |
| 541 std::queue<NavigationEntryImpl::TreeNode*> work_queue; |
| 542 work_queue.push(root_node()); |
| 543 while (!work_queue.empty()) { |
| 544 node = work_queue.front(); |
| 545 work_queue.pop(); |
| 546 if (node->MatchesFrame(frame_tree_node)) { |
| 547 // Only the root TreeNode should have a FTN ID of -1. |
| 548 DCHECK_IMPLIES(node->frame_entry->frame_tree_node_id() == -1, |
| 549 node == root_node()); |
| 550 return node; |
| 551 } |
| 552 // Enqueue any children and keep looking. |
| 553 for (auto& child : node->children) |
| 554 work_queue.push(child); |
| 555 } |
| 556 return nullptr; |
| 557 } |
| 558 |
| 537 } // namespace content | 559 } // namespace content |
| OLD | NEW |