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/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 "content/browser/frame_host/frame_tree.h" | 8 #include "content/browser/frame_host/frame_tree.h" |
| 9 #include "content/browser/frame_host/frame_tree_node.h" | 9 #include "content/browser/frame_host/frame_tree_node.h" |
| 10 #include "content/browser/frame_host/navigation_controller_impl.h" | 10 #include "content/browser/frame_host/navigation_controller_impl.h" |
| 11 #include "content/browser/frame_host/navigation_entry_impl.h" | 11 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 12 #include "content/browser/frame_host/navigator_delegate.h" | 12 #include "content/browser/frame_host/navigator_delegate.h" |
| 13 #include "content/browser/frame_host/render_frame_host_impl.h" | 13 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 14 #include "content/browser/renderer_host/render_view_host_impl.h" | 14 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 15 #include "content/browser/site_instance_impl.h" | 15 #include "content/browser/site_instance_impl.h" |
| 16 #include "content/browser/webui/web_ui_controller_factory_registry.h" | 16 #include "content/browser/webui/web_ui_controller_factory_registry.h" |
| 17 #include "content/common/frame_messages.h" | 17 #include "content/common/frame_messages.h" |
| 18 #include "content/common/view_messages.h" | 18 #include "content/common/view_messages.h" |
| 19 #include "content/public/browser/browser_context.h" | 19 #include "content/public/browser/browser_context.h" |
| 20 #include "content/public/browser/content_browser_client.h" | 20 #include "content/public/browser/content_browser_client.h" |
| 21 #include "content/public/browser/invalidate_type.h" | 21 #include "content/public/browser/invalidate_type.h" |
| 22 #include "content/public/browser/navigation_controller.h" | 22 #include "content/public/browser/navigation_controller.h" |
| 23 #include "content/public/browser/navigation_details.h" | |
| 23 #include "content/public/browser/render_view_host.h" | 24 #include "content/public/browser/render_view_host.h" |
| 24 #include "content/public/common/bindings_policy.h" | 25 #include "content/public/common/bindings_policy.h" |
| 26 #include "content/public/common/content_client.h" | |
| 25 #include "content/public/common/content_switches.h" | 27 #include "content/public/common/content_switches.h" |
| 26 #include "content/public/common/url_constants.h" | 28 #include "content/public/common/url_constants.h" |
| 27 #include "content/public/common/url_utils.h" | 29 #include "content/public/common/url_utils.h" |
| 28 | 30 |
| 31 namespace { | |
|
Charlie Reis
2014/02/05 23:30:37
Why not put this in the namespace below, alongside
nasko
2014/02/06 01:55:13
Moved to the namespace below. I think we will have
| |
| 32 | |
| 33 content::RenderFrameHostManager* GetRenderManager( | |
| 34 content::RenderFrameHostImpl* rfh) { | |
| 35 return rfh->frame_tree_node()->render_manager(); | |
| 36 } | |
| 37 | |
| 38 } // namespace | |
| 39 | |
| 29 namespace content { | 40 namespace content { |
| 30 | 41 |
| 31 namespace { | 42 namespace { |
| 32 | 43 |
| 33 ViewMsg_Navigate_Type::Value GetNavigationType( | 44 ViewMsg_Navigate_Type::Value GetNavigationType( |
| 34 BrowserContext* browser_context, const NavigationEntryImpl& entry, | 45 BrowserContext* browser_context, const NavigationEntryImpl& entry, |
| 35 NavigationController::ReloadType reload_type) { | 46 NavigationController::ReloadType reload_type) { |
| 36 switch (reload_type) { | 47 switch (reload_type) { |
| 37 case NavigationControllerImpl::RELOAD: | 48 case NavigationControllerImpl::RELOAD: |
| 38 return ViewMsg_Navigate_Type::RELOAD; | 49 return ViewMsg_Navigate_Type::RELOAD; |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 return NavigateToEntry( | 365 return NavigateToEntry( |
| 355 render_frame_host, | 366 render_frame_host, |
| 356 *NavigationEntryImpl::FromNavigationEntry(controller_->GetPendingEntry()), | 367 *NavigationEntryImpl::FromNavigationEntry(controller_->GetPendingEntry()), |
| 357 reload_type); | 368 reload_type); |
| 358 } | 369 } |
| 359 | 370 |
| 360 base::TimeTicks NavigatorImpl::GetCurrentLoadStart() { | 371 base::TimeTicks NavigatorImpl::GetCurrentLoadStart() { |
| 361 return current_load_start_; | 372 return current_load_start_; |
| 362 } | 373 } |
| 363 | 374 |
| 375 void NavigatorImpl::DidNavigate( | |
| 376 RenderFrameHostImpl* render_frame_host, | |
| 377 const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params) { | |
| 378 FrameHostMsg_DidCommitProvisionalLoad_Params params(input_params); | |
| 379 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); | |
| 380 RenderViewHostImpl* rvh = render_frame_host->render_view_host(); | |
| 381 bool use_site_per_process = | |
| 382 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess); | |
| 383 if (frame_tree->IsFirstNavigationAfterSwap()) { | |
| 384 // First navigation should be a main frame navigation. | |
| 385 // TODO(creis): This DCHECK is currently disabled for --site-per-process | |
| 386 // because cross-process subframe navigations still have a main frame | |
| 387 // PageTransition. | |
| 388 if (!use_site_per_process) | |
| 389 DCHECK(PageTransitionIsMainFrame(params.transition)); | |
| 390 frame_tree->OnFirstNavigationAfterSwap(params.frame_id); | |
| 391 } | |
| 392 | |
| 393 // When using --site-per-process, look up the FrameTreeNode ID that the | |
| 394 // renderer-specific frame ID corresponds to. | |
| 395 int64 frame_tree_node_id = frame_tree->root()->frame_tree_node_id(); | |
| 396 if (use_site_per_process) { | |
| 397 FrameTreeNode* source_node = frame_tree->FindByFrameID(params.frame_id); | |
| 398 if (source_node) | |
| 399 frame_tree_node_id = source_node->frame_tree_node_id(); | |
|
Charlie Reis
2014/02/05 23:30:37
I think we can get frame_tree_node_id from render_
nasko
2014/02/06 01:55:13
I agree with the simpler code, so fixed. I don't t
Charlie Reis
2014/02/06 21:49:07
Ah, good point.
| |
| 400 | |
| 401 // TODO(creis): In the short term, cross-process subframe navigations are | |
| 402 // happening in the pending RenderViewHost's top-level frame. (We need to | |
| 403 // both mirror the frame tree and get the navigation to occur in the correct | |
| 404 // subframe to fix this.) Until then, we should check whether we have a | |
| 405 // pending NavigationEntry with a frame ID and if so, treat the | |
| 406 // cross-process "main frame" navigation as a subframe navigation. This | |
| 407 // limits us to a single cross-process subframe per RVH, and it affects | |
| 408 // NavigateToEntry, NavigatorImpl::DidStartProvisionalLoad, and | |
| 409 // OnDidFinishLoad. | |
| 410 NavigationEntryImpl* pending_entry = | |
| 411 NavigationEntryImpl::FromNavigationEntry( | |
| 412 controller_->GetPendingEntry()); | |
| 413 int root_ftn_id = frame_tree->root()->frame_tree_node_id(); | |
| 414 if (pending_entry && | |
| 415 pending_entry->frame_tree_node_id() != -1 && | |
| 416 pending_entry->frame_tree_node_id() != root_ftn_id) { | |
| 417 params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; | |
| 418 frame_tree_node_id = pending_entry->frame_tree_node_id(); | |
|
Charlie Reis
2014/02/05 23:30:37
This part is probably still necessary, unlike the
nasko
2014/02/06 01:55:13
Done.
| |
| 419 } | |
| 420 } | |
| 421 | |
| 422 if (PageTransitionIsMainFrame(params.transition)) { | |
| 423 // When overscroll navigation gesture is enabled, a screenshot of the page | |
| 424 // in its current state is taken so that it can be used during the | |
| 425 // nav-gesture. It is necessary to take the screenshot here, before calling | |
| 426 // RenderFrameHostManager::DidNavigateMainFrame, because that can change | |
| 427 // WebContents::GetRenderViewHost to return the new host, instead of the one | |
| 428 // that may have just been swapped out. | |
| 429 if (delegate_ && delegate_->CanOverscrollContent()) | |
| 430 controller_->TakeScreenshot(); | |
| 431 | |
| 432 if (!use_site_per_process) | |
| 433 GetRenderManager(render_frame_host)->DidNavigateMainFrame(rvh); | |
| 434 } | |
| 435 | |
| 436 // When using --site-per-process, we notify the RFHM for all navigations, | |
| 437 // not just main frame navigations. | |
| 438 if (use_site_per_process) { | |
| 439 FrameTreeNode* frame = frame_tree->FindByID(frame_tree_node_id); | |
| 440 // TODO(creis): Rename to DidNavigateFrame. | |
| 441 frame->render_manager()->DidNavigateMainFrame(rvh); | |
| 442 } | |
| 443 | |
| 444 // Update the site of the SiteInstance if it doesn't have one yet, unless | |
| 445 // assigning a site is not necessary for this URL. In that case, the | |
| 446 // SiteInstance can still be considered unused until a navigation to a real | |
| 447 // page. | |
| 448 if (!static_cast<SiteInstanceImpl*>( | |
| 449 render_frame_host->GetSiteInstance())->HasSite() && | |
|
Charlie Reis
2014/02/05 23:30:37
Let's make this easier to read by grabbing site_in
nasko
2014/02/06 01:55:13
Done.
| |
| 450 ShouldAssignSiteForURL(params.url)) { | |
| 451 static_cast<SiteInstanceImpl*>( | |
| 452 render_frame_host->GetSiteInstance())->SetSite(params.url); | |
| 453 } | |
| 454 | |
| 455 // The MIME type is updated only for the main frame. For a subframe, | |
| 456 // RenderView::UpdateURL does not set params.contents_mime_type. | |
|
Charlie Reis
2014/02/05 23:30:37
Please preserve the rest of jungshik's comment. (
nasko
2014/02/06 01:55:13
Done.
| |
| 457 if (PageTransitionIsMainFrame(params.transition) && delegate_) | |
| 458 delegate_->SetMainFrameMimeType(params.contents_mime_type); | |
| 459 | |
| 460 LoadCommittedDetails details; | |
| 461 bool did_navigate = controller_->RendererDidNavigate(rvh, params, &details); | |
| 462 | |
| 463 // For now, keep track of each frame's URL in its FrameTreeNode. This lets | |
| 464 // us estimate our process count for implementing OOP iframes. | |
| 465 // TODO(creis): Remove this when we track which pages commit in each frame. | |
| 466 frame_tree->SetFrameUrl(params.frame_id, params.url); | |
| 467 | |
| 468 // Send notification about committed provisional loads. This notification is | |
| 469 // different from the NAV_ENTRY_COMMITTED notification which doesn't include | |
| 470 // the actual URL navigated to and isn't sent for AUTO_SUBFRAME navigations. | |
| 471 if (details.type != NAVIGATION_TYPE_NAV_IGNORE && delegate_) { | |
| 472 // For AUTO_SUBFRAME navigations, an event for the main frame is generated | |
| 473 // that is not recorded in the navigation history. For the purpose of | |
| 474 // tracking navigation events, we treat this event as a sub frame navigation | |
| 475 // event. | |
| 476 bool is_main_frame = did_navigate ? details.is_main_frame : false; | |
| 477 PageTransition transition_type = params.transition; | |
| 478 // Whether or not a page transition was triggered by going backward or | |
| 479 // forward in the history is only stored in the navigation controller's | |
| 480 // entry list. | |
| 481 if (did_navigate && | |
| 482 (controller_->GetLastCommittedEntry()->GetTransitionType() & | |
| 483 PAGE_TRANSITION_FORWARD_BACK)) { | |
| 484 transition_type = PageTransitionFromInt( | |
| 485 params.transition | PAGE_TRANSITION_FORWARD_BACK); | |
| 486 } | |
| 487 | |
| 488 delegate_->DidCommitProvisionalLoad(params.frame_id, | |
| 489 params.frame_unique_name, | |
| 490 is_main_frame, | |
| 491 params.url, | |
| 492 transition_type, | |
| 493 render_frame_host); | |
| 494 } | |
| 495 | |
| 496 if (!did_navigate) | |
| 497 return; // No navigation happened. | |
| 498 | |
| 499 // DO NOT ADD MORE STUFF TO THIS FUNCTION! Your component should either listen | |
| 500 // for the appropriate notification (best) or you can add it to | |
| 501 // DidNavigateMainFramePostCommit / DidNavigateAnyFramePostCommit (only if | |
| 502 // necessary, please). | |
| 503 | |
| 504 // Run post-commit tasks. | |
| 505 if (delegate_) { | |
| 506 if (details.is_main_frame) | |
| 507 delegate_->DidNavigateMainFramePostCommit(details, params); | |
| 508 | |
| 509 delegate_->DidNavigateAnyFramePostCommit( | |
| 510 render_frame_host, details, params); | |
| 511 } | |
| 512 } | |
| 513 | |
| 514 bool NavigatorImpl::ShouldAssignSiteForURL(const GURL& url) { | |
| 515 // about:blank should not "use up" a new SiteInstance. The SiteInstance can | |
| 516 // still be used for a normal web site. | |
| 517 if (url == GURL(kAboutBlankURL)) | |
| 518 return false; | |
| 519 | |
| 520 // The embedder will then have the opportunity to determine if the URL | |
| 521 // should "use up" the SiteInstance. | |
| 522 return GetContentClient()->browser()->ShouldAssignSiteForURL(url); | |
| 523 } | |
| 524 | |
| 364 } // namespace content | 525 } // namespace content |
| OLD | NEW |