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/navigator_impl.h" | 5 #include "content/browser/frame_host/navigator_impl.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "content/browser/frame_host/frame_tree.h" | 10 #include "content/browser/frame_host/frame_tree.h" |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 const base::string16& error_description) { | 244 const base::string16& error_description) { |
245 if (delegate_) { | 245 if (delegate_) { |
246 delegate_->DidFailLoadWithError( | 246 delegate_->DidFailLoadWithError( |
247 render_frame_host, url, error_code, | 247 render_frame_host, url, error_code, |
248 error_description); | 248 error_description); |
249 } | 249 } |
250 } | 250 } |
251 | 251 |
252 bool NavigatorImpl::NavigateToEntry( | 252 bool NavigatorImpl::NavigateToEntry( |
253 FrameTreeNode* frame_tree_node, | 253 FrameTreeNode* frame_tree_node, |
| 254 const FrameNavigationEntry& frame_nav_entry, |
254 const NavigationEntryImpl& entry, | 255 const NavigationEntryImpl& entry, |
255 NavigationController::ReloadType reload_type) { | 256 NavigationController::ReloadType reload_type) { |
256 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); | 257 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); |
257 | 258 |
258 // The renderer will reject IPC messages with URLs longer than | 259 // The renderer will reject IPC messages with URLs longer than |
259 // this limit, so don't attempt to navigate with a longer URL. | 260 // this limit, so don't attempt to navigate with a longer URL. |
260 if (entry.GetURL().spec().size() > GetMaxURLChars()) { | 261 if (frame_nav_entry.url().spec().size() > GetMaxURLChars()) { |
261 LOG(WARNING) << "Refusing to load URL as it exceeds " << GetMaxURLChars() | 262 LOG(WARNING) << "Refusing to load URL as it exceeds " << GetMaxURLChars() |
262 << " characters."; | 263 << " characters."; |
263 return false; | 264 return false; |
264 } | 265 } |
265 | 266 |
266 // This will be used to set the Navigation Timing API navigationStart | 267 // This will be used to set the Navigation Timing API navigationStart |
267 // parameter for browser navigations in new tabs (intents, tabs opened through | 268 // parameter for browser navigations in new tabs (intents, tabs opened through |
268 // "Open link in new tab"). We need to keep it above RFHM::Navigate() call to | 269 // "Open link in new tab"). We need to keep it above RFHM::Navigate() call to |
269 // capture the time needed for the RenderFrameHost initialization. | 270 // capture the time needed for the RenderFrameHost initialization. |
270 base::TimeTicks navigation_start = base::TimeTicks::Now(); | 271 base::TimeTicks navigation_start = base::TimeTicks::Now(); |
271 | 272 |
272 RenderFrameHostManager* manager = frame_tree_node->render_manager(); | 273 RenderFrameHostManager* manager = frame_tree_node->render_manager(); |
273 | 274 |
274 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. | 275 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. |
275 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 276 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
276 switches::kEnableBrowserSideNavigation)) { | 277 switches::kEnableBrowserSideNavigation)) { |
277 navigation_data_.reset(new NavigationMetricsData( | 278 navigation_data_.reset(new NavigationMetricsData( |
278 navigation_start, entry.GetURL(), entry.restore_type())); | 279 navigation_start, frame_nav_entry.url(), entry.restore_type())); |
279 RequestNavigation(frame_tree_node, entry, reload_type, navigation_start); | 280 RequestNavigation(frame_tree_node, frame_nav_entry, entry, reload_type, |
| 281 navigation_start); |
280 return true; | 282 return true; |
281 } | 283 } |
282 | 284 |
283 RenderFrameHostImpl* dest_render_frame_host = manager->Navigate(entry); | 285 RenderFrameHostImpl* dest_render_frame_host = |
| 286 manager->Navigate(frame_nav_entry, entry); |
284 if (!dest_render_frame_host) | 287 if (!dest_render_frame_host) |
285 return false; // Unable to create the desired RenderFrameHost. | 288 return false; // Unable to create the desired RenderFrameHost. |
286 | 289 |
287 // Make sure no code called via RFHM::Navigate clears the pending entry. | 290 // Make sure no code called via RFHM::Navigate clears the pending entry. |
288 CHECK_EQ(controller_->GetPendingEntry(), &entry); | 291 CHECK_EQ(controller_->GetPendingEntry(), &entry); |
289 | 292 |
290 // For security, we should never send non-Web-UI URLs to a Web UI renderer. | 293 // For security, we should never send non-Web-UI URLs to a Web UI renderer. |
291 // Double check that here. | 294 // Double check that here. |
292 CheckWebUIRendererDoesNotDisplayNormalURL( | 295 CheckWebUIRendererDoesNotDisplayNormalURL( |
293 dest_render_frame_host, entry.GetURL()); | 296 dest_render_frame_host, frame_nav_entry.url()); |
294 | 297 |
295 // Notify observers that we will navigate in this RenderFrame. | 298 // Notify observers that we will navigate in this RenderFrame. |
296 if (delegate_) { | 299 if (delegate_) { |
| 300 // TODO(creis): Deprecate this API. We should not be accessing the current |
| 301 // RFH here. |
297 delegate_->AboutToNavigateRenderFrame(frame_tree_node->current_frame_host(), | 302 delegate_->AboutToNavigateRenderFrame(frame_tree_node->current_frame_host(), |
298 dest_render_frame_host); | 303 dest_render_frame_host); |
299 } | 304 } |
300 | 305 |
301 // Navigate in the desired RenderFrameHost. | 306 // Navigate in the desired RenderFrameHost. |
302 // We can skip this step in the rare case that this is a transfer navigation | 307 // We can skip this step in the rare case that this is a transfer navigation |
303 // which began in the chosen RenderFrameHost, since the request has already | 308 // which began in the chosen RenderFrameHost, since the request has already |
304 // been issued. In that case, simply resume the response. | 309 // been issued. In that case, simply resume the response. |
305 bool is_transfer_to_same = | 310 bool is_transfer_to_same = |
306 entry.transferred_global_request_id().child_id != -1 && | 311 entry.transferred_global_request_id().child_id != -1 && |
307 entry.transferred_global_request_id().child_id == | 312 entry.transferred_global_request_id().child_id == |
308 dest_render_frame_host->GetProcess()->GetID(); | 313 dest_render_frame_host->GetProcess()->GetID(); |
309 if (!is_transfer_to_same) { | 314 if (!is_transfer_to_same) { |
310 navigation_data_.reset(new NavigationMetricsData( | 315 navigation_data_.reset(new NavigationMetricsData( |
311 navigation_start, entry.GetURL(), entry.restore_type())); | 316 navigation_start, frame_nav_entry.url(), entry.restore_type())); |
312 // Create the navigation parameters. | 317 // Create the navigation parameters. |
313 // TODO(vitalybuka): Move this before AboutToNavigateRenderFrame once | 318 // TODO(vitalybuka): Move this before AboutToNavigateRenderFrame once |
314 // http://crbug.com/408684 is fixed. | 319 // http://crbug.com/408684 is fixed. |
315 FrameMsg_Navigate_Type::Value navigation_type = | 320 FrameMsg_Navigate_Type::Value navigation_type = |
316 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); | 321 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); |
317 dest_render_frame_host->Navigate( | 322 dest_render_frame_host->Navigate( |
318 entry.ConstructCommonNavigationParams(navigation_type), | 323 entry.ConstructCommonNavigationParams(frame_nav_entry, navigation_type), |
319 entry.ConstructStartNavigationParams(), | 324 entry.ConstructStartNavigationParams(), |
320 entry.ConstructCommitNavigationParams(navigation_start), | 325 entry.ConstructCommitNavigationParams(navigation_start), |
321 entry.ConstructHistoryNavigationParams(controller_)); | 326 entry.ConstructHistoryNavigationParams(frame_nav_entry, controller_)); |
322 } else { | 327 } else { |
323 // No need to navigate again. Just resume the deferred request. | 328 // No need to navigate again. Just resume the deferred request. |
324 dest_render_frame_host->GetProcess()->ResumeDeferredNavigation( | 329 dest_render_frame_host->GetProcess()->ResumeDeferredNavigation( |
325 entry.transferred_global_request_id()); | 330 entry.transferred_global_request_id()); |
326 } | 331 } |
327 | 332 |
328 // Make sure no code called via RFH::Navigate clears the pending entry. | 333 // Make sure no code called via RFH::Navigate clears the pending entry. |
329 CHECK_EQ(controller_->GetPendingEntry(), &entry); | 334 CHECK_EQ(controller_->GetPendingEntry(), &entry); |
330 | 335 |
331 if (entry.GetPageID() == -1) { | 336 if (entry.GetPageID() == -1) { |
332 // HACK!! This code suppresses javascript: URLs from being added to | 337 // HACK!! This code suppresses javascript: URLs from being added to |
333 // session history, which is what we want to do for javascript: URLs that | 338 // session history, which is what we want to do for javascript: URLs that |
334 // do not generate content. What we really need is a message from the | 339 // do not generate content. What we really need is a message from the |
335 // renderer telling us that a new page was not created. The same message | 340 // renderer telling us that a new page was not created. The same message |
336 // could be used for mailto: URLs and the like. | 341 // could be used for mailto: URLs and the like. |
337 if (entry.GetURL().SchemeIs(url::kJavaScriptScheme)) | 342 if (frame_nav_entry.url().SchemeIs(url::kJavaScriptScheme)) |
338 return false; | 343 return false; |
339 } | 344 } |
340 | 345 |
341 // Notify observers about navigation. | 346 // Notify observers about navigation. |
342 if (delegate_) | 347 if (delegate_) { |
343 delegate_->DidStartNavigationToPendingEntry(entry.GetURL(), reload_type); | 348 delegate_->DidStartNavigationToPendingEntry(frame_nav_entry.url(), |
| 349 reload_type); |
| 350 } |
344 | 351 |
345 return true; | 352 return true; |
346 } | 353 } |
347 | 354 |
348 bool NavigatorImpl::NavigateToPendingEntry( | 355 bool NavigatorImpl::NavigateToPendingEntry( |
349 FrameTreeNode* frame_tree_node, | 356 FrameTreeNode* frame_tree_node, |
| 357 const FrameNavigationEntry& frame_nav_entry, |
350 NavigationController::ReloadType reload_type) { | 358 NavigationController::ReloadType reload_type) { |
351 return NavigateToEntry(frame_tree_node, *controller_->GetPendingEntry(), | 359 return NavigateToEntry(frame_tree_node, frame_nav_entry, |
352 reload_type); | 360 *controller_->GetPendingEntry(), reload_type); |
353 } | 361 } |
354 | 362 |
355 void NavigatorImpl::DidNavigate( | 363 void NavigatorImpl::DidNavigate( |
356 RenderFrameHostImpl* render_frame_host, | 364 RenderFrameHostImpl* render_frame_host, |
357 const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params) { | 365 const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params) { |
358 // PlzNavigate | 366 // PlzNavigate |
359 // The navigation request has been committed so the browser process doesn't | 367 // The navigation request has been committed so the browser process doesn't |
360 // need to care about it anymore. | 368 // need to care about it anymore. |
361 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 369 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
362 switches::kEnableBrowserSideNavigation)) { | 370 switches::kEnableBrowserSideNavigation)) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 // TODO(nasko): Verify the correctness of the above comment, since some of the | 442 // TODO(nasko): Verify the correctness of the above comment, since some of the |
435 // code doesn't exist anymore. Also, move this code in the | 443 // code doesn't exist anymore. Also, move this code in the |
436 // PageTransitionIsMainFrame code block above. | 444 // PageTransitionIsMainFrame code block above. |
437 if (ui::PageTransitionIsMainFrame(params.transition) && delegate_) | 445 if (ui::PageTransitionIsMainFrame(params.transition) && delegate_) |
438 delegate_->SetMainFrameMimeType(params.contents_mime_type); | 446 delegate_->SetMainFrameMimeType(params.contents_mime_type); |
439 | 447 |
440 LoadCommittedDetails details; | 448 LoadCommittedDetails details; |
441 bool did_navigate = controller_->RendererDidNavigate(render_frame_host, | 449 bool did_navigate = controller_->RendererDidNavigate(render_frame_host, |
442 params, &details); | 450 params, &details); |
443 | 451 |
444 // For now, keep track of each frame's URL in its FrameTreeNode. This lets | |
445 // us estimate our process count for implementing OOP iframes. | |
446 // TODO(creis): Remove this when we track which pages commit in each frame. | |
447 render_frame_host->frame_tree_node()->set_current_url(params.url); | |
448 | |
449 // Send notification about committed provisional loads. This notification is | 452 // Send notification about committed provisional loads. This notification is |
450 // different from the NAV_ENTRY_COMMITTED notification which doesn't include | 453 // different from the NAV_ENTRY_COMMITTED notification which doesn't include |
451 // the actual URL navigated to and isn't sent for AUTO_SUBFRAME navigations. | 454 // the actual URL navigated to and isn't sent for AUTO_SUBFRAME navigations. |
452 if (details.type != NAVIGATION_TYPE_NAV_IGNORE && delegate_) { | 455 if (details.type != NAVIGATION_TYPE_NAV_IGNORE && delegate_) { |
453 DCHECK_EQ(!render_frame_host->GetParent(), | 456 DCHECK_EQ(!render_frame_host->GetParent(), |
454 did_navigate ? details.is_main_frame : false); | 457 did_navigate ? details.is_main_frame : false); |
455 ui::PageTransition transition_type = params.transition; | 458 ui::PageTransition transition_type = params.transition; |
456 // Whether or not a page transition was triggered by going backward or | 459 // Whether or not a page transition was triggered by going backward or |
457 // forward in the history is only stored in the navigation controller's | 460 // forward in the history is only stored in the navigation controller's |
458 // entry list. | 461 // entry list. |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 !is_allowed_in_web_ui_renderer) { | 770 !is_allowed_in_web_ui_renderer) { |
768 // Log the URL to help us diagnose any future failures of this CHECK. | 771 // Log the URL to help us diagnose any future failures of this CHECK. |
769 GetContentClient()->SetActiveURL(url); | 772 GetContentClient()->SetActiveURL(url); |
770 CHECK(0); | 773 CHECK(0); |
771 } | 774 } |
772 } | 775 } |
773 | 776 |
774 // PlzNavigate | 777 // PlzNavigate |
775 void NavigatorImpl::RequestNavigation( | 778 void NavigatorImpl::RequestNavigation( |
776 FrameTreeNode* frame_tree_node, | 779 FrameTreeNode* frame_tree_node, |
| 780 const FrameNavigationEntry& frame_entry, |
777 const NavigationEntryImpl& entry, | 781 const NavigationEntryImpl& entry, |
778 NavigationController::ReloadType reload_type, | 782 NavigationController::ReloadType reload_type, |
779 base::TimeTicks navigation_start) { | 783 base::TimeTicks navigation_start) { |
780 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 784 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
781 switches::kEnableBrowserSideNavigation)); | 785 switches::kEnableBrowserSideNavigation)); |
782 DCHECK(frame_tree_node); | 786 DCHECK(frame_tree_node); |
783 int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id(); | 787 int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id(); |
784 FrameMsg_Navigate_Type::Value navigation_type = | 788 FrameMsg_Navigate_Type::Value navigation_type = |
785 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); | 789 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); |
| 790 // TODO(creis): Pass frame_entry and get the URL and referrer from there. |
786 scoped_ptr<NavigationRequest> navigation_request = | 791 scoped_ptr<NavigationRequest> navigation_request = |
787 NavigationRequest::CreateBrowserInitiated(frame_tree_node, entry, | 792 NavigationRequest::CreateBrowserInitiated(frame_tree_node, entry, |
788 navigation_type, | 793 navigation_type, |
789 navigation_start, controller_); | 794 navigation_start, controller_); |
790 // TODO(clamy): Check if navigations are blocked and if so store the | 795 // TODO(clamy): Check if navigations are blocked and if so store the |
791 // parameters. | 796 // parameters. |
792 | 797 |
793 // If there is an ongoing request, cancel and replace it. | 798 // If there is an ongoing request, cancel and replace it. |
794 NavigationRequest* ongoing_request = | 799 NavigationRequest* ongoing_request = |
795 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | 800 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 "Navigation.TimeToCommit_ExistingRenderer_BeforeUnloadDiscounted", | 878 "Navigation.TimeToCommit_ExistingRenderer_BeforeUnloadDiscounted", |
874 time_to_commit); | 879 time_to_commit); |
875 UMA_HISTOGRAM_TIMES( | 880 UMA_HISTOGRAM_TIMES( |
876 "Navigation.TimeToURLJobStart_ExistingRenderer_BeforeUnloadDiscounted", | 881 "Navigation.TimeToURLJobStart_ExistingRenderer_BeforeUnloadDiscounted", |
877 time_to_network); | 882 time_to_network); |
878 } | 883 } |
879 navigation_data_.reset(); | 884 navigation_data_.reset(); |
880 } | 885 } |
881 | 886 |
882 } // namespace content | 887 } // namespace content |
OLD | NEW |