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_controller_impl.h" | 5 #include "content/browser/frame_host/navigation_controller_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
789 details->previous_entry_index = -1; | 789 details->previous_entry_index = -1; |
790 } | 790 } |
791 | 791 |
792 // If we have a pending entry at this point, it should have a SiteInstance. | 792 // If we have a pending entry at this point, it should have a SiteInstance. |
793 // Restored entries start out with a null SiteInstance, but we should have | 793 // Restored entries start out with a null SiteInstance, but we should have |
794 // assigned one in NavigateToPendingEntry. | 794 // assigned one in NavigateToPendingEntry. |
795 DCHECK(pending_entry_index_ == -1 || pending_entry_->site_instance()); | 795 DCHECK(pending_entry_index_ == -1 || pending_entry_->site_instance()); |
796 | 796 |
797 // If we are doing a cross-site reload, we need to replace the existing | 797 // If we are doing a cross-site reload, we need to replace the existing |
798 // navigation entry, not add another entry to the history. This has the side | 798 // navigation entry, not add another entry to the history. This has the side |
799 // effect of removing forward browsing history, if such existed. | 799 // effect of removing forward browsing history, if such existed. Or if we are |
800 // Or if we are doing a cross-site redirect navigation, | 800 // doing a cross-site redirect navigation, we will do a similar thing. |
801 // we will do a similar thing. | 801 if (params.url_is_unreachable) { |
Charlie Reis
2015/04/03 20:59:46
Should this be params.url_is_unreachable && failed
Avi (use Gerrit)
2015/04/06 19:38:16
I'm trying to come up with a scenario in which the
Charlie Reis
2015/04/06 20:48:10
The multiple frames thing is a different issue, an
Avi (use Gerrit)
2015/04/06 21:30:14
Yeah, I got it. The pending entry isn't guaranteed
| |
802 details->did_replace_entry = | 802 details->did_replace_entry = failed_pending_entry_.get() && |
803 pending_entry_ && pending_entry_->should_replace_entry(); | 803 failed_pending_entry_->should_replace_entry(); |
804 } else { | |
805 details->did_replace_entry = pending_entry_ && | |
806 pending_entry_->should_replace_entry(); | |
807 } | |
804 | 808 |
805 // Do navigation-type specific actions. These will make and commit an entry. | 809 // Do navigation-type specific actions. These will make and commit an entry. |
806 details->type = ClassifyNavigation(rfh, params); | 810 details->type = ClassifyNavigation(rfh, params); |
807 | 811 |
808 // is_in_page must be computed before the entry gets committed. | 812 // is_in_page must be computed before the entry gets committed. |
809 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(), | 813 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(), |
810 params.url, params.was_within_same_page, rfh); | 814 params.url, params.was_within_same_page, rfh); |
811 | 815 |
812 switch (details->type) { | 816 switch (details->type) { |
813 case NAVIGATION_TYPE_NEW_PAGE: | 817 case NAVIGATION_TYPE_NEW_PAGE: |
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1751 RestoreType type) { | 1755 RestoreType type) { |
1752 DCHECK(selected_index >= 0 && selected_index < GetEntryCount()); | 1756 DCHECK(selected_index >= 0 && selected_index < GetEntryCount()); |
1753 ConfigureEntriesForRestore(&entries_, type); | 1757 ConfigureEntriesForRestore(&entries_, type); |
1754 | 1758 |
1755 SetMaxRestoredPageID(static_cast<int32>(GetEntryCount())); | 1759 SetMaxRestoredPageID(static_cast<int32>(GetEntryCount())); |
1756 | 1760 |
1757 last_committed_entry_index_ = selected_index; | 1761 last_committed_entry_index_ = selected_index; |
1758 } | 1762 } |
1759 | 1763 |
1760 void NavigationControllerImpl::DiscardNonCommittedEntriesInternal() { | 1764 void NavigationControllerImpl::DiscardNonCommittedEntriesInternal() { |
1761 DiscardPendingEntry(); | 1765 DiscardPendingEntry(false); |
1762 DiscardTransientEntry(); | 1766 DiscardTransientEntry(); |
1763 } | 1767 } |
1764 | 1768 |
1765 void NavigationControllerImpl::DiscardPendingEntry() { | 1769 void NavigationControllerImpl::DiscardPendingEntry(bool was_failure) { |
1766 // It is not safe to call DiscardPendingEntry while NavigateToEntry is in | 1770 // It is not safe to call DiscardPendingEntry while NavigateToEntry is in |
1767 // progress, since this will cause a use-after-free. (We only allow this | 1771 // progress, since this will cause a use-after-free. (We only allow this |
1768 // when the tab is being destroyed for shutdown, since it won't return to | 1772 // when the tab is being destroyed for shutdown, since it won't return to |
1769 // NavigateToEntry in that case.) http://crbug.com/347742. | 1773 // NavigateToEntry in that case.) http://crbug.com/347742. |
1770 CHECK(!in_navigate_to_pending_entry_ || delegate_->IsBeingDestroyed()); | 1774 CHECK(!in_navigate_to_pending_entry_ || delegate_->IsBeingDestroyed()); |
1771 | 1775 |
1772 if (pending_entry_index_ == -1) | 1776 if (pending_entry_index_ == -1) { |
1773 delete pending_entry_; | 1777 if (was_failure) |
1778 failed_pending_entry_.reset(pending_entry_); | |
1779 else | |
1780 delete pending_entry_; | |
1781 } | |
1782 | |
1774 pending_entry_ = NULL; | 1783 pending_entry_ = NULL; |
1775 pending_entry_index_ = -1; | 1784 pending_entry_index_ = -1; |
1785 if (!was_failure) | |
1786 failed_pending_entry_.reset(); | |
Charlie Reis
2015/04/03 20:59:46
You've confirmed this gets cleared after the error
Avi (use Gerrit)
2015/04/06 19:38:16
Yes, this gets cleared by the DiscardNonCommittedE
| |
1776 } | 1787 } |
1777 | 1788 |
1778 void NavigationControllerImpl::DiscardTransientEntry() { | 1789 void NavigationControllerImpl::DiscardTransientEntry() { |
1779 if (transient_entry_index_ == -1) | 1790 if (transient_entry_index_ == -1) |
1780 return; | 1791 return; |
1781 entries_.erase(entries_.begin() + transient_entry_index_); | 1792 entries_.erase(entries_.begin() + transient_entry_index_); |
1782 if (last_committed_entry_index_ > transient_entry_index_) | 1793 if (last_committed_entry_index_ > transient_entry_index_) |
1783 last_committed_entry_index_--; | 1794 last_committed_entry_index_--; |
1784 transient_entry_index_ = -1; | 1795 transient_entry_index_ = -1; |
1785 } | 1796 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1830 } | 1841 } |
1831 } | 1842 } |
1832 } | 1843 } |
1833 | 1844 |
1834 void NavigationControllerImpl::SetGetTimestampCallbackForTest( | 1845 void NavigationControllerImpl::SetGetTimestampCallbackForTest( |
1835 const base::Callback<base::Time()>& get_timestamp_callback) { | 1846 const base::Callback<base::Time()>& get_timestamp_callback) { |
1836 get_timestamp_callback_ = get_timestamp_callback; | 1847 get_timestamp_callback_ = get_timestamp_callback; |
1837 } | 1848 } |
1838 | 1849 |
1839 } // namespace content | 1850 } // namespace content |
OLD | NEW |