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