| 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 /* | 5 /* |
| 6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
| 9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
| 10 * | 10 * |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 FrameTreeNode* node = | 714 FrameTreeNode* node = |
| 715 params.frame_tree_node_id != -1 | 715 params.frame_tree_node_id != -1 |
| 716 ? delegate_->GetFrameTree()->FindByID(params.frame_tree_node_id) | 716 ? delegate_->GetFrameTree()->FindByID(params.frame_tree_node_id) |
| 717 : delegate_->GetFrameTree()->FindByName(params.frame_name); | 717 : delegate_->GetFrameTree()->FindByName(params.frame_name); |
| 718 if (node && !node->IsMainFrame()) { | 718 if (node && !node->IsMainFrame()) { |
| 719 DCHECK(GetLastCommittedEntry()); | 719 DCHECK(GetLastCommittedEntry()); |
| 720 | 720 |
| 721 // Update the FTN ID to use below in case we found a named frame. | 721 // Update the FTN ID to use below in case we found a named frame. |
| 722 frame_tree_node_id = node->frame_tree_node_id(); | 722 frame_tree_node_id = node->frame_tree_node_id(); |
| 723 | 723 |
| 724 // In --site-per-process, create an identical NavigationEntry with a | 724 // Create an identical NavigationEntry with a new FrameNavigationEntry for |
| 725 // new FrameNavigationEntry for the target subframe. | 725 // the target subframe. |
| 726 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { | 726 entry = GetLastCommittedEntry()->Clone(); |
| 727 entry = GetLastCommittedEntry()->Clone(); | 727 entry->AddOrUpdateFrameEntry( |
| 728 entry->AddOrUpdateFrameEntry( | 728 node, -1, -1, nullptr, |
| 729 node, -1, -1, nullptr, | 729 static_cast<SiteInstanceImpl*>(params.source_site_instance.get()), |
| 730 static_cast<SiteInstanceImpl*>(params.source_site_instance.get()), | 730 params.url, params.referrer, params.redirect_chain, PageState(), |
| 731 params.url, params.referrer, params.redirect_chain, PageState(), | 731 "GET", -1); |
| 732 "GET", -1); | |
| 733 } | |
| 734 } | 732 } |
| 735 } | 733 } |
| 736 | 734 |
| 737 // Otherwise, create a pending entry for the main frame. | 735 // Otherwise, create a pending entry for the main frame. |
| 738 if (!entry) { | 736 if (!entry) { |
| 739 entry = NavigationEntryImpl::FromNavigationEntry(CreateNavigationEntry( | 737 entry = NavigationEntryImpl::FromNavigationEntry(CreateNavigationEntry( |
| 740 params.url, params.referrer, params.transition_type, | 738 params.url, params.referrer, params.transition_type, |
| 741 params.is_renderer_initiated, params.extra_headers, browser_context_)); | 739 params.is_renderer_initiated, params.extra_headers, browser_context_)); |
| 742 entry->set_source_site_instance( | 740 entry->set_source_site_instance( |
| 743 static_cast<SiteInstanceImpl*>(params.source_site_instance.get())); | 741 static_cast<SiteInstanceImpl*>(params.source_site_instance.get())); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 break; | 858 break; |
| 861 case NAVIGATION_TYPE_SAME_PAGE: | 859 case NAVIGATION_TYPE_SAME_PAGE: |
| 862 RendererDidNavigateToSamePage(rfh, params, navigation_handle); | 860 RendererDidNavigateToSamePage(rfh, params, navigation_handle); |
| 863 break; | 861 break; |
| 864 case NAVIGATION_TYPE_NEW_SUBFRAME: | 862 case NAVIGATION_TYPE_NEW_SUBFRAME: |
| 865 RendererDidNavigateNewSubframe(rfh, params, details->is_in_page, | 863 RendererDidNavigateNewSubframe(rfh, params, details->is_in_page, |
| 866 details->did_replace_entry); | 864 details->did_replace_entry); |
| 867 break; | 865 break; |
| 868 case NAVIGATION_TYPE_AUTO_SUBFRAME: | 866 case NAVIGATION_TYPE_AUTO_SUBFRAME: |
| 869 if (!RendererDidNavigateAutoSubframe(rfh, params)) { | 867 if (!RendererDidNavigateAutoSubframe(rfh, params)) { |
| 870 // In UseSubframeNavigationEntries mode, we won't send a notification | 868 // We don't send a notification about auto-subframe PageState during |
| 871 // about auto-subframe PageState during UpdateStateForFrame, since it | 869 // UpdateStateForFrame, since it looks like nothing has changed. Send |
| 872 // looks like nothing has changed. Send it here at commit time instead. | 870 // it here at commit time instead. |
| 873 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) | 871 NotifyEntryChanged(GetLastCommittedEntry()); |
| 874 NotifyEntryChanged(GetLastCommittedEntry()); | |
| 875 return false; | 872 return false; |
| 876 } | 873 } |
| 877 break; | 874 break; |
| 878 case NAVIGATION_TYPE_NAV_IGNORE: | 875 case NAVIGATION_TYPE_NAV_IGNORE: |
| 879 // If a pending navigation was in progress, this canceled it. We should | 876 // If a pending navigation was in progress, this canceled it. We should |
| 880 // discard it and make sure it is removed from the URL bar. After that, | 877 // discard it and make sure it is removed from the URL bar. After that, |
| 881 // there is nothing we can do with this navigation, so we just return to | 878 // there is nothing we can do with this navigation, so we just return to |
| 882 // the caller that nothing has happened. | 879 // the caller that nothing has happened. |
| 883 if (pending_entry_) { | 880 if (pending_entry_) { |
| 884 DiscardNonCommittedEntries(); | 881 DiscardNonCommittedEntries(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 909 // Temporarily generate a minidump to diagnose https://crbug.com/568703. | 906 // Temporarily generate a minidump to diagnose https://crbug.com/568703. |
| 910 base::debug::DumpWithoutCrashing(); | 907 base::debug::DumpWithoutCrashing(); |
| 911 NOTREACHED() << "Shouldn't see an empty PageState at commit."; | 908 NOTREACHED() << "Shouldn't see an empty PageState at commit."; |
| 912 } | 909 } |
| 913 NavigationEntryImpl* active_entry = GetLastCommittedEntry(); | 910 NavigationEntryImpl* active_entry = GetLastCommittedEntry(); |
| 914 active_entry->SetTimestamp(timestamp); | 911 active_entry->SetTimestamp(timestamp); |
| 915 active_entry->SetHttpStatusCode(params.http_status_code); | 912 active_entry->SetHttpStatusCode(params.http_status_code); |
| 916 | 913 |
| 917 FrameNavigationEntry* frame_entry = | 914 FrameNavigationEntry* frame_entry = |
| 918 active_entry->GetFrameEntry(rfh->frame_tree_node()); | 915 active_entry->GetFrameEntry(rfh->frame_tree_node()); |
| 919 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { | 916 // Update the frame-specific PageState and RedirectChain |
| 920 // Update the frame-specific PageState and RedirectChain | 917 // We may not find a frame_entry in some cases; ignore the PageState if so. |
| 921 // We may not find a frame_entry in some cases; ignore the PageState if so. | 918 // TODO(creis): Remove the "if" once https://crbug.com/522193 is fixed. |
| 922 // TODO(creis): Remove the "if" once https://crbug.com/522193 is fixed. | 919 if (frame_entry) { |
| 923 if (frame_entry) { | 920 frame_entry->SetPageState(params.page_state); |
| 924 frame_entry->SetPageState(params.page_state); | 921 frame_entry->set_redirect_chain(params.redirects); |
| 925 frame_entry->set_redirect_chain(params.redirects); | |
| 926 } | |
| 927 } else { | |
| 928 active_entry->SetPageState(params.page_state); | |
| 929 active_entry->SetRedirectChain(params.redirects); | |
| 930 } | 922 } |
| 931 | 923 |
| 932 // Use histogram to track memory impact of redirect chain because it's now | 924 // Use histogram to track memory impact of redirect chain because it's now |
| 933 // not cleared for committed entries. | 925 // not cleared for committed entries. |
| 934 size_t redirect_chain_size = 0; | 926 size_t redirect_chain_size = 0; |
| 935 for (size_t i = 0; i < params.redirects.size(); ++i) { | 927 for (size_t i = 0; i < params.redirects.size(); ++i) { |
| 936 redirect_chain_size += params.redirects[i].spec().length(); | 928 redirect_chain_size += params.redirects[i].spec().length(); |
| 937 } | 929 } |
| 938 UMA_HISTOGRAM_COUNTS("Navigation.RedirectChainSize", redirect_chain_size); | 930 UMA_HISTOGRAM_COUNTS("Navigation.RedirectChainSize", redirect_chain_size); |
| 939 | 931 |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 DCHECK(ui::PageTransitionCoreTypeIs(params.transition, | 1328 DCHECK(ui::PageTransitionCoreTypeIs(params.transition, |
| 1337 ui::PAGE_TRANSITION_MANUAL_SUBFRAME)); | 1329 ui::PAGE_TRANSITION_MANUAL_SUBFRAME)); |
| 1338 | 1330 |
| 1339 // Manual subframe navigations just get the current entry cloned so the user | 1331 // Manual subframe navigations just get the current entry cloned so the user |
| 1340 // can go back or forward to it. The actual subframe information will be | 1332 // can go back or forward to it. The actual subframe information will be |
| 1341 // stored in the page state for each of those entries. This happens out of | 1333 // stored in the page state for each of those entries. This happens out of |
| 1342 // band with the actual navigations. | 1334 // band with the actual navigations. |
| 1343 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " | 1335 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " |
| 1344 << "that a last committed entry exists."; | 1336 << "that a last committed entry exists."; |
| 1345 | 1337 |
| 1346 std::unique_ptr<NavigationEntryImpl> new_entry; | 1338 // Make sure we don't leak frame_entry if new_entry doesn't take ownership. |
| 1347 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { | 1339 scoped_refptr<FrameNavigationEntry> frame_entry(new FrameNavigationEntry( |
| 1348 // Make sure we don't leak frame_entry if new_entry doesn't take ownership. | 1340 params.frame_unique_name, params.item_sequence_number, |
| 1349 scoped_refptr<FrameNavigationEntry> frame_entry(new FrameNavigationEntry( | 1341 params.document_sequence_number, rfh->GetSiteInstance(), nullptr, |
| 1350 params.frame_unique_name, params.item_sequence_number, | 1342 params.url, params.referrer, params.method, params.post_id)); |
| 1351 params.document_sequence_number, rfh->GetSiteInstance(), nullptr, | 1343 std::unique_ptr<NavigationEntryImpl> new_entry = |
| 1352 params.url, params.referrer, params.method, params.post_id)); | 1344 GetLastCommittedEntry()->CloneAndReplace( |
| 1353 new_entry = GetLastCommittedEntry()->CloneAndReplace( | 1345 frame_entry.get(), is_in_page, rfh->frame_tree_node(), |
| 1354 frame_entry.get(), is_in_page, rfh->frame_tree_node(), | 1346 delegate_->GetFrameTree()->root()); |
| 1355 delegate_->GetFrameTree()->root()); | |
| 1356 | 1347 |
| 1357 // TODO(creis): Update this to add the frame_entry if we can't find the one | 1348 // TODO(creis): Update this to add the frame_entry if we can't find the one |
| 1358 // to replace, which can happen due to a unique name change. See | 1349 // to replace, which can happen due to a unique name change. See |
| 1359 // https://crbug.com/607205. For now, frame_entry will be deleted when it | 1350 // https://crbug.com/607205. For now, frame_entry will be deleted when it |
| 1360 // goes out of scope if it doesn't get used. | 1351 // goes out of scope if it doesn't get used. |
| 1361 } else { | |
| 1362 new_entry = GetLastCommittedEntry()->Clone(); | |
| 1363 } | |
| 1364 | 1352 |
| 1365 InsertOrReplaceEntry(std::move(new_entry), replace_entry); | 1353 InsertOrReplaceEntry(std::move(new_entry), replace_entry); |
| 1366 } | 1354 } |
| 1367 | 1355 |
| 1368 bool NavigationControllerImpl::RendererDidNavigateAutoSubframe( | 1356 bool NavigationControllerImpl::RendererDidNavigateAutoSubframe( |
| 1369 RenderFrameHostImpl* rfh, | 1357 RenderFrameHostImpl* rfh, |
| 1370 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1358 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
| 1371 DCHECK(ui::PageTransitionCoreTypeIs(params.transition, | 1359 DCHECK(ui::PageTransitionCoreTypeIs(params.transition, |
| 1372 ui::PAGE_TRANSITION_AUTO_SUBFRAME)); | 1360 ui::PAGE_TRANSITION_AUTO_SUBFRAME)); |
| 1373 | 1361 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1406 // We only need to discard the pending entry in this history navigation | 1394 // We only need to discard the pending entry in this history navigation |
| 1407 // case. For newly created subframes, there was no pending entry. | 1395 // case. For newly created subframes, there was no pending entry. |
| 1408 last_committed_entry_index_ = entry_index; | 1396 last_committed_entry_index_ = entry_index; |
| 1409 DiscardNonCommittedEntriesInternal(); | 1397 DiscardNonCommittedEntriesInternal(); |
| 1410 | 1398 |
| 1411 // History navigations should send a commit notification. | 1399 // History navigations should send a commit notification. |
| 1412 send_commit_notification = true; | 1400 send_commit_notification = true; |
| 1413 } | 1401 } |
| 1414 } | 1402 } |
| 1415 | 1403 |
| 1416 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { | 1404 // This may be a "new auto" case where we add a new FrameNavigationEntry, or |
| 1417 // This may be a "new auto" case where we add a new FrameNavigationEntry, or | 1405 // it may be a "history auto" case where we update an existing one. |
| 1418 // it may be a "history auto" case where we update an existing one. | 1406 NavigationEntryImpl* last_committed = GetLastCommittedEntry(); |
| 1419 NavigationEntryImpl* last_committed = GetLastCommittedEntry(); | 1407 last_committed->AddOrUpdateFrameEntry( |
| 1420 last_committed->AddOrUpdateFrameEntry( | 1408 rfh->frame_tree_node(), params.item_sequence_number, |
| 1421 rfh->frame_tree_node(), params.item_sequence_number, | 1409 params.document_sequence_number, rfh->GetSiteInstance(), nullptr, |
| 1422 params.document_sequence_number, rfh->GetSiteInstance(), nullptr, | 1410 params.url, params.referrer, params.redirects, params.page_state, |
| 1423 params.url, params.referrer, params.redirects, params.page_state, | 1411 params.method, params.post_id); |
| 1424 params.method, params.post_id); | |
| 1425 } | |
| 1426 | 1412 |
| 1427 return send_commit_notification; | 1413 return send_commit_notification; |
| 1428 } | 1414 } |
| 1429 | 1415 |
| 1430 int NavigationControllerImpl::GetIndexOfEntry( | 1416 int NavigationControllerImpl::GetIndexOfEntry( |
| 1431 const NavigationEntryImpl* entry) const { | 1417 const NavigationEntryImpl* entry) const { |
| 1432 for (size_t i = 0; i < entries_.size(); ++i) { | 1418 for (size_t i = 0; i < entries_.size(); ++i) { |
| 1433 if (entries_[i].get() == entry) | 1419 if (entries_[i].get() == entry) |
| 1434 return i; | 1420 return i; |
| 1435 } | 1421 } |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1889 | 1875 |
| 1890 if (!success) | 1876 if (!success) |
| 1891 DiscardNonCommittedEntries(); | 1877 DiscardNonCommittedEntries(); |
| 1892 } | 1878 } |
| 1893 | 1879 |
| 1894 bool NavigationControllerImpl::NavigateToPendingEntryInternal( | 1880 bool NavigationControllerImpl::NavigateToPendingEntryInternal( |
| 1895 ReloadType reload_type) { | 1881 ReloadType reload_type) { |
| 1896 DCHECK(pending_entry_); | 1882 DCHECK(pending_entry_); |
| 1897 FrameTreeNode* root = delegate_->GetFrameTree()->root(); | 1883 FrameTreeNode* root = delegate_->GetFrameTree()->root(); |
| 1898 | 1884 |
| 1899 // In default Chrome, there are no subframe FrameNavigationEntries. Either | 1885 // Compare FrameNavigationEntries to see which frames in the tree need to be |
| 1900 // navigate the main frame or use the main frame's FrameNavigationEntry to | 1886 // navigated. |
| 1901 // tell the indicated frame where to go. | |
| 1902 if (!SiteIsolationPolicy::UseSubframeNavigationEntries()) { | |
| 1903 FrameNavigationEntry* frame_entry = GetPendingEntry()->GetFrameEntry(root); | |
| 1904 FrameTreeNode* frame = root; | |
| 1905 int ftn_id = GetPendingEntry()->frame_tree_node_id(); | |
| 1906 if (ftn_id != -1) { | |
| 1907 frame = delegate_->GetFrameTree()->FindByID(ftn_id); | |
| 1908 DCHECK(frame); | |
| 1909 } | |
| 1910 return frame->navigator()->NavigateToPendingEntry(frame, *frame_entry, | |
| 1911 reload_type, false); | |
| 1912 } | |
| 1913 | |
| 1914 // In --site-per-process, we compare FrameNavigationEntries to see which | |
| 1915 // frames in the tree need to be navigated. | |
| 1916 FrameLoadVector same_document_loads; | 1887 FrameLoadVector same_document_loads; |
| 1917 FrameLoadVector different_document_loads; | 1888 FrameLoadVector different_document_loads; |
| 1918 if (GetLastCommittedEntry()) { | 1889 if (GetLastCommittedEntry()) { |
| 1919 FindFramesToNavigate(root, &same_document_loads, &different_document_loads); | 1890 FindFramesToNavigate(root, &same_document_loads, &different_document_loads); |
| 1920 } | 1891 } |
| 1921 | 1892 |
| 1922 if (same_document_loads.empty() && different_document_loads.empty()) { | 1893 if (same_document_loads.empty() && different_document_loads.empty()) { |
| 1923 // If we don't have any frames to navigate at this point, either | 1894 // If we don't have any frames to navigate at this point, either |
| 1924 // (1) there is no previous history entry to compare against, or | 1895 // (1) there is no previous history entry to compare against, or |
| 1925 // (2) we were unable to match any frames by name. In the first case, | 1896 // (2) we were unable to match any frames by name. In the first case, |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 } | 2134 } |
| 2164 } | 2135 } |
| 2165 } | 2136 } |
| 2166 | 2137 |
| 2167 void NavigationControllerImpl::SetGetTimestampCallbackForTest( | 2138 void NavigationControllerImpl::SetGetTimestampCallbackForTest( |
| 2168 const base::Callback<base::Time()>& get_timestamp_callback) { | 2139 const base::Callback<base::Time()>& get_timestamp_callback) { |
| 2169 get_timestamp_callback_ = get_timestamp_callback; | 2140 get_timestamp_callback_ = get_timestamp_callback; |
| 2170 } | 2141 } |
| 2171 | 2142 |
| 2172 } // namespace content | 2143 } // namespace content |
| OLD | NEW |