OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/tab_contents/render_view_host_manager.h" | 5 #include "chrome/browser/tab_contents/render_view_host_manager.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "chrome/browser/dom_ui/web_ui.h" | 9 #include "chrome/browser/dom_ui/web_ui.h" |
10 #include "chrome/browser/dom_ui/web_ui_factory.h" | 10 #include "chrome/browser/dom_ui/web_ui_factory.h" |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 // determine the site instance for this navigation. | 356 // determine the site instance for this navigation. |
357 // | 357 // |
358 // NOTE: This can be removed once we have a way to transition between | 358 // NOTE: This can be removed once we have a way to transition between |
359 // RenderViews in response to a link click. | 359 // RenderViews in response to a link click. |
360 // | 360 // |
361 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && | 361 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && |
362 entry.transition_type() == PageTransition::GENERATED) | 362 entry.transition_type() == PageTransition::GENERATED) |
363 return curr_instance; | 363 return curr_instance; |
364 | 364 |
365 const GURL& dest_url = entry.url(); | 365 const GURL& dest_url = entry.url(); |
| 366 NavigationController& controller = delegate_->GetControllerForRenderManager(); |
| 367 Profile* profile = controller.profile(); |
366 | 368 |
367 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it | 369 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it |
368 // for this entry. We won't commit the SiteInstance to this site until the | 370 // for this entry. We won't commit the SiteInstance to this site until the |
369 // navigation commits (in DidNavigate), unless the navigation entry was | 371 // navigation commits (in DidNavigate), unless the navigation entry was |
370 // restored or it's a Web UI as described below. | 372 // restored or it's a Web UI as described below. |
371 if (!curr_instance->has_site()) { | 373 if (!curr_instance->has_site()) { |
372 // If we've already created a SiteInstance for our destination, we don't | 374 // If we've already created a SiteInstance for our destination, we don't |
373 // want to use this unused SiteInstance; use the existing one. (We don't | 375 // want to use this unused SiteInstance; use the existing one. (We don't |
374 // do this check if the curr_instance has a site, because for now, we want | 376 // do this check if the curr_instance has a site, because for now, we want |
375 // to compare against the current URL and not the SiteInstance's site. In | 377 // to compare against the current URL and not the SiteInstance's site. In |
376 // this case, there is no current URL, so comparing against the site is ok. | 378 // this case, there is no current URL, so comparing against the site is ok. |
377 // See additional comments below.) | 379 // See additional comments below.) |
378 if (curr_instance->HasRelatedSiteInstance(dest_url)) { | 380 if (curr_instance->HasRelatedSiteInstance(dest_url)) |
379 return curr_instance->GetRelatedSiteInstance(dest_url); | 381 return curr_instance->GetRelatedSiteInstance(dest_url); |
380 } else { | 382 |
381 // Normally the "site" on the SiteInstance is set lazily when the load | 383 // For extensions and Web UI URLs (such as the new tab page), we do not |
382 // actually commits. This is to support better process sharing in case | 384 // want to use the curr_instance if it has no site, since it will have a |
383 // the site redirects to some other site: we want to use the destination | 385 // RenderProcessHost of TYPE_NORMAL. Create a new SiteInstance for this |
384 // site in the site instance. | 386 // URL instead (with the correct process type). |
385 // | 387 if (WebUIFactory::UseWebUIForURL(profile, dest_url)) |
386 // In the case of session restore, as it loads all the pages immediately | 388 return SiteInstance::CreateSiteInstanceForURL(profile, dest_url); |
387 // we need to set the site first, otherwise after a restore none of the | 389 |
388 // pages would share renderers. | 390 // Normally the "site" on the SiteInstance is set lazily when the load |
389 // | 391 // actually commits. This is to support better process sharing in case |
390 // For Web UI (this mostly comes up for the new tab page), the | 392 // the site redirects to some other site: we want to use the destination |
391 // SiteInstance has special meaning: we never want to reassign the | 393 // site in the site instance. |
392 // process. If you navigate to another site before the Web UI commits, | 394 // |
393 // we still want to create a new process rather than re-using the | 395 // In the case of session restore, as it loads all the pages immediately |
394 // existing Web UI process. | 396 // we need to set the site first, otherwise after a restore none of the |
395 if (entry.restore_type() != NavigationEntry::RESTORE_NONE || | 397 // pages would share renderers in process-per-site. |
396 WebUIFactory::HasWebUIScheme(dest_url)) | 398 if (entry.restore_type() != NavigationEntry::RESTORE_NONE) |
397 curr_instance->SetSite(dest_url); | 399 curr_instance->SetSite(dest_url); |
398 return curr_instance; | 400 |
399 } | 401 return curr_instance; |
400 } | 402 } |
401 | 403 |
402 // Otherwise, only create a new SiteInstance for cross-site navigation. | 404 // Otherwise, only create a new SiteInstance for cross-site navigation. |
403 | 405 |
404 // TODO(creis): Once we intercept links and script-based navigations, we | 406 // TODO(creis): Once we intercept links and script-based navigations, we |
405 // will be able to enforce that all entries in a SiteInstance actually have | 407 // will be able to enforce that all entries in a SiteInstance actually have |
406 // the same site, and it will be safe to compare the URL against the | 408 // the same site, and it will be safe to compare the URL against the |
407 // SiteInstance's site, as follows: | 409 // SiteInstance's site, as follows: |
408 // const GURL& current_url = curr_instance->site(); | 410 // const GURL& current_url = curr_instance->site(); |
409 // For now, though, we're in a hybrid model where you only switch | 411 // For now, though, we're in a hybrid model where you only switch |
410 // SiteInstances if you type in a cross-site URL. This means we have to | 412 // SiteInstances if you type in a cross-site URL. This means we have to |
411 // compare the entry's URL to the last committed entry's URL. | 413 // compare the entry's URL to the last committed entry's URL. |
412 NavigationController& controller = delegate_->GetControllerForRenderManager(); | |
413 NavigationEntry* curr_entry = controller.GetLastCommittedEntry(); | 414 NavigationEntry* curr_entry = controller.GetLastCommittedEntry(); |
414 if (interstitial_page_) { | 415 if (interstitial_page_) { |
415 // The interstitial is currently the last committed entry, but we want to | 416 // The interstitial is currently the last committed entry, but we want to |
416 // compare against the last non-interstitial entry. | 417 // compare against the last non-interstitial entry. |
417 curr_entry = controller.GetEntryAtOffset(-1); | 418 curr_entry = controller.GetEntryAtOffset(-1); |
418 } | 419 } |
419 // If there is no last non-interstitial entry (and curr_instance already | 420 // If there is no last non-interstitial entry (and curr_instance already |
420 // has a site), then we must have been opened from another tab. We want | 421 // has a site), then we must have been opened from another tab. We want |
421 // to compare against the URL of the page that opened us, but we can't | 422 // to compare against the URL of the page that opened us, but we can't |
422 // get to it directly. The best we can do is check against the site of | 423 // get to it directly. The best we can do is check against the site of |
423 // the SiteInstance. This will be correct when we intercept links and | 424 // the SiteInstance. This will be correct when we intercept links and |
424 // script-based navigations, but for now, it could place some pages in a | 425 // script-based navigations, but for now, it could place some pages in a |
425 // new process unnecessarily. We should only hit this case if a page tries | 426 // new process unnecessarily. We should only hit this case if a page tries |
426 // to open a new tab to an interstitial-inducing URL, and then navigates | 427 // to open a new tab to an interstitial-inducing URL, and then navigates |
427 // the page to a different same-site URL. (This seems very unlikely in | 428 // the page to a different same-site URL. (This seems very unlikely in |
428 // practice.) | 429 // practice.) |
429 const GURL& current_url = (curr_entry) ? curr_entry->url() : | 430 const GURL& current_url = (curr_entry) ? curr_entry->url() : |
430 curr_instance->site(); | 431 curr_instance->site(); |
431 Profile* profile = controller.profile(); | |
432 | 432 |
433 if (SiteInstance::IsSameWebSite(profile, current_url, dest_url)) { | 433 if (SiteInstance::IsSameWebSite(profile, current_url, dest_url)) { |
434 return curr_instance; | 434 return curr_instance; |
435 } else if (ShouldSwapProcessesForNavigation(curr_entry, &entry)) { | 435 } else if (ShouldSwapProcessesForNavigation(curr_entry, &entry)) { |
436 // When we're swapping, we need to force the site instance AND browsing | 436 // When we're swapping, we need to force the site instance AND browsing |
437 // instance to be different ones. This addresses special cases where we use | 437 // instance to be different ones. This addresses special cases where we use |
438 // a single BrowsingInstance for all pages of a certain type (e.g., New Tab | 438 // a single BrowsingInstance for all pages of a certain type (e.g., New Tab |
439 // Pages), keeping them in the same process. When you navigate away from | 439 // Pages), keeping them in the same process. When you navigate away from |
440 // that page, we want to explicity ignore that BrowsingInstance and group | 440 // that page, we want to explicity ignore that BrowsingInstance and group |
441 // this page into the appropriate SiteInstance for its URL. | 441 // this page into the appropriate SiteInstance for its URL. |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), | 720 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), |
721 Details<RenderViewHostSwitchedDetails>(&details)); | 721 Details<RenderViewHostSwitchedDetails>(&details)); |
722 | 722 |
723 // This will cause the old RenderViewHost to delete itself. | 723 // This will cause the old RenderViewHost to delete itself. |
724 old_render_view_host->Shutdown(); | 724 old_render_view_host->Shutdown(); |
725 | 725 |
726 // Let the task manager know that we've swapped RenderViewHosts, since it | 726 // Let the task manager know that we've swapped RenderViewHosts, since it |
727 // might need to update its process groupings. | 727 // might need to update its process groupings. |
728 delegate_->NotifySwappedFromRenderManager(); | 728 delegate_->NotifySwappedFromRenderManager(); |
729 } | 729 } |
OLD | NEW |