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

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

Issue 1002803002: Classify navigations without page id in parallel to the existing classifier. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: better crash url Created 5 years, 9 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
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_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 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 // If we are doing a cross-site reload, we need to replace the existing 794 // If we are doing a cross-site reload, we need to replace the existing
795 // navigation entry, not add another entry to the history. This has the side 795 // navigation entry, not add another entry to the history. This has the side
796 // effect of removing forward browsing history, if such existed. 796 // effect of removing forward browsing history, if such existed.
797 // Or if we are doing a cross-site redirect navigation, 797 // Or if we are doing a cross-site redirect navigation,
798 // we will do a similar thing. 798 // we will do a similar thing.
799 details->did_replace_entry = 799 details->did_replace_entry =
800 pending_entry_ && pending_entry_->should_replace_entry(); 800 pending_entry_ && pending_entry_->should_replace_entry();
801 801
802 // Do navigation-type specific actions. These will make and commit an entry. 802 // Do navigation-type specific actions. These will make and commit an entry.
803 details->type = ClassifyNavigation(rfh, params); 803 details->type = ClassifyNavigation(rfh, params);
804 DCHECK_EQ(details->type, ClassifyNavigationWithoutPageID(rfh, params));
804 805
805 // is_in_page must be computed before the entry gets committed. 806 // is_in_page must be computed before the entry gets committed.
806 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(), 807 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(),
807 params.url, params.was_within_same_page, rfh); 808 params.url, params.was_within_same_page, rfh);
808 809
809 switch (details->type) { 810 switch (details->type) {
810 case NAVIGATION_TYPE_NEW_PAGE: 811 case NAVIGATION_TYPE_NEW_PAGE:
811 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry); 812 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry);
812 break; 813 break;
813 case NAVIGATION_TYPE_EXISTING_PAGE: 814 case NAVIGATION_TYPE_EXISTING_PAGE:
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url, 1032 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url,
1032 params.was_within_same_page, rfh)) { 1033 params.was_within_same_page, rfh)) {
1033 return NAVIGATION_TYPE_IN_PAGE; 1034 return NAVIGATION_TYPE_IN_PAGE;
1034 } 1035 }
1035 1036
1036 // Since we weeded out "new" navigations above, we know this is an existing 1037 // Since we weeded out "new" navigations above, we know this is an existing
1037 // (back/forward) navigation. 1038 // (back/forward) navigation.
1038 return NAVIGATION_TYPE_EXISTING_PAGE; 1039 return NAVIGATION_TYPE_EXISTING_PAGE;
1039 } 1040 }
1040 1041
1042 NavigationType NavigationControllerImpl::ClassifyNavigationWithoutPageID(
1043 RenderFrameHostImpl* rfh,
1044 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const {
1045 if (params.commit_type == blink::WebStandardCommit) {
1046 // Standard commits are new pages. We may or may not have a pending entry
1047 // for the page, and this may or may not be the main frame.
1048 if (!rfh->GetParent()) {
1049 // TODO(avi): Everyone does ui::PageTransitionIsMainFrame to determine
1050 // main-frame-ness. I can get that consumers of page transitions would
1051 // want to do that, but for code inside RenderFrameHost and NavController?
1052 // Please.
1053 return NAVIGATION_TYPE_NEW_PAGE;
1054 }
1055
1056 // When this is a new subframe navigation, we should have a committed page
1057 // in which it's a subframe. This may not be the case when an iframe is
1058 // navigated on a popup navigated to about:blank (the iframe would be
1059 // written into the popup by script on the main page). For these cases,
1060 // there isn't any navigation stuff we can do, so just ignore it.
1061 if (!GetLastCommittedEntry())
1062 return NAVIGATION_TYPE_NAV_IGNORE;
1063
1064 // Valid subframe navigation.
1065 return NAVIGATION_TYPE_NEW_SUBFRAME;
1066 }
1067
1068 // We only clear the session history when navigating to a new page.
1069 DCHECK(!params.history_list_was_cleared);
1070
1071 if (rfh->GetParent()) {
1072 // All manual subframes would be WebStandardCommit and handled above, so we
1073 // know this is auto.
1074 DCHECK(GetLastCommittedEntry());
1075 return NAVIGATION_TYPE_AUTO_SUBFRAME;
1076 }
1077
1078 if (params.nav_entry_id == 0) {
1079 // This is a renderer-initiated navigation, but didn't create a new page.
1080 // This must be an inert commit (standard commits are handled above,
Charlie Reis 2015/03/12 18:28:17 Can you explain what inert commit means? That's a
Avi (use Gerrit) 2015/03/12 19:21:17 https://code.google.com/p/chromium/codesearch#chro
1081 // back/forward commits are always browser-initiated, and initial child
Charlie Reis 2015/03/12 18:28:17 Minor wording issue, though I'm not sure if it cha
Avi (use Gerrit) 2015/03/12 19:21:17 That doesn't change the code. Because the request
1082 // frame commits are only seen with subframes, also handled above).
1083 DCHECK_EQ(blink::WebHistoryInertCommit, params.commit_type);
1084 if (params.was_within_same_page) {
1085 // This is history.replaceState(), which is renderer-initiated yet within
1086 // the same page.
1087 return NAVIGATION_TYPE_IN_PAGE;
1088 } else {
1089 // This is history.reload() and client-side redirection.
1090 return NAVIGATION_TYPE_EXISTING_PAGE;
1091 }
1092 }
1093
1094 if (pending_entry_ && pending_entry_index_ == -1 &&
1095 pending_entry_->GetUniqueID() == params.nav_entry_id) {
1096 DCHECK_EQ(blink::WebHistoryInertCommit, params.commit_type);
1097 // In this case, we have a pending entry for a load of a new URL but Blink
1098 // didn't do a new navigation (aka WebStandardCommit). This happens when you
1099 // press enter in the URL bar to reload. We will create a pending entry, but
1100 // Blink will convert it to a reload since it's the same page and not create
1101 // a new entry for it (the user doesn't want to have a new back/forward
1102 // entry when they do this). Therefore we want to just ignore the pending
1103 // entry and go back to where we were (the "existing entry").
1104 return NAVIGATION_TYPE_SAME_PAGE;
1105 }
1106
1107 // Now we know that the notification is for an existing page. Find that entry.
1108 int existing_entry_index = GetEntryIndexWithUniqueID(params.nav_entry_id);
1109 if (existing_entry_index == -1) {
1110 // The page was not found. It could have been pruned because of the limit on
1111 // back/forward entries (not likely since we'll usually tell it to navigate
1112 // to such entries). It could also mean that the renderer is smoking crack.
1113 NOTREACHED() << "Could not find nav entry with id " << params.nav_entry_id;
1114
1115 // Because the unknown entry has committed, we risk showing the wrong URL in
1116 // release builds. Instead, we'll kill the renderer process to be safe.
1117 LOG(ERROR) << "terminating renderer for bad navigation: " << params.url;
1118 RecordAction(base::UserMetricsAction("BadMessageTerminate_NC"));
Charlie Reis 2015/03/12 18:28:17 We probably don't want to kill the renderer in bot
Avi (use Gerrit) 2015/03/12 19:21:17 Done.
1119
1120 // Temporary code so we can get more information. Format:
1121 // http://url/foo.html#uniqueid5#frame1#ids2,3,4,
1122 std::string temp = params.url.spec();
1123 temp.append("#uniqueid");
1124 temp.append(base::IntToString(params.nav_entry_id));
1125 temp.append("#frame");
1126 temp.append(base::IntToString(rfh->GetRoutingID()));
1127 temp.append("#ids");
1128 for (int i = 0; i < static_cast<int>(entries_.size()); ++i) {
1129 // Append entry metadata (e.g., 3):
1130 // 3: nav_entry_id
1131 temp.append(base::IntToString(entries_[i]->GetUniqueID()));
1132 temp.append(",");
1133 }
1134 GURL url(temp);
1135 rfh->render_view_host()->Send(new ViewMsg_TempCrashWithData(url));
1136 return NAVIGATION_TYPE_NAV_IGNORE;
1137 }
1138
1139 // Any top-level navigations with the same base (minus the reference fragment)
1140 // are in-page navigations. (We weeded out subframe navigations above.) Most
1141 // of the time this doesn't matter since Blink doesn't tell us about subframe
1142 // navigations that don't actually navigate, but it can happen when there is
1143 // an encoding override (it always sends a navigation request).
1144 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get();
1145 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url,
1146 params.was_within_same_page, rfh)) {
1147 return NAVIGATION_TYPE_IN_PAGE;
1148 }
1149
1150 // Since we weeded out "new" navigations above, we know this is an existing
1151 // (back/forward) navigation.
1152 return NAVIGATION_TYPE_EXISTING_PAGE;
1153 }
1154
1041 void NavigationControllerImpl::RendererDidNavigateToNewPage( 1155 void NavigationControllerImpl::RendererDidNavigateToNewPage(
1042 RenderFrameHostImpl* rfh, 1156 RenderFrameHostImpl* rfh,
1043 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, 1157 const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
1044 bool replace_entry) { 1158 bool replace_entry) {
1045 NavigationEntryImpl* new_entry; 1159 NavigationEntryImpl* new_entry;
1046 bool update_virtual_url; 1160 bool update_virtual_url;
1047 // Only make a copy of the pending entry if it is appropriate for the new page 1161 // Only make a copy of the pending entry if it is appropriate for the new page
1048 // that was just loaded. We verify this at a coarse grain by checking that 1162 // that was just loaded. We verify this at a coarse grain by checking that
1049 // the SiteInstance hasn't been assigned to something else. 1163 // the SiteInstance hasn't been assigned to something else.
1050 if (pending_entry_ && 1164 if (pending_entry_ &&
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after
1773 int NavigationControllerImpl::GetEntryIndexWithPageID( 1887 int NavigationControllerImpl::GetEntryIndexWithPageID(
1774 SiteInstance* instance, int32 page_id) const { 1888 SiteInstance* instance, int32 page_id) const {
1775 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) { 1889 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) {
1776 if ((entries_[i]->site_instance() == instance) && 1890 if ((entries_[i]->site_instance() == instance) &&
1777 (entries_[i]->GetPageID() == page_id)) 1891 (entries_[i]->GetPageID() == page_id))
1778 return i; 1892 return i;
1779 } 1893 }
1780 return -1; 1894 return -1;
1781 } 1895 }
1782 1896
1897 int NavigationControllerImpl::GetEntryIndexWithUniqueID(
1898 int nav_entry_id) const {
1899 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) {
1900 if (entries_[i]->GetUniqueID() == nav_entry_id)
1901 return i;
1902 }
1903 return -1;
1904 }
1905
1783 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const { 1906 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const {
1784 if (transient_entry_index_ == -1) 1907 if (transient_entry_index_ == -1)
1785 return NULL; 1908 return NULL;
1786 return entries_[transient_entry_index_].get(); 1909 return entries_[transient_entry_index_].get();
1787 } 1910 }
1788 1911
1789 void NavigationControllerImpl::SetTransientEntry(NavigationEntry* entry) { 1912 void NavigationControllerImpl::SetTransientEntry(NavigationEntry* entry) {
1790 // Discard any current transient entry, we can only have one at a time. 1913 // Discard any current transient entry, we can only have one at a time.
1791 int index = 0; 1914 int index = 0;
1792 if (last_committed_entry_index_ != -1) 1915 if (last_committed_entry_index_ != -1)
(...skipping 21 matching lines...) Expand all
1814 } 1937 }
1815 } 1938 }
1816 } 1939 }
1817 1940
1818 void NavigationControllerImpl::SetGetTimestampCallbackForTest( 1941 void NavigationControllerImpl::SetGetTimestampCallbackForTest(
1819 const base::Callback<base::Time()>& get_timestamp_callback) { 1942 const base::Callback<base::Time()>& get_timestamp_callback) {
1820 get_timestamp_callback_ = get_timestamp_callback; 1943 get_timestamp_callback_ = get_timestamp_callback;
1821 } 1944 }
1822 1945
1823 } // namespace content 1946 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698