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) { | |
Charlie Reis
2014/02/06 21:49:07
nit: Wrong indent (2 spaces too many)
nasko
2014/02/06 21:58:43
Done.
| |
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 |