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