Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/chrome_content_browser_client.h" | 5 #include "chrome/browser/chrome_content_browser_client.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/path_service.h" | 13 #include "base/path_service.h" |
| 14 #include "base/string_split.h" | |
| 14 #include "base/string_tokenizer.h" | 15 #include "base/string_tokenizer.h" |
| 15 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 16 #include "chrome/app/breakpad_mac.h" | 17 #include "chrome/app/breakpad_mac.h" |
| 17 #include "chrome/browser/browser_about_handler.h" | 18 #include "chrome/browser/browser_about_handler.h" |
| 18 #include "chrome/browser/browser_process.h" | 19 #include "chrome/browser/browser_process.h" |
| 19 #include "chrome/browser/browsing_data/browsing_data_helper.h" | 20 #include "chrome/browser/browsing_data/browsing_data_helper.h" |
| 20 #include "chrome/browser/browsing_data/browsing_data_remover.h" | 21 #include "chrome/browser/browsing_data/browsing_data_remover.h" |
| 21 #include "chrome/browser/character_encoding.h" | 22 #include "chrome/browser/character_encoding.h" |
| 22 #include "chrome/browser/chrome_benchmarking_message_filter.h" | 23 #include "chrome/browser/chrome_benchmarking_message_filter.h" |
| 23 #include "chrome/browser/chrome_quota_permission_context.h" | 24 #include "chrome/browser/chrome_quota_permission_context.h" |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 93 #include "content/public/browser/render_process_host.h" | 94 #include "content/public/browser/render_process_host.h" |
| 94 #include "content/public/browser/render_view_host.h" | 95 #include "content/public/browser/render_view_host.h" |
| 95 #include "content/public/browser/resource_context.h" | 96 #include "content/public/browser/resource_context.h" |
| 96 #include "content/public/browser/site_instance.h" | 97 #include "content/public/browser/site_instance.h" |
| 97 #include "content/public/browser/web_contents.h" | 98 #include "content/public/browser/web_contents.h" |
| 98 #include "content/public/browser/web_contents_view.h" | 99 #include "content/public/browser/web_contents_view.h" |
| 99 #include "content/public/common/child_process_host.h" | 100 #include "content/public/common/child_process_host.h" |
| 100 #include "content/public/common/content_descriptors.h" | 101 #include "content/public/common/content_descriptors.h" |
| 101 #include "grit/generated_resources.h" | 102 #include "grit/generated_resources.h" |
| 102 #include "grit/ui_resources.h" | 103 #include "grit/ui_resources.h" |
| 104 #include "net/base/escape.h" | |
| 103 #include "net/base/ssl_cert_request_info.h" | 105 #include "net/base/ssl_cert_request_info.h" |
| 104 #include "net/cookies/canonical_cookie.h" | 106 #include "net/cookies/canonical_cookie.h" |
| 105 #include "net/cookies/cookie_options.h" | 107 #include "net/cookies/cookie_options.h" |
| 106 #include "ppapi/host/ppapi_host.h" | 108 #include "ppapi/host/ppapi_host.h" |
| 107 #include "ui/base/l10n/l10n_util.h" | 109 #include "ui/base/l10n/l10n_util.h" |
| 108 #include "ui/base/resource/resource_bundle.h" | 110 #include "ui/base/resource/resource_bundle.h" |
| 109 #include "webkit/glue/webpreferences.h" | 111 #include "webkit/glue/webpreferences.h" |
| 110 #include "webkit/plugins/plugin_switches.h" | 112 #include "webkit/plugins/plugin_switches.h" |
| 111 | 113 |
| 112 #if defined(OS_WIN) | 114 #if defined(OS_WIN) |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 461 return main_parts; | 463 return main_parts; |
| 462 } | 464 } |
| 463 | 465 |
| 464 content::WebContentsView* | 466 content::WebContentsView* |
| 465 ChromeContentBrowserClient::OverrideCreateWebContentsView( | 467 ChromeContentBrowserClient::OverrideCreateWebContentsView( |
| 466 WebContents* web_contents, | 468 WebContents* web_contents, |
| 467 content::RenderViewHostDelegateView** render_view_host_delegate_view) { | 469 content::RenderViewHostDelegateView** render_view_host_delegate_view) { |
| 468 return NULL; | 470 return NULL; |
| 469 } | 471 } |
| 470 | 472 |
| 471 std::string ChromeContentBrowserClient::GetStoragePartitionIdForChildProcess( | |
| 472 content::BrowserContext* browser_context, | |
| 473 int child_process_id) { | |
| 474 const Extension* extension = NULL; | |
| 475 Profile* profile = Profile::FromBrowserContext(browser_context); | |
| 476 ExtensionService* extension_service = | |
| 477 extensions::ExtensionSystem::Get(profile)->extension_service(); | |
| 478 if (extension_service) { | |
| 479 std::set<std::string> extension_ids = | |
| 480 extension_service->process_map()-> | |
| 481 GetExtensionsInProcess(child_process_id); | |
| 482 if (!extension_ids.empty()) | |
| 483 // Since All the apps in a process share the same storage partition, | |
| 484 // we can pick any of them to retrieve the storage partition id. | |
| 485 extension = | |
| 486 extension_service->extensions()->GetByID(*(extension_ids.begin())); | |
| 487 } | |
| 488 return GetStoragePartitionIdForExtension(browser_context, extension); | |
| 489 } | |
| 490 | |
| 491 std::string ChromeContentBrowserClient::GetStoragePartitionIdForSite( | 473 std::string ChromeContentBrowserClient::GetStoragePartitionIdForSite( |
| 492 content::BrowserContext* browser_context, | 474 content::BrowserContext* browser_context, |
| 493 const GURL& site) { | 475 const GURL& site) { |
| 476 std::string app_id; | |
| 477 std::string partition_name; | |
| 478 bool in_memory = false; | |
| 479 | |
| 480 // We need to get all the pieces that will go into the storage partition | |
| 481 // identifier first, before we compose it. | |
| 482 GetStoragePartitionConfigForSite(browser_context, site, &app_id, | |
| 483 &partition_name, &in_memory); | |
| 484 | |
| 485 // If there is no app, we are in the default browser partition, so return | |
| 486 // an empty string. | |
| 487 if (app_id.empty()) | |
| 488 return std::string(); | |
| 489 | |
| 490 // A non-empty storage partition id string is of the form | |
| 491 // "app_id:in_memory:partition_name", where each of the three parts is | |
| 492 // optional and the ':' separators are mandatory. Since "in-memory" is fixed | |
| 493 // string and the app_id cannot contain the separator, it is safe to parse | |
| 494 // the string based on the two separators. | |
|
awong
2012/11/05 23:48:37
Question: How strong is our belief that |app_id|wi
nasko
2012/11/06 01:21:52
The app id is the ascii representation of a public
| |
| 495 std::string partition_id = base::StringPrintf("%s:%s:%s", | |
| 496 app_id.c_str(), | |
| 497 in_memory ? "in-memory" : "", | |
| 498 partition_name.c_str()); | |
| 499 | |
| 500 DCHECK(IsValidStoragePartitionId(browser_context,partition_id)); | |
| 501 return partition_id; | |
| 502 } | |
| 503 | |
| 504 bool ChromeContentBrowserClient::IsValidStoragePartitionId( | |
| 505 content::BrowserContext* browser_context, | |
| 506 const std::string& partition_id) { | |
| 507 // The default ID is empty and is always valid. | |
| 508 if (partition_id.empty()) | |
| 509 return true; | |
| 510 | |
| 511 // Now, parse the three parts of the partition ID, so we can verify them. | |
|
Charlie Reis
2012/11/06 00:17:18
Yeah, let's chat about this in person tomorrow. I
nasko
2012/11/07 00:33:57
Done.
| |
| 512 std::vector<std::string> tokens; | |
| 513 base::SplitString(partition_id, ':', &tokens); | |
| 514 | |
| 515 if (tokens.size() < 3) { | |
|
awong
2012/11/05 23:48:37
Should it be exactly 3?
nasko
2012/11/06 01:21:52
Not if the partition name itself has ':'. Since we
| |
| 516 NOTREACHED(); | |
| 517 return false; | |
| 518 } | |
| 519 | |
| 520 // Starting off with the app id, verify it exists. | |
| 521 if (!tokens[0].empty()) { | |
| 522 Profile* profile = Profile::FromBrowserContext(browser_context); | |
| 523 ExtensionService* extension_service = | |
| 524 extensions::ExtensionSystem::Get(profile)->extension_service(); | |
| 525 | |
| 526 // No extension service means no storage partitions in Chrome. | |
| 527 if (!extension_service) | |
| 528 return false; | |
| 529 if (extension_service->GetExtensionById(tokens[0], false) == NULL) | |
| 530 return false; | |
| 531 } | |
| 532 | |
| 533 // The second token is either empty or the "in-memory" string. | |
| 534 if (!tokens[1].empty() && tokens[1] != "in-memory") | |
| 535 return false; | |
| 536 | |
| 537 return true; | |
| 538 } | |
| 539 | |
| 540 void ChromeContentBrowserClient::GetStoragePartitionConfigForSite( | |
| 541 content::BrowserContext* browser_context, | |
| 542 const GURL& site, | |
| 543 std::string* app_id, | |
| 544 std::string* partition_name, | |
| 545 bool* in_memory) { | |
| 546 // For the webview tag, we create special guest processes, which host the | |
| 547 // tag content separately from the main application that embeds the tag. | |
| 548 // A webview tag can specify both the partition name and whether the storage | |
| 549 // for that partition should be persisted. Each tag gets a SiteInstance with | |
| 550 // a specially formatted URL, based on the application it is hosted by and | |
| 551 // the partition requested by it. The format for that URL is: | |
| 552 // guest://app_id/persist?partition_name | |
| 553 if (site.SchemeIs(chrome::kGuestScheme)) { | |
| 554 // Since guest URLs are only used for packaged apps, there must be an app | |
| 555 // id in the URL. | |
| 556 CHECK(site.has_host()); | |
| 557 *app_id = site.host(); | |
| 558 // Since persistence is optional, the path must either be empty or the | |
| 559 // literal string. | |
| 560 *in_memory = (site.path() != "/persist"); | |
| 561 // The partition name is user supplied value, which we have encoded when the | |
| 562 // URL was created, so it needs to be decoded. | |
| 563 *partition_name = net::UnescapeURLComponent(site.query(), | |
| 564 net::UnescapeRule::NORMAL); | |
| 565 return; | |
| 566 } | |
| 567 | |
| 494 const Extension* extension = NULL; | 568 const Extension* extension = NULL; |
| 495 Profile* profile = Profile::FromBrowserContext(browser_context); | 569 Profile* profile = Profile::FromBrowserContext(browser_context); |
| 496 ExtensionService* extension_service = | 570 ExtensionService* extension_service = |
| 497 extensions::ExtensionSystem::Get(profile)->extension_service(); | 571 extensions::ExtensionSystem::Get(profile)->extension_service(); |
| 498 if (extension_service) { | 572 if (extension_service) { |
| 499 extension = extension_service->extensions()-> | 573 extension = extension_service->extensions()-> |
| 500 GetExtensionOrAppByURL(ExtensionURLInfo(site)); | 574 GetExtensionOrAppByURL(ExtensionURLInfo(site)); |
| 575 if (extension && extension->is_storage_isolated()) { | |
| 576 *app_id = extension->id(); | |
| 577 *partition_name = std::string(); | |
|
awong
2012/11/05 23:48:37
partition_name->clear()?
nasko
2012/11/06 01:21:52
Done.
| |
| 578 *in_memory = false; | |
| 579 return; | |
| 580 } | |
| 501 } | 581 } |
| 502 | 582 |
| 503 return GetStoragePartitionIdForExtension(browser_context, extension); | 583 *app_id = std::string(); |
|
awong
2012/11/05 23:48:37
->clear(), here and below?
nasko
2012/11/06 01:21:52
Done.
| |
| 504 } | 584 *partition_name = std::string(); |
| 505 | 585 *in_memory = false; |
| 506 bool ChromeContentBrowserClient::IsValidStoragePartitionId( | |
| 507 content::BrowserContext* browser_context, | |
| 508 const std::string& partition_id) { | |
| 509 // The default ID is empty which is always allowed. | |
| 510 if (partition_id.empty()) | |
| 511 return true; | |
| 512 | |
| 513 // If it isn't empty, then it must belong to an extension of some sort. Parse | |
| 514 // out the extension ID and make sure it is still installed. | |
| 515 Profile* profile = Profile::FromBrowserContext(browser_context); | |
| 516 ExtensionService* extension_service = | |
| 517 extensions::ExtensionSystem::Get(profile)->extension_service(); | |
| 518 if (!extension_service) { | |
| 519 // No extension service means no storage partitions in Chrome. | |
| 520 return false; | |
| 521 } | |
| 522 | |
| 523 // See if we can find an extension. The |partition_id| is the extension ID so | |
| 524 // no parsing needed to be done. | |
| 525 return extension_service->GetExtensionById(partition_id, false) != NULL; | |
| 526 } | 586 } |
| 527 | 587 |
| 528 content::WebContentsViewDelegate* | 588 content::WebContentsViewDelegate* |
| 529 ChromeContentBrowserClient::GetWebContentsViewDelegate( | 589 ChromeContentBrowserClient::GetWebContentsViewDelegate( |
| 530 content::WebContents* web_contents) { | 590 content::WebContents* web_contents) { |
| 531 return chrome::CreateWebContentsViewDelegate(web_contents); | 591 return chrome::CreateWebContentsViewDelegate(web_contents); |
| 532 } | 592 } |
| 533 | 593 |
| 534 void ChromeContentBrowserClient::RenderViewHostCreated( | 594 void ChromeContentBrowserClient::RenderViewHostCreated( |
| 535 RenderViewHost* render_view_host) { | 595 RenderViewHost* render_view_host) { |
| (...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1601 if (web_prefs->default_encoding.empty()) { | 1661 if (web_prefs->default_encoding.empty()) { |
| 1602 prefs->ClearPref(prefs::kDefaultCharset); | 1662 prefs->ClearPref(prefs::kDefaultCharset); |
| 1603 web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset); | 1663 web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset); |
| 1604 } | 1664 } |
| 1605 DCHECK(!web_prefs->default_encoding.empty()); | 1665 DCHECK(!web_prefs->default_encoding.empty()); |
| 1606 | 1666 |
| 1607 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); | 1667 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); |
| 1608 chrome::ViewType view_type = chrome::GetViewType(web_contents); | 1668 chrome::ViewType view_type = chrome::GetViewType(web_contents); |
| 1609 ExtensionService* service = profile->GetExtensionService(); | 1669 ExtensionService* service = profile->GetExtensionService(); |
| 1610 if (service) { | 1670 if (service) { |
| 1611 const Extension* extension = service->extensions()->GetByID( | 1671 const GURL& url = rvh->GetSiteInstance()->GetSiteURL(); |
| 1612 rvh->GetSiteInstance()->GetSiteURL().host()); | 1672 const Extension* extension = service->extensions()->GetByID(url.host()); |
| 1613 extension_webkit_preferences::SetPreferences( | 1673 // Ensure that we are only granting extension preferences to URLs with |
| 1614 extension, view_type, web_prefs); | 1674 // the correct scheme. Without this check, guest:// schemes used by |
| 1675 // webview tags as well as hosts that happen to match the id of an | |
| 1676 // installed extension would get the wrong preferences. | |
| 1677 if (url.SchemeIs(chrome::kExtensionScheme)) { | |
| 1678 extension_webkit_preferences::SetPreferences( | |
| 1679 extension, view_type, web_prefs); | |
| 1680 } | |
| 1615 } | 1681 } |
| 1616 | 1682 |
| 1617 if (content::IsForceCompositingModeEnabled()) | 1683 if (content::IsForceCompositingModeEnabled()) |
| 1618 web_prefs->force_compositing_mode = true; | 1684 web_prefs->force_compositing_mode = true; |
| 1619 | 1685 |
| 1620 if (view_type == chrome::VIEW_TYPE_NOTIFICATION) { | 1686 if (view_type == chrome::VIEW_TYPE_NOTIFICATION) { |
| 1621 web_prefs->allow_scripts_to_close_windows = true; | 1687 web_prefs->allow_scripts_to_close_windows = true; |
| 1622 } else if (view_type == chrome::VIEW_TYPE_BACKGROUND_CONTENTS) { | 1688 } else if (view_type == chrome::VIEW_TYPE_BACKGROUND_CONTENTS) { |
| 1623 // Disable all kinds of acceleration for background pages. | 1689 // Disable all kinds of acceleration for background pages. |
| 1624 // See http://crbug.com/96005 and http://crbug.com/96006 | 1690 // See http://crbug.com/96005 and http://crbug.com/96006 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1861 base::Unretained(this), locale))) | 1927 base::Unretained(this), locale))) |
| 1862 io_thread_application_locale_ = locale; | 1928 io_thread_application_locale_ = locale; |
| 1863 } | 1929 } |
| 1864 | 1930 |
| 1865 void ChromeContentBrowserClient::SetApplicationLocaleOnIOThread( | 1931 void ChromeContentBrowserClient::SetApplicationLocaleOnIOThread( |
| 1866 const std::string& locale) { | 1932 const std::string& locale) { |
| 1867 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1933 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 1868 io_thread_application_locale_ = locale; | 1934 io_thread_application_locale_ = locale; |
| 1869 } | 1935 } |
| 1870 | 1936 |
| 1871 std::string ChromeContentBrowserClient::GetStoragePartitionIdForExtension( | |
| 1872 content::BrowserContext* browser_context, const Extension* extension) { | |
| 1873 // In chrome, we use the extension ID as the partition ID. This works well | |
| 1874 // because the extension ID fits the partition ID pattern and currently only | |
| 1875 // apps can designate that storage should be isolated. | |
| 1876 // | |
| 1877 // If |extension| is NULL, then the default, empty string, partition id is | |
| 1878 // used. | |
| 1879 std::string partition_id; | |
| 1880 if (extension && extension->is_storage_isolated()) { | |
| 1881 partition_id = extension->id(); | |
| 1882 } | |
| 1883 | |
| 1884 // Enforce that IsValidStoragePartitionId() implementation stays in sync. | |
| 1885 DCHECK(IsValidStoragePartitionId(browser_context, partition_id)); | |
| 1886 return partition_id; | |
| 1887 } | |
| 1888 | |
| 1889 | |
| 1890 } // namespace chrome | 1937 } // namespace chrome |
| OLD | NEW |