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

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

Issue 2475693002: Do not reset NavigationHandle when navigating same-page (Closed)
Patch Set: Rebase + removed DCHECK Created 4 years, 1 month 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/render_frame_host_impl.h" 5 #include "content/browser/frame_host/render_frame_host_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 process->FilterURL(true, &validated_params.searchable_form_url); 1199 process->FilterURL(true, &validated_params.searchable_form_url);
1200 1200
1201 // Without this check, the renderer can trick the browser into using 1201 // Without this check, the renderer can trick the browser into using
1202 // filenames it can't access in a future session restore. 1202 // filenames it can't access in a future session restore.
1203 if (!CanAccessFilesOfPageState(validated_params.page_state)) { 1203 if (!CanAccessFilesOfPageState(validated_params.page_state)) {
1204 bad_message::ReceivedBadMessage( 1204 bad_message::ReceivedBadMessage(
1205 GetProcess(), bad_message::RFH_CAN_ACCESS_FILES_OF_PAGE_STATE); 1205 GetProcess(), bad_message::RFH_CAN_ACCESS_FILES_OF_PAGE_STATE);
1206 return; 1206 return;
1207 } 1207 }
1208 1208
1209 // If the URL or |was_within_same_page| does not match what the 1209 // PlzNavigate
1210 // NavigationHandle expects, treat the commit as a new navigation. This can 1210 if (!navigation_handle_ && IsBrowserSideNavigationEnabled()) {
1211 // happen if an ongoing slow same-process navigation is interwoven with a 1211 // PlzNavigate: the browser has not been notified about the start of the
1212 // synchronous renderer-initiated navigation. 1212 // load in this renderer yet (e.g., for same-page navigations that start in
1213 // TODO(csharrison): Data navigations loaded with LoadDataWithBaseURL get 1213 // the renderer). Do it now.
clamy 2016/11/10 14:25:16 I had to remove the DCHECK(validated_params.was_wi
1214 // reset here, because the NavigationHandle tracks the URL but the 1214 if (!is_loading()) {
1215 // validated_params.url tracks the data. The trick of saving the old entry ids 1215 bool was_loading = frame_tree_node()->frame_tree()->IsLoading();
1216 // for these navigations should go away when this is properly handled. See 1216 is_loading_ = true;
1217 // crbug.com/588317. 1217 frame_tree_node()->DidStartLoading(true, was_loading);
1218 int entry_id_for_data_nav = 0;
1219 bool is_renderer_initiated = true;
1220 if (navigation_handle_ &&
1221 ((navigation_handle_->GetURL() != validated_params.url) ||
1222 navigation_handle_->IsSamePage() !=
1223 validated_params.was_within_same_page)) {
1224 // Make sure that the pending entry was really loaded via
1225 // LoadDataWithBaseURL and that it matches this handle.
1226 NavigationEntryImpl* pending_entry =
1227 NavigationEntryImpl::FromNavigationEntry(
1228 frame_tree_node()->navigator()->GetController()->GetPendingEntry());
1229 bool pending_entry_matches_handle =
1230 pending_entry &&
1231 pending_entry->GetUniqueID() ==
1232 navigation_handle_->pending_nav_entry_id();
1233 // TODO(csharrison): The pending entry's base url should equal
1234 // |validated_params.base_url|. This is not the case for loads with invalid
1235 // base urls.
1236 if (navigation_handle_->GetURL() == validated_params.base_url &&
1237 pending_entry_matches_handle &&
1238 !pending_entry->GetBaseURLForDataURL().is_empty()) {
1239 entry_id_for_data_nav = navigation_handle_->pending_nav_entry_id();
1240 is_renderer_initiated = pending_entry->is_renderer_initiated();
1241 } 1218 }
1242 navigation_handle_.reset(); 1219 pending_commit_ = false;
1243 } 1220 }
1244 1221
1245 // Synchronous renderer-initiated navigations will send a 1222 // Find the appropriate NavigationHandle for this navigation.
1246 // DidCommitProvisionalLoad IPC without a prior DidStartProvisionalLoad 1223 std::unique_ptr<NavigationHandleImpl> navigation_handle =
1247 // message. Or in addition, the if block above can reset the NavigationHandle 1224 TakeNavigationHandleForCommit(validated_params);
1248 // in cases it doesn't match the expected commit. 1225 DCHECK(navigation_handle);
1249 if (!navigation_handle_) {
1250 // There is no pending NavigationEntry in these cases, so pass 0 as the
1251 // nav_id. If the previous handle was a prematurely aborted navigation
1252 // loaded via LoadDataWithBaseURL, propogate the entry id.
1253 navigation_handle_ = NavigationHandleImpl::Create(
1254 validated_params.url, frame_tree_node_, is_renderer_initiated,
1255 validated_params.was_within_same_page, validated_params.is_srcdoc,
1256 base::TimeTicks::Now(), entry_id_for_data_nav,
1257 false); // started_from_context_menu
1258 // PlzNavigate
1259 if (IsBrowserSideNavigationEnabled()) {
1260 // PlzNavigate: synchronous loads happen in the renderer, and the browser
1261 // has not been notified about the start of the load yet. Do it now.
1262 if (!is_loading()) {
1263 bool was_loading = frame_tree_node()->frame_tree()->IsLoading();
1264 is_loading_ = true;
1265 frame_tree_node()->DidStartLoading(true, was_loading);
1266 }
1267 pending_commit_ = false;
1268 }
1269 }
1270 1226
1271 accessibility_reset_count_ = 0; 1227 accessibility_reset_count_ = 0;
1272 frame_tree_node()->navigator()->DidNavigate(this, validated_params); 1228 frame_tree_node()->navigator()->DidNavigate(this, validated_params,
1229 std::move(navigation_handle));
1273 1230
1274 // Since we didn't early return, it's safe to keep the commit state. 1231 // Since we didn't early return, it's safe to keep the commit state.
1275 commit_state_resetter.disable(); 1232 commit_state_resetter.disable();
1276 1233
1277 // For a top-level frame, there are potential security concerns associated 1234 // For a top-level frame, there are potential security concerns associated
1278 // with displaying graphics from a previously loaded page after the URL in 1235 // with displaying graphics from a previously loaded page after the URL in
1279 // the omnibar has been changed. It is unappealing to clear the page 1236 // the omnibar has been changed. It is unappealing to clear the page
1280 // immediately, but if the renderer is taking a long time to issue any 1237 // immediately, but if the renderer is taking a long time to issue any
1281 // compositor output (possibly because of script deliberately creating this 1238 // compositor output (possibly because of script deliberately creating this
1282 // situation) then we clear it after a while anyway. 1239 // situation) then we clear it after a while anyway.
(...skipping 1920 matching lines...) Expand 10 before | Expand all | Expand 10 after
3203 // handler after it's destroyed so it can't run after the RFHI is destroyed. 3160 // handler after it's destroyed so it can't run after the RFHI is destroyed.
3204 web_bluetooth_service_->SetClientConnectionErrorHandler(base::Bind( 3161 web_bluetooth_service_->SetClientConnectionErrorHandler(base::Bind(
3205 &RenderFrameHostImpl::DeleteWebBluetoothService, base::Unretained(this))); 3162 &RenderFrameHostImpl::DeleteWebBluetoothService, base::Unretained(this)));
3206 return web_bluetooth_service_.get(); 3163 return web_bluetooth_service_.get();
3207 } 3164 }
3208 3165
3209 void RenderFrameHostImpl::DeleteWebBluetoothService() { 3166 void RenderFrameHostImpl::DeleteWebBluetoothService() {
3210 web_bluetooth_service_.reset(); 3167 web_bluetooth_service_.reset();
3211 } 3168 }
3212 3169
3170 std::unique_ptr<NavigationHandleImpl>
3171 RenderFrameHostImpl::TakeNavigationHandleForCommit(
3172 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
3173 // If this is a same-page navigation, there isn't an existing NavigationHandle
3174 // to use for the navigation. Create one, but don't reset any NavigationHandle
3175 // tracking an ongoing navigation, since this may lead to the cancellation of
3176 // the navigation.
3177 if (params.was_within_same_page) {
3178 // We don't ever expect navigation_handle_ to match, because handles are not
3179 // created for same-page navigations.
3180 DCHECK(!navigation_handle_ || !navigation_handle_->IsSamePage());
3181
3182 // First, determine if the navigation corresponds to the pending navigation
3183 // entry. This is the case for a browser-initiated same-page navigation,
3184 // which does not cause a NavigationHandle to be created because it does not
3185 // go through DidStartProvisionalLoad.
3186 bool is_renderer_initiated = true;
3187 int pending_nav_entry_id = 0;
3188 NavigationEntryImpl* pending_entry =
3189 NavigationEntryImpl::FromNavigationEntry(
3190 frame_tree_node()->navigator()->GetController()->GetPendingEntry());
3191 if (pending_entry && pending_entry->GetUniqueID() == params.nav_entry_id) {
3192 pending_nav_entry_id = params.nav_entry_id;
3193 is_renderer_initiated = pending_entry->is_renderer_initiated();
3194 }
3195
3196 return NavigationHandleImpl::Create(
3197 params.url, frame_tree_node_, is_renderer_initiated,
3198 params.was_within_same_page, params.is_srcdoc, base::TimeTicks::Now(),
3199 pending_nav_entry_id, false); // started_from_context_menu
3200 }
3201
3202 // Determine if the current NavigationHandle can be used.
3203 if (navigation_handle_ && navigation_handle_->GetURL() == params.url) {
3204 return std::move(navigation_handle_);
3205 }
3206
3207 // If the URL does not match what the NavigationHandle expects, treat the
3208 // commit as a new navigation. This can happen when loading a Data
3209 // navigation with LoadDataWithBaseURL.
3210 //
3211 // TODO(csharrison): Data navigations loaded with LoadDataWithBaseURL get
3212 // reset here, because the NavigationHandle tracks the URL but the params.url
3213 // tracks the data. The trick of saving the old entry ids for these
3214 // navigations should go away when this is properly handled.
3215 // See crbug.com/588317.
3216 int entry_id_for_data_nav = 0;
3217 bool is_renderer_initiated = true;
3218
3219 // Make sure that the pending entry was really loaded via LoadDataWithBaseURL
3220 // and that it matches this handle. TODO(csharrison): The pending entry's
3221 // base url should equal |params.base_url|. This is not the case for loads
3222 // with invalid base urls.
3223 if (navigation_handle_) {
3224 NavigationEntryImpl* pending_entry =
3225 NavigationEntryImpl::FromNavigationEntry(
3226 frame_tree_node()->navigator()->GetController()->GetPendingEntry());
3227 bool pending_entry_matches_handle =
3228 pending_entry &&
3229 pending_entry->GetUniqueID() ==
3230 navigation_handle_->pending_nav_entry_id();
3231 // TODO(csharrison): The pending entry's base url should equal
3232 // |validated_params.base_url|. This is not the case for loads with invalid
3233 // base urls.
3234 if (navigation_handle_->GetURL() == params.base_url &&
3235 pending_entry_matches_handle &&
3236 !pending_entry->GetBaseURLForDataURL().is_empty()) {
3237 entry_id_for_data_nav = navigation_handle_->pending_nav_entry_id();
3238 is_renderer_initiated = pending_entry->is_renderer_initiated();
3239 }
3240
3241 // Reset any existing NavigationHandle.
3242 navigation_handle_.reset();
3243 }
3244
3245 // There is no pending NavigationEntry in these cases, so pass 0 as the
3246 // pending_nav_entry_id. If the previous handle was a prematurely aborted
3247 // navigation loaded via LoadDataWithBaseURL, propagate the entry id.
3248 return NavigationHandleImpl::Create(
3249 params.url, frame_tree_node_, is_renderer_initiated,
3250 params.was_within_same_page, params.is_srcdoc, base::TimeTicks::Now(),
3251 entry_id_for_data_nav, false); // started_from_context_menu
3252 }
3253
3213 } // namespace content 3254 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_frame_host_impl.h ('k') | content/browser/loader/navigation_resource_throttle.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698