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