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