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

Side by Side Diff: content/browser/frame_host/navigation_controller_impl.cc

Issue 2810173002: NavigationController: Fix several broken class invariants. (Closed)
Patch Set: Remove DCHECK because of WebContentsImplTest.ShowInterstitialThenNavigate. Created 3 years, 8 months 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
« no previous file with comments | « no previous file | content/public/browser/navigation_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /* 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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 } 272 }
273 273
274 void NavigationControllerImpl::Restore( 274 void NavigationControllerImpl::Restore(
275 int selected_navigation, 275 int selected_navigation,
276 RestoreType type, 276 RestoreType type,
277 std::vector<std::unique_ptr<NavigationEntry>>* entries) { 277 std::vector<std::unique_ptr<NavigationEntry>>* entries) {
278 // Verify that this controller is unused and that the input is valid. 278 // Verify that this controller is unused and that the input is valid.
279 DCHECK(GetEntryCount() == 0 && !GetPendingEntry()); 279 DCHECK(GetEntryCount() == 0 && !GetPendingEntry());
280 DCHECK(selected_navigation >= 0 && 280 DCHECK(selected_navigation >= 0 &&
281 selected_navigation < static_cast<int>(entries->size())); 281 selected_navigation < static_cast<int>(entries->size()));
282 DCHECK_EQ(pending_entry_index_, -1);
Charlie Reis 2017/04/24 03:58:13 nit: Swap order (expected, actual). Same in all t
arthursonzogni 2017/04/24 16:28:17 Done.
282 283
283 needs_reload_ = true; 284 needs_reload_ = true;
284 entries_.reserve(entries->size()); 285 entries_.reserve(entries->size());
285 for (auto& entry : *entries) 286 for (auto& entry : *entries)
286 entries_.push_back( 287 entries_.push_back(
287 NavigationEntryImpl::FromNavigationEntry(std::move(entry))); 288 NavigationEntryImpl::FromNavigationEntry(std::move(entry)));
288 289
289 // At this point, the |entries| is full of empty scoped_ptrs, so it can be 290 // At this point, the |entries| is full of empty scoped_ptrs, so it can be
290 // cleared out safely. 291 // cleared out safely.
291 entries->clear(); 292 entries->clear();
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 NavigationEntryImpl* 441 NavigationEntryImpl*
441 NavigationControllerImpl::GetEntryWithUniqueID(int nav_entry_id) const { 442 NavigationControllerImpl::GetEntryWithUniqueID(int nav_entry_id) const {
442 int index = GetEntryIndexWithUniqueID(nav_entry_id); 443 int index = GetEntryIndexWithUniqueID(nav_entry_id);
443 return (index != -1) ? entries_[index].get() : nullptr; 444 return (index != -1) ? entries_[index].get() : nullptr;
444 } 445 }
445 446
446 void NavigationControllerImpl::LoadEntry( 447 void NavigationControllerImpl::LoadEntry(
447 std::unique_ptr<NavigationEntryImpl> entry) { 448 std::unique_ptr<NavigationEntryImpl> entry) {
448 // Remember the last pending entry for which we haven't received a response 449 // Remember the last pending entry for which we haven't received a response
449 // yet. This will be deleted in the NavigateToPendingEntry() function. 450 // yet. This will be deleted in the NavigateToPendingEntry() function.
451 DCHECK_EQ(last_pending_entry_, nullptr);
452 DCHECK_EQ(last_pending_entry_index_, -1);
450 last_pending_entry_ = pending_entry_; 453 last_pending_entry_ = pending_entry_;
451 last_pending_entry_index_ = pending_entry_index_; 454 last_pending_entry_index_ = pending_entry_index_;
452 last_transient_entry_index_ = transient_entry_index_; 455 last_transient_entry_index_ = transient_entry_index_;
456
453 pending_entry_ = nullptr; 457 pending_entry_ = nullptr;
458 pending_entry_index_ = -1;
454 // When navigating to a new page, we don't know for sure if we will actually 459 // When navigating to a new page, we don't know for sure if we will actually
455 // end up leaving the current page. The new page load could for example 460 // end up leaving the current page. The new page load could for example
456 // result in a download or a 'no content' response (e.g., a mailto: URL). 461 // result in a download or a 'no content' response (e.g., a mailto: URL).
457 SetPendingEntry(std::move(entry)); 462 SetPendingEntry(std::move(entry));
458 NavigateToPendingEntry(ReloadType::NONE); 463 NavigateToPendingEntry(ReloadType::NONE);
459 } 464 }
460 465
461 void NavigationControllerImpl::SetPendingEntry( 466 void NavigationControllerImpl::SetPendingEntry(
462 std::unique_ptr<NavigationEntryImpl> entry) { 467 std::unique_ptr<NavigationEntryImpl> entry) {
463 DiscardNonCommittedEntriesInternal(); 468 DiscardNonCommittedEntriesInternal();
464 pending_entry_ = entry.release(); 469 pending_entry_ = entry.release();
470 DCHECK_EQ(pending_entry_index_, -1);
465 NotificationService::current()->Notify( 471 NotificationService::current()->Notify(
466 NOTIFICATION_NAV_ENTRY_PENDING, 472 NOTIFICATION_NAV_ENTRY_PENDING,
467 Source<NavigationController>(this), 473 Source<NavigationController>(this),
468 Details<NavigationEntry>(pending_entry_)); 474 Details<NavigationEntry>(pending_entry_));
469 } 475 }
470 476
471 NavigationEntryImpl* NavigationControllerImpl::GetActiveEntry() const { 477 NavigationEntryImpl* NavigationControllerImpl::GetActiveEntry() const {
472 if (transient_entry_index_ != -1) 478 if (transient_entry_index_ != -1)
473 return entries_[transient_entry_index_].get(); 479 return entries_[transient_entry_index_].get();
474 if (pending_entry_) 480 if (pending_entry_)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 const std::string& mime_type = delegate_->GetContentsMimeType(); 533 const std::string& mime_type = delegate_->GetContentsMimeType();
528 bool is_viewable_mime_type = 534 bool is_viewable_mime_type =
529 mime_util::IsSupportedNonImageMimeType(mime_type) && 535 mime_util::IsSupportedNonImageMimeType(mime_type) &&
530 !media::IsSupportedMediaMimeType(mime_type); 536 !media::IsSupportedMediaMimeType(mime_type);
531 NavigationEntry* visible_entry = GetVisibleEntry(); 537 NavigationEntry* visible_entry = GetVisibleEntry();
532 return visible_entry && !visible_entry->IsViewSourceMode() && 538 return visible_entry && !visible_entry->IsViewSourceMode() &&
533 is_viewable_mime_type && !delegate_->GetInterstitialPage(); 539 is_viewable_mime_type && !delegate_->GetInterstitialPage();
534 } 540 }
535 541
536 int NavigationControllerImpl::GetLastCommittedEntryIndex() const { 542 int NavigationControllerImpl::GetLastCommittedEntryIndex() const {
543 // The last committed entry index must always be less than the number of
544 // entries. It should be -1 iff there are no entries.
545 DCHECK_LT(last_committed_entry_index_, GetEntryCount());
Charlie Reis 2017/04/24 03:58:13 Can we also include the second DCHECK from my CL (
arthursonzogni 2017/04/24 16:28:17 We can't because: https://codereview.chromium.org/
537 return last_committed_entry_index_; 546 return last_committed_entry_index_;
538 } 547 }
539 548
540 int NavigationControllerImpl::GetEntryCount() const { 549 int NavigationControllerImpl::GetEntryCount() const {
541 DCHECK(entries_.size() <= max_entry_count()); 550 DCHECK_LE(entries_.size(), max_entry_count());
542 return static_cast<int>(entries_.size()); 551 return static_cast<int>(entries_.size());
543 } 552 }
544 553
545 NavigationEntryImpl* NavigationControllerImpl::GetEntryAtIndex( 554 NavigationEntryImpl* NavigationControllerImpl::GetEntryAtIndex(
546 int index) const { 555 int index) const {
547 if (index < 0 || index >= GetEntryCount()) 556 if (index < 0 || index >= GetEntryCount())
548 return nullptr; 557 return nullptr;
549 558
550 return entries_[index].get(); 559 return entries_[index].get();
551 } 560 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 return; 617 return;
609 } 618 }
610 if (index > transient_entry_index_) { 619 if (index > transient_entry_index_) {
611 // Removing the transient is goint to shift all entries by 1. 620 // Removing the transient is goint to shift all entries by 1.
612 index--; 621 index--;
613 } 622 }
614 } 623 }
615 624
616 DiscardNonCommittedEntries(); 625 DiscardNonCommittedEntries();
617 626
627 DCHECK_EQ(pending_entry_, nullptr);
628 DCHECK_EQ(pending_entry_index_, -1);
629 pending_entry_ = entries_[index].get();
618 pending_entry_index_ = index; 630 pending_entry_index_ = index;
619 entries_[pending_entry_index_]->SetTransitionType( 631 pending_entry_->SetTransitionType(ui::PageTransitionFromInt(
620 ui::PageTransitionFromInt( 632 pending_entry_->GetTransitionType() | ui::PAGE_TRANSITION_FORWARD_BACK));
621 entries_[pending_entry_index_]->GetTransitionType() |
622 ui::PAGE_TRANSITION_FORWARD_BACK));
623 NavigateToPendingEntry(ReloadType::NONE); 633 NavigateToPendingEntry(ReloadType::NONE);
624 } 634 }
625 635
626 void NavigationControllerImpl::GoToOffset(int offset) { 636 void NavigationControllerImpl::GoToOffset(int offset) {
627 // Note: This is actually reached in unit tests. 637 // Note: This is actually reached in unit tests.
628 if (!CanGoToOffset(offset)) 638 if (!CanGoToOffset(offset))
629 return; 639 return;
630 640
631 GoToIndex(GetIndexForOffset(offset)); 641 GoToIndex(GetIndexForOffset(offset));
632 } 642 }
(...skipping 1086 matching lines...) Expand 10 before | Expand all | Expand 10 after
1719 DiscardNonCommittedEntriesInternal(); 1729 DiscardNonCommittedEntriesInternal();
1720 1730
1721 // If there was a transient entry, invalidate everything so the new active 1731 // If there was a transient entry, invalidate everything so the new active
1722 // entry state is shown. 1732 // entry state is shown.
1723 if (transient) { 1733 if (transient) {
1724 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL); 1734 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL);
1725 } 1735 }
1726 } 1736 }
1727 1737
1728 NavigationEntryImpl* NavigationControllerImpl::GetPendingEntry() const { 1738 NavigationEntryImpl* NavigationControllerImpl::GetPendingEntry() const {
1739 // If there is no pending_entry_, there should be no pending_entry_index_.
1740 DCHECK(pending_entry_ || pending_entry_index_ == -1);
1741
1742 // If there is a pending_entry_index_, then pending_entry_ must be the entry
1743 // at that index.
1744 DCHECK(pending_entry_index_ == -1 ||
1745 pending_entry_ == GetEntryAtIndex(pending_entry_index_));
1746
1729 return pending_entry_; 1747 return pending_entry_;
1730 } 1748 }
1731 1749
1732 int NavigationControllerImpl::GetPendingEntryIndex() const { 1750 int NavigationControllerImpl::GetPendingEntryIndex() const {
1751 // The pending entry index must always be less than the number of entries.
1752 // If there are no entries, it must be exactly -1.
1753 DCHECK_LT(pending_entry_index_, GetEntryCount());
1754 DCHECK(GetEntryCount() != 0 || pending_entry_index_ == -1);
1733 return pending_entry_index_; 1755 return pending_entry_index_;
1734 } 1756 }
1735 1757
1736 void NavigationControllerImpl::InsertOrReplaceEntry( 1758 void NavigationControllerImpl::InsertOrReplaceEntry(
1737 std::unique_ptr<NavigationEntryImpl> entry, 1759 std::unique_ptr<NavigationEntryImpl> entry,
1738 bool replace) { 1760 bool replace) {
1739 DCHECK(!ui::PageTransitionCoreTypeIs(entry->GetTransitionType(), 1761 DCHECK(!ui::PageTransitionCoreTypeIs(entry->GetTransitionType(),
1740 ui::PAGE_TRANSITION_AUTO_SUBFRAME)); 1762 ui::PAGE_TRANSITION_AUTO_SUBFRAME));
1741 1763
1742 // If the pending_entry_index_ is -1, the navigation was to a new page, and we 1764 // If the pending_entry_index_ is -1, the navigation was to a new page, and we
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1784 void NavigationControllerImpl::PruneOldestEntryIfFull() { 1806 void NavigationControllerImpl::PruneOldestEntryIfFull() {
1785 if (entries_.size() >= max_entry_count()) { 1807 if (entries_.size() >= max_entry_count()) {
1786 DCHECK_EQ(max_entry_count(), entries_.size()); 1808 DCHECK_EQ(max_entry_count(), entries_.size());
1787 DCHECK_GT(last_committed_entry_index_, 0); 1809 DCHECK_GT(last_committed_entry_index_, 0);
1788 RemoveEntryAtIndex(0); 1810 RemoveEntryAtIndex(0);
1789 NotifyPrunedEntries(this, true, 1); 1811 NotifyPrunedEntries(this, true, 1);
1790 } 1812 }
1791 } 1813 }
1792 1814
1793 void NavigationControllerImpl::NavigateToPendingEntry(ReloadType reload_type) { 1815 void NavigationControllerImpl::NavigateToPendingEntry(ReloadType reload_type) {
1816 DCHECK(pending_entry_);
1794 needs_reload_ = false; 1817 needs_reload_ = false;
1795 1818
1796 // If we were navigating to a slow-to-commit page, and the user performs 1819 // If we were navigating to a slow-to-commit page, and the user performs
1797 // a session history navigation to the last committed page, RenderViewHost 1820 // a session history navigation to the last committed page, RenderViewHost
1798 // will force the throbber to start, but WebKit will essentially ignore the 1821 // will force the throbber to start, but WebKit will essentially ignore the
1799 // navigation, and won't send a message to stop the throbber. To prevent this 1822 // navigation, and won't send a message to stop the throbber. To prevent this
1800 // from happening, we drop the navigation here and stop the slow-to-commit 1823 // from happening, we drop the navigation here and stop the slow-to-commit
1801 // page from loading (which would normally happen during the navigation). 1824 // page from loading (which would normally happen during the navigation).
1802 if (pending_entry_index_ != -1 && 1825 if (pending_entry_index_ != -1 &&
1803 pending_entry_index_ == last_committed_entry_index_ && 1826 pending_entry_index_ == last_committed_entry_index_ &&
1804 (entries_[pending_entry_index_]->restore_type() == RestoreType::NONE) && 1827 pending_entry_->restore_type() == RestoreType::NONE &&
1805 (entries_[pending_entry_index_]->GetTransitionType() & 1828 pending_entry_->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK) {
1806 ui::PAGE_TRANSITION_FORWARD_BACK)) {
1807 delegate_->Stop(); 1829 delegate_->Stop();
1808 1830
1809 // If an interstitial page is showing, we want to close it to get back 1831 // If an interstitial page is showing, we want to close it to get back
1810 // to what was showing before. 1832 // to what was showing before.
1811 if (delegate_->GetInterstitialPage()) 1833 if (delegate_->GetInterstitialPage())
1812 delegate_->GetInterstitialPage()->DontProceed(); 1834 delegate_->GetInterstitialPage()->DontProceed();
1813 1835
1814 DiscardNonCommittedEntries(); 1836 DiscardNonCommittedEntries();
1815 return; 1837 return;
1816 } 1838 }
1817 1839
1818 // If an interstitial page is showing, the previous renderer is blocked and 1840 // If an interstitial page is showing, the previous renderer is blocked and
1819 // cannot make new requests. Unblock (and disable) it to allow this 1841 // cannot make new requests. Unblock (and disable) it to allow this
1820 // navigation to succeed. The interstitial will stay visible until the 1842 // navigation to succeed. The interstitial will stay visible until the
1821 // resulting DidNavigate. 1843 // resulting DidNavigate.
1822 if (delegate_->GetInterstitialPage()) { 1844 if (delegate_->GetInterstitialPage()) {
1823 static_cast<InterstitialPageImpl*>(delegate_->GetInterstitialPage()) 1845 static_cast<InterstitialPageImpl*>(delegate_->GetInterstitialPage())
1824 ->CancelForNavigation(); 1846 ->CancelForNavigation();
1825 } 1847 }
1826 1848
1827 // The last navigation is the last pending navigation which hasn't been 1849 // The last navigation is the last pending navigation which hasn't been
1828 // committed yet, or the last committed navigation. 1850 // committed yet, or the last committed navigation.
1829 NavigationEntryImpl* last_navigation = 1851 NavigationEntryImpl* last_navigation =
1830 last_pending_entry_ ? last_pending_entry_ : GetLastCommittedEntry(); 1852 last_pending_entry_ ? last_pending_entry_ : GetLastCommittedEntry();
1831 1853
1832 // Convert Enter-in-omnibox to a reload. This is what Blink does in 1854 // Convert Enter-in-omnibox to a reload. This is what Blink does in
1833 // FrameLoader, but we want to handle it here so that if the navigation is 1855 // FrameLoader, but we want to handle it here so that if the navigation is
1834 // redirected or handled purely on the browser side in PlzNavigate we have the 1856 // redirected or handled purely on the browser side in PlzNavigate we have the
1835 // same behaviour as Blink would. Note that we don't want to convert to a 1857 // same behaviour as Blink would. Note that we don't want to convert to a
1836 // reload for history navigations, so this must be above the retrieval of the 1858 // reload for history navigations.
1837 // pending_entry_ below when pending_entry_index_ is used. 1859 if (reload_type == ReloadType::NONE && last_navigation &&
1838 if (reload_type == ReloadType::NONE && last_navigation && pending_entry_ && 1860 !(pending_entry_->GetTransitionType() &
1861 ui::PAGE_TRANSITION_FORWARD_BACK) &&
Charlie Reis 2017/04/24 03:58:13 Let's avoid using PageTransition for any meaningfu
arthursonzogni 2017/04/24 16:28:17 Okay, please note that pending_entry_ is already n
Charlie Reis 2017/04/24 17:34:55 Acknowledged.
1839 // Please refer to the ShouldTreatNavigationAsReload() function for info 1862 // Please refer to the ShouldTreatNavigationAsReload() function for info
1840 // on which navigations are treated as reloads. In general navigating to 1863 // on which navigations are treated as reloads. In general navigating to
1841 // the last committed or pending entry via the address bar, clicking on 1864 // the last committed or pending entry via the address bar, clicking on
1842 // a link, etc would be treated as reloads. 1865 // a link, etc would be treated as reloads.
1843 ShouldTreatNavigationAsReload(pending_entry_) && 1866 ShouldTreatNavigationAsReload(pending_entry_) &&
1844 // Skip entries with SSL errors. 1867 // Skip entries with SSL errors.
1845 !last_navigation->ssl_error() && 1868 !last_navigation->ssl_error() &&
1846 // Ignore interstitial pages 1869 // Ignore interstitial pages
1847 last_transient_entry_index_ == -1 && 1870 last_transient_entry_index_ == -1 &&
1848 pending_entry_->frame_tree_node_id() == -1 && 1871 pending_entry_->frame_tree_node_id() == -1 &&
(...skipping 14 matching lines...) Expand all
1863 reload_type = ReloadType::NORMAL; 1886 reload_type = ReloadType::NORMAL;
1864 } 1887 }
1865 1888
1866 if (last_pending_entry_index_ == -1 && last_pending_entry_) 1889 if (last_pending_entry_index_ == -1 && last_pending_entry_)
1867 delete last_pending_entry_; 1890 delete last_pending_entry_;
1868 1891
1869 last_transient_entry_index_ = -1; 1892 last_transient_entry_index_ = -1;
1870 last_pending_entry_ = nullptr; 1893 last_pending_entry_ = nullptr;
1871 last_pending_entry_index_ = -1; 1894 last_pending_entry_index_ = -1;
1872 1895
1873 // For session history navigations only the pending_entry_index_ is set.
1874 if (!pending_entry_) {
1875 CHECK_NE(pending_entry_index_, -1);
1876 pending_entry_ = entries_[pending_entry_index_].get();
1877 }
1878
1879 // Any renderer-side debug URLs or javascript: URLs should be ignored if the 1896 // Any renderer-side debug URLs or javascript: URLs should be ignored if the
1880 // renderer process is not live, unless it is the initial navigation of the 1897 // renderer process is not live, unless it is the initial navigation of the
1881 // tab. 1898 // tab.
1882 if (IsRendererDebugURL(pending_entry_->GetURL())) { 1899 if (IsRendererDebugURL(pending_entry_->GetURL())) {
1883 // TODO(creis): Find the RVH for the correct frame. 1900 // TODO(creis): Find the RVH for the correct frame.
1884 if (!delegate_->GetRenderViewHost()->IsRenderViewLive() && 1901 if (!delegate_->GetRenderViewHost()->IsRenderViewLive() &&
1885 !IsInitialNavigation()) { 1902 !IsInitialNavigation()) {
1886 DiscardNonCommittedEntries(); 1903 DiscardNonCommittedEntries();
1887 return; 1904 return;
1888 } 1905 }
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2037 void NavigationControllerImpl::LoadIfNecessary() { 2054 void NavigationControllerImpl::LoadIfNecessary() {
2038 if (!needs_reload_) 2055 if (!needs_reload_)
2039 return; 2056 return;
2040 2057
2041 // Calling Reload() results in ignoring state, and not loading. 2058 // Calling Reload() results in ignoring state, and not loading.
2042 // Explicitly use NavigateToPendingEntry so that the renderer uses the 2059 // Explicitly use NavigateToPendingEntry so that the renderer uses the
2043 // cached state. 2060 // cached state.
2044 if (pending_entry_) { 2061 if (pending_entry_) {
2045 NavigateToPendingEntry(ReloadType::NONE); 2062 NavigateToPendingEntry(ReloadType::NONE);
2046 } else if (last_committed_entry_index_ != -1) { 2063 } else if (last_committed_entry_index_ != -1) {
2064 pending_entry_ = entries_[last_committed_entry_index_].get();
2047 pending_entry_index_ = last_committed_entry_index_; 2065 pending_entry_index_ = last_committed_entry_index_;
2048 NavigateToPendingEntry(ReloadType::NONE); 2066 NavigateToPendingEntry(ReloadType::NONE);
2049 } else { 2067 } else {
2050 // If there is something to reload, the successful reload will clear the 2068 // If there is something to reload, the successful reload will clear the
2051 // |needs_reload_| flag. Otherwise, just do it here. 2069 // |needs_reload_| flag. Otherwise, just do it here.
2052 needs_reload_ = false; 2070 needs_reload_ = false;
2053 } 2071 }
2054 } 2072 }
2055 2073
2056 void NavigationControllerImpl::NotifyEntryChanged( 2074 void NavigationControllerImpl::NotifyEntryChanged(
(...skipping 27 matching lines...) Expand all
2084 // when the tab is being destroyed for shutdown, since it won't return to 2102 // when the tab is being destroyed for shutdown, since it won't return to
2085 // NavigateToEntry in that case.) http://crbug.com/347742. 2103 // NavigateToEntry in that case.) http://crbug.com/347742.
2086 CHECK(!in_navigate_to_pending_entry_ || delegate_->IsBeingDestroyed()); 2104 CHECK(!in_navigate_to_pending_entry_ || delegate_->IsBeingDestroyed());
2087 2105
2088 if (was_failure && pending_entry_) { 2106 if (was_failure && pending_entry_) {
2089 failed_pending_entry_id_ = pending_entry_->GetUniqueID(); 2107 failed_pending_entry_id_ = pending_entry_->GetUniqueID();
2090 } else { 2108 } else {
2091 failed_pending_entry_id_ = 0; 2109 failed_pending_entry_id_ = 0;
2092 } 2110 }
2093 2111
2094 if (pending_entry_index_ == -1) 2112 if (pending_entry_) {
2095 delete pending_entry_; 2113 if (pending_entry_index_ == -1)
2096 pending_entry_ = NULL; 2114 delete pending_entry_;
2097 pending_entry_index_ = -1; 2115 pending_entry_index_ = -1;
2116 pending_entry_ = nullptr;
2117 }
2098 } 2118 }
2099 2119
2100 void NavigationControllerImpl::SetPendingNavigationSSLError(bool error) { 2120 void NavigationControllerImpl::SetPendingNavigationSSLError(bool error) {
2101 if (pending_entry_) 2121 if (pending_entry_)
2102 pending_entry_->set_ssl_error(error); 2122 pending_entry_->set_ssl_error(error);
2103 } 2123 }
2104 2124
2105 void NavigationControllerImpl::DiscardTransientEntry() { 2125 void NavigationControllerImpl::DiscardTransientEntry() {
2106 if (transient_entry_index_ == -1) 2126 if (transient_entry_index_ == -1)
2107 return; 2127 return;
2108 entries_.erase(entries_.begin() + transient_entry_index_); 2128 entries_.erase(entries_.begin() + transient_entry_index_);
2109 if (last_committed_entry_index_ > transient_entry_index_) 2129 if (last_committed_entry_index_ > transient_entry_index_)
2110 last_committed_entry_index_--; 2130 last_committed_entry_index_--;
2131 if (pending_entry_index_ > transient_entry_index_)
Charlie Reis 2017/04/24 03:58:13 (Same question as below.)
2132 pending_entry_index_--;
2111 transient_entry_index_ = -1; 2133 transient_entry_index_ = -1;
2112 } 2134 }
2113 2135
2114 int NavigationControllerImpl::GetEntryIndexWithUniqueID( 2136 int NavigationControllerImpl::GetEntryIndexWithUniqueID(
2115 int nav_entry_id) const { 2137 int nav_entry_id) const {
2116 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) { 2138 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) {
2117 if (entries_[i]->GetUniqueID() == nav_entry_id) 2139 if (entries_[i]->GetUniqueID() == nav_entry_id)
2118 return i; 2140 return i;
2119 } 2141 }
2120 return -1; 2142 return -1;
2121 } 2143 }
2122 2144
2123 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const { 2145 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const {
2124 if (transient_entry_index_ == -1) 2146 if (transient_entry_index_ == -1)
2125 return NULL; 2147 return NULL;
2126 return entries_[transient_entry_index_].get(); 2148 return entries_[transient_entry_index_].get();
2127 } 2149 }
2128 2150
2129 void NavigationControllerImpl::SetTransientEntry( 2151 void NavigationControllerImpl::SetTransientEntry(
2130 std::unique_ptr<NavigationEntry> entry) { 2152 std::unique_ptr<NavigationEntry> entry) {
2131 // Discard any current transient entry, we can only have one at a time. 2153 // Discard any current transient entry, we can only have one at a time.
2132 int index = 0; 2154 int index = 0;
2133 if (last_committed_entry_index_ != -1) 2155 if (last_committed_entry_index_ != -1)
2134 index = last_committed_entry_index_ + 1; 2156 index = last_committed_entry_index_ + 1;
2135 DiscardTransientEntry(); 2157 DiscardTransientEntry();
2136 entries_.insert(entries_.begin() + index, 2158 entries_.insert(entries_.begin() + index,
2137 NavigationEntryImpl::FromNavigationEntry(std::move(entry))); 2159 NavigationEntryImpl::FromNavigationEntry(std::move(entry)));
2160 if (pending_entry_index_ >= index)
Charlie Reis 2017/04/24 03:58:13 Thanks for pointing me to the CL showing the failu
arthursonzogni 2017/04/24 16:28:17 Maybe we didn't catch it before, because pending_e
Charlie Reis 2017/04/24 17:34:55 More specifically, I think this means we might hav
2161 pending_entry_index_++;
2138 transient_entry_index_ = index; 2162 transient_entry_index_ = index;
2139 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL); 2163 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL);
2140 } 2164 }
2141 2165
2142 void NavigationControllerImpl::InsertEntriesFrom( 2166 void NavigationControllerImpl::InsertEntriesFrom(
2143 const NavigationControllerImpl& source, 2167 const NavigationControllerImpl& source,
2144 int max_index) { 2168 int max_index) {
2145 DCHECK_LE(max_index, source.GetEntryCount()); 2169 DCHECK_LE(max_index, source.GetEntryCount());
2146 size_t insert_index = 0; 2170 size_t insert_index = 0;
2147 for (int i = 0; i < max_index; i++) { 2171 for (int i = 0; i < max_index; i++) {
2148 // When cloning a tab, copy all entries except interstitial pages. 2172 // When cloning a tab, copy all entries except interstitial pages.
2149 if (source.entries_[i]->GetPageType() != PAGE_TYPE_INTERSTITIAL) { 2173 if (source.entries_[i]->GetPageType() != PAGE_TYPE_INTERSTITIAL) {
2150 // TODO(creis): Once we start sharing FrameNavigationEntries between 2174 // TODO(creis): Once we start sharing FrameNavigationEntries between
2151 // NavigationEntries, it will not be safe to share them with another tab. 2175 // NavigationEntries, it will not be safe to share them with another tab.
2152 // Must have a version of Clone that recreates them. 2176 // Must have a version of Clone that recreates them.
2153 entries_.insert(entries_.begin() + insert_index++, 2177 entries_.insert(entries_.begin() + insert_index++,
2154 source.entries_[i]->Clone()); 2178 source.entries_[i]->Clone());
2155 } 2179 }
2156 } 2180 }
2181 DCHECK(pending_entry_index_ == -1 ||
2182 pending_entry_ == GetEntryAtIndex(pending_entry_index_));
2157 } 2183 }
2158 2184
2159 void NavigationControllerImpl::SetGetTimestampCallbackForTest( 2185 void NavigationControllerImpl::SetGetTimestampCallbackForTest(
2160 const base::Callback<base::Time()>& get_timestamp_callback) { 2186 const base::Callback<base::Time()>& get_timestamp_callback) {
2161 get_timestamp_callback_ = get_timestamp_callback; 2187 get_timestamp_callback_ = get_timestamp_callback;
2162 } 2188 }
2163 2189
2164 } // namespace content 2190 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/public/browser/navigation_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698