Index: chrome/browser/chrome_content_browser_client.cc |
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc |
index 68a1e3a8a74905a02760a6c04d96605c5c7b345e..d783fb96e72105da574a51e6b7565666229bed33 100644 |
--- a/chrome/browser/chrome_content_browser_client.cc |
+++ b/chrome/browser/chrome_content_browser_client.cc |
@@ -33,11 +33,7 @@ |
#include "chrome/browser/defaults.h" |
#include "chrome/browser/devtools/chrome_devtools_manager_delegate.h" |
#include "chrome/browser/download/download_prefs.h" |
-#include "chrome/browser/extensions/browser_permissions_policy_delegate.h" |
#include "chrome/browser/extensions/chrome_content_browser_client_extensions_part.h" |
-#include "chrome/browser/extensions/extension_service.h" |
-#include "chrome/browser/extensions/extension_util.h" |
-#include "chrome/browser/extensions/suggest_permission_util.h" |
#include "chrome/browser/geolocation/chrome_access_token_store.h" |
#include "chrome/browser/geolocation/geolocation_permission_context.h" |
#include "chrome/browser/geolocation/geolocation_permission_context_factory.h" |
@@ -61,7 +57,6 @@ |
#include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/profiles/profile_io_data.h" |
-#include "chrome/browser/profiles/profile_manager.h" |
#include "chrome/browser/renderer_host/chrome_render_message_filter.h" |
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" |
#include "chrome/browser/search/instant_service.h" |
@@ -87,9 +82,6 @@ |
#include "chrome/common/chrome_paths.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/env_vars.h" |
-#include "chrome/common/extensions/extension_constants.h" |
-#include "chrome/common/extensions/extension_process_policy.h" |
-#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" |
#include "chrome/common/logging_chrome.h" |
#include "chrome/common/pepper_permission_util.h" |
#include "chrome/common/pref_names.h" |
@@ -123,18 +115,11 @@ |
#include "content/public/common/show_desktop_notification_params.h" |
#include "content/public/common/url_utils.h" |
#include "content/public/common/web_preferences.h" |
-#include "extensions/browser/extension_host.h" |
#include "extensions/browser/extension_system.h" |
-#include "extensions/browser/info_map.h" |
-#include "extensions/browser/process_manager.h" |
-#include "extensions/browser/process_map.h" |
-#include "extensions/browser/view_type_utils.h" |
#include "extensions/common/constants.h" |
#include "extensions/common/extension.h" |
#include "extensions/common/extension_set.h" |
-#include "extensions/common/manifest_handlers/background_info.h" |
#include "extensions/common/manifest_handlers/shared_module_info.h" |
-#include "extensions/common/manifest_handlers/web_accessible_resources_info.h" |
#include "extensions/common/permissions/permissions_data.h" |
#include "extensions/common/permissions/socket_permission.h" |
#include "extensions/common/switches.h" |
@@ -230,12 +215,16 @@ |
#endif |
#if defined(ENABLE_EXTENSIONS) |
+#include "chrome/browser/extensions/extension_service.h" |
+#include "chrome/browser/extensions/extension_util.h" |
+#include "chrome/browser/extensions/suggest_permission_util.h" |
#include "chrome/browser/guest_view/guest_view_base.h" |
#include "chrome/browser/guest_view/guest_view_constants.h" |
#include "chrome/browser/guest_view/guest_view_manager.h" |
#include "chrome/browser/guest_view/web_view/web_view_guest.h" |
#include "chrome/browser/guest_view/web_view/web_view_permission_helper.h" |
#include "chrome/browser/guest_view/web_view/web_view_renderer_state.h" |
+#include "extensions/common/manifest_handlers/background_info.h" |
#endif |
#if defined(ENABLE_SPELLCHECK) |
@@ -264,6 +253,7 @@ using content::SiteInstance; |
using content::WebContents; |
using content::WebPreferences; |
using extensions::APIPermission; |
+using extensions::ChromeContentBrowserClientExtensionsPart; |
using extensions::Extension; |
using extensions::InfoMap; |
using extensions::Manifest; |
@@ -415,66 +405,6 @@ bool HandleWebUIReverse(GURL* url, content::BrowserContext* browser_context) { |
return RemoveUberHost(url); |
} |
-// Used by the GetPrivilegeRequiredByUrl() and GetProcessPrivilege() functions |
-// below. Extension, and isolated apps require different privileges to be |
-// granted to their RenderProcessHosts. This classification allows us to make |
-// sure URLs are served by hosts with the right set of privileges. |
-enum RenderProcessHostPrivilege { |
- PRIV_NORMAL, |
- PRIV_HOSTED, |
- PRIV_ISOLATED, |
- PRIV_EXTENSION, |
-}; |
- |
-RenderProcessHostPrivilege GetPrivilegeRequiredByUrl( |
- const GURL& url, |
- ExtensionService* service) { |
- // Default to a normal renderer cause it is lower privileged. This should only |
- // occur if the URL on a site instance is either malformed, or uninitialized. |
- // If it is malformed, then there is no need for better privileges anyways. |
- // If it is uninitialized, but eventually settles on being an a scheme other |
- // than normal webrenderer, the navigation logic will correct us out of band |
- // anyways. |
- if (!url.is_valid()) |
- return PRIV_NORMAL; |
- |
- if (url.SchemeIs(extensions::kExtensionScheme)) { |
- const Extension* extension = |
- service->extensions()->GetByID(url.host()); |
- if (extension && |
- extensions::AppIsolationInfo::HasIsolatedStorage(extension)) |
- return PRIV_ISOLATED; |
- if (extension && extension->is_hosted_app()) |
- return PRIV_HOSTED; |
- |
- return PRIV_EXTENSION; |
- } |
- |
- return PRIV_NORMAL; |
-} |
- |
-RenderProcessHostPrivilege GetProcessPrivilege( |
- content::RenderProcessHost* process_host, |
- extensions::ProcessMap* process_map, |
- ExtensionService* service) { |
- std::set<std::string> extension_ids = |
- process_map->GetExtensionsInProcess(process_host->GetID()); |
- if (extension_ids.empty()) |
- return PRIV_NORMAL; |
- |
- for (std::set<std::string>::iterator iter = extension_ids.begin(); |
- iter != extension_ids.end(); ++iter) { |
- const Extension* extension = service->GetExtensionById(*iter, false); |
- if (extension && |
- extensions::AppIsolationInfo::HasIsolatedStorage(extension)) |
- return PRIV_ISOLATED; |
- if (extension && extension->is_hosted_app()) |
- return PRIV_HOSTED; |
- } |
- |
- return PRIV_EXTENSION; |
-} |
- |
bool CertMatchesFilter(const net::X509Certificate& cert, |
const base::DictionaryValue& filter) { |
// TODO(markusheintz): This is the minimal required filter implementation. |
@@ -659,16 +589,12 @@ ChromeContentBrowserClient::ChromeContentBrowserClient() |
allowed_socket_origins_.insert(kPredefinedAllowedSocketOrigins[i]); |
#endif |
- permissions_policy_delegate_.reset( |
- new extensions::BrowserPermissionsPolicyDelegate()); |
- |
#if !defined(OS_ANDROID) |
TtsExtensionEngine* tts_extension_engine = TtsExtensionEngine::GetInstance(); |
TtsController::GetInstance()->SetTtsEngineDelegate(tts_extension_engine); |
#endif |
- extra_parts_.push_back( |
- new extensions::ChromeContentBrowserClientExtensionsPart); |
+ extra_parts_.push_back(new ChromeContentBrowserClientExtensionsPart); |
} |
ChromeContentBrowserClient::~ChromeContentBrowserClient() { |
@@ -937,27 +863,8 @@ GURL ChromeContentBrowserClient::GetEffectiveURL( |
return GetEffectiveURLForSignin(url); |
#endif |
- // If the input |url| is part of an installed app, the effective URL is an |
- // extension URL with the ID of that extension as the host. This has the |
- // effect of grouping apps together in a common SiteInstance. |
- ExtensionService* extension_service = |
- extensions::ExtensionSystem::Get(profile)->extension_service(); |
- if (!extension_service) |
- return url; |
- |
- const Extension* extension = extension_service->extensions()-> |
- GetHostedAppByURL(url); |
- if (!extension) |
- return url; |
- |
- // Bookmark apps do not use the hosted app process model, and should be |
- // treated as normal URLs. |
- if (extension->from_bookmark()) |
- return url; |
- |
- // If the URL is part of an extension's web extent, convert it to an |
- // extension URL. |
- return extension->GetResourceURL(url.path()); |
+ return ChromeContentBrowserClientExtensionsPart::GetEffectiveURL( |
+ profile, url); |
} |
bool ChromeContentBrowserClient::ShouldUseProcessPerSite( |
@@ -979,35 +886,8 @@ bool ChromeContentBrowserClient::ShouldUseProcessPerSite( |
return true; |
#endif |
- if (!effective_url.SchemeIs(extensions::kExtensionScheme)) |
- return false; |
- |
- ExtensionService* extension_service = |
- extensions::ExtensionSystem::Get(profile)->extension_service(); |
- if (!extension_service) |
- return false; |
- |
- const Extension* extension = |
- extension_service->extensions()->GetExtensionOrAppByURL(effective_url); |
- if (!extension) |
- return false; |
- |
- // If the URL is part of a hosted app that does not have the background |
- // permission, or that does not allow JavaScript access to the background |
- // page, we want to give each instance its own process to improve |
- // responsiveness. |
- if (extension->GetType() == Manifest::TYPE_HOSTED_APP) { |
- if (!extension->permissions_data()->HasAPIPermission( |
- APIPermission::kBackground) || |
- !extensions::BackgroundInfo::AllowJSAccess(extension)) { |
- return false; |
- } |
- } |
- |
- // Hosted apps that have script access to their background page must use |
- // process per site, since all instances can make synchronous calls to the |
- // background window. Other extensions should use process per site as well. |
- return true; |
+ return ChromeContentBrowserClientExtensionsPart::ShouldUseProcessPerSite( |
+ profile, effective_url); |
} |
// These are treated as WebUI schemes but do not get WebUI bindings. Also, |
@@ -1060,58 +940,18 @@ bool ChromeContentBrowserClient::IsHandledURL(const GURL& url) { |
bool ChromeContentBrowserClient::CanCommitURL( |
content::RenderProcessHost* process_host, |
const GURL& url) { |
- // We need to let most extension URLs commit in any process, since this can |
- // be allowed due to web_accessible_resources. Most hosted app URLs may also |
- // load in any process (e.g., in an iframe). However, the Chrome Web Store |
- // cannot be loaded in iframes and should never be requested outside its |
- // process. |
- Profile* profile = |
- Profile::FromBrowserContext(process_host->GetBrowserContext()); |
- ExtensionService* service = |
- extensions::ExtensionSystem::Get(profile)->extension_service(); |
- if (!service) |
- return true; |
- const Extension* new_extension = |
- service->extensions()->GetExtensionOrAppByURL(url); |
- if (new_extension && |
- new_extension->is_hosted_app() && |
- new_extension->id() == extension_misc::kWebStoreAppId && |
- !extensions::ProcessMap::Get(profile)-> |
- Contains(new_extension->id(), process_host->GetID())) { |
- return false; |
- } |
- |
- return true; |
+ return ChromeContentBrowserClientExtensionsPart::CanCommitURL( |
+ process_host, url); |
} |
bool ChromeContentBrowserClient::ShouldAllowOpenURL( |
content::SiteInstance* site_instance, const GURL& url) { |
GURL from_url = site_instance->GetSiteURL(); |
- // Do not allow pages from the web or other extensions navigate to |
- // non-web-accessible extension resources. |
- if (url.SchemeIs(extensions::kExtensionScheme) && |
- (from_url.SchemeIsHTTPOrHTTPS() || |
- from_url.SchemeIs(extensions::kExtensionScheme))) { |
- Profile* profile = Profile::FromBrowserContext( |
- site_instance->GetProcess()->GetBrowserContext()); |
- ExtensionService* service = |
- extensions::ExtensionSystem::Get(profile)->extension_service(); |
- if (!service) |
- return true; |
- const Extension* extension = |
- service->extensions()->GetExtensionOrAppByURL(url); |
- if (!extension) |
- return true; |
- const Extension* from_extension = |
- service->extensions()->GetExtensionOrAppByURL( |
- site_instance->GetSiteURL()); |
- if (from_extension && from_extension->id() == extension->id()) |
- return true; |
- if (!extensions::WebAccessibleResourcesInfo::IsResourceWebAccessible( |
- extension, url.path())) |
- return false; |
- } |
+ bool result; |
+ if (ChromeContentBrowserClientExtensionsPart::ShouldAllowOpenURL( |
+ site_instance, from_url, url, &result)) |
+ return result; |
// Do not allow chrome://chrome-signin navigate to other chrome:// URLs, since |
// the signin page may host untrusted web content. |
@@ -1156,21 +996,8 @@ bool ChromeContentBrowserClient::IsSuitableHost( |
return SigninManager::IsWebBasedSigninFlowURL(site_url); |
#endif |
- ExtensionService* service = |
- extensions::ExtensionSystem::Get(profile)->extension_service(); |
- extensions::ProcessMap* process_map = extensions::ProcessMap::Get(profile); |
- |
- // These may be NULL during tests. In that case, just assume any site can |
- // share any host. |
- if (!service || !process_map) |
- return true; |
- |
- // Otherwise, just make sure the process privilege matches the privilege |
- // required by the site. |
- RenderProcessHostPrivilege privilege_required = |
- GetPrivilegeRequiredByUrl(site_url, service); |
- return GetProcessPrivilege(process_host, process_map, service) == |
- privilege_required; |
+ return ChromeContentBrowserClientExtensionsPart::IsSuitableHost( |
+ profile, process_host, site_url); |
} |
bool ChromeContentBrowserClient::MayReuseHost( |
@@ -1191,10 +1018,6 @@ bool ChromeContentBrowserClient::MayReuseHost( |
return true; |
} |
-// This function is trying to limit the amount of processes used by extensions |
-// with background pages. It uses a globally set percentage of processes to |
-// run such extensions and if the limit is exceeded, it returns true, to |
-// indicate to the content module to group extensions together. |
bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost( |
content::BrowserContext* browser_context, const GURL& url) { |
// It has to be a valid URL for us to check for an extension. |
@@ -1202,45 +1025,9 @@ bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost( |
return false; |
Profile* profile = Profile::FromBrowserContext(browser_context); |
- ExtensionService* service = !profile ? NULL : |
- extensions::ExtensionSystem::Get(profile)->extension_service(); |
- if (!service) |
- return false; |
- |
- // We have to have a valid extension with background page to proceed. |
- const Extension* extension = |
- service->extensions()->GetExtensionOrAppByURL(url); |
- if (!extension) |
- return false; |
- if (!extensions::BackgroundInfo::HasBackgroundPage(extension)) |
- return false; |
- |
- std::set<int> process_ids; |
- size_t max_process_count = |
- content::RenderProcessHost::GetMaxRendererProcessCount(); |
- |
- // Go through all profiles to ensure we have total count of extension |
- // processes containing background pages, otherwise one profile can |
- // starve the other. |
- std::vector<Profile*> profiles = g_browser_process->profile_manager()-> |
- GetLoadedProfiles(); |
- for (size_t i = 0; i < profiles.size(); ++i) { |
- extensions::ProcessManager* epm = |
- extensions::ExtensionSystem::Get(profiles[i])->process_manager(); |
- for (extensions::ProcessManager::const_iterator iter = |
- epm->background_hosts().begin(); |
- iter != epm->background_hosts().end(); ++iter) { |
- const extensions::ExtensionHost* host = *iter; |
- process_ids.insert(host->render_process_host()->GetID()); |
- } |
- } |
- |
- if (process_ids.size() > |
- (max_process_count * chrome::kMaxShareOfExtensionProcesses)) { |
- return true; |
- } |
- |
- return false; |
+ return ChromeContentBrowserClientExtensionsPart:: |
+ ShouldTryToUseExistingProcessHost( |
+ profile, url); |
} |
void ChromeContentBrowserClient::SiteInstanceGotProcess( |
@@ -1271,12 +1058,7 @@ void ChromeContentBrowserClient::SiteInstanceGotProcess( |
ChromeSigninClientFactory::GetForProfile(profile); |
if (signin_client) |
signin_client->SetSigninProcess(site_instance->GetProcess()->GetID()); |
- BrowserThread::PostTask( |
- BrowserThread::IO, |
- FROM_HERE, |
- base::Bind(&InfoMap::SetSigninProcess, |
- extensions::ExtensionSystem::Get(profile)->info_map(), |
- site_instance->GetProcess()->GetID())); |
+ ChromeContentBrowserClientExtensionsPart::SetSigninProcess(site_instance); |
} |
#endif |
@@ -1311,61 +1093,17 @@ bool ChromeContentBrowserClient::ShouldSwapBrowsingInstancesForNavigation( |
SiteInstance* site_instance, |
const GURL& current_url, |
const GURL& new_url) { |
- // If we don't have an ExtensionService, then rely on the SiteInstance logic |
- // in RenderFrameHostManager to decide when to swap. |
- Profile* profile = |
- Profile::FromBrowserContext(site_instance->GetBrowserContext()); |
- ExtensionService* service = |
- extensions::ExtensionSystem::Get(profile)->extension_service(); |
- if (!service) |
- return false; |
- |
- // We must use a new BrowsingInstance (forcing a process swap and disabling |
- // scripting by existing tabs) if one of the URLs is an extension and the |
- // other is not the exact same extension. |
- // |
- // We ignore hosted apps here so that other tabs in their BrowsingInstance can |
- // use postMessage with them. (The exception is the Chrome Web Store, which |
- // is a hosted app that requires its own BrowsingInstance.) Navigations |
- // to/from a hosted app will still trigger a SiteInstance swap in |
- // RenderFrameHostManager. |
- const Extension* current_extension = |
- service->extensions()->GetExtensionOrAppByURL(current_url); |
- if (current_extension && |
- current_extension->is_hosted_app() && |
- current_extension->id() != extension_misc::kWebStoreAppId) |
- current_extension = NULL; |
- |
- const Extension* new_extension = |
- service->extensions()->GetExtensionOrAppByURL(new_url); |
- if (new_extension && |
- new_extension->is_hosted_app() && |
- new_extension->id() != extension_misc::kWebStoreAppId) |
- new_extension = NULL; |
- |
- // First do a process check. We should force a BrowsingInstance swap if the |
- // current process doesn't know about new_extension, even if current_extension |
- // is somehow the same as new_extension. |
- extensions::ProcessMap* process_map = extensions::ProcessMap::Get(profile); |
- if (new_extension && |
- site_instance->HasProcess() && |
- !process_map->Contains( |
- new_extension->id(), site_instance->GetProcess()->GetID())) |
- return true; |
- |
- // Otherwise, swap BrowsingInstances if current_extension and new_extension |
- // differ. |
- return current_extension != new_extension; |
+ return ChromeContentBrowserClientExtensionsPart:: |
+ ShouldSwapBrowsingInstancesForNavigation( |
+ site_instance, current_url, new_url); |
} |
bool ChromeContentBrowserClient::ShouldSwapProcessesForRedirect( |
content::ResourceContext* resource_context, const GURL& current_url, |
const GURL& new_url) { |
#if defined(ENABLE_EXTENSIONS) |
- ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context); |
- return extensions::CrossesExtensionProcessBoundary( |
- io_data->GetExtensionInfoMap()->extensions(), |
- current_url, new_url, false); |
+ return ChromeContentBrowserClientExtensionsPart:: |
+ ShouldSwapProcessesForRedirect(resource_context, current_url, new_url); |
#else |
return false; |
#endif |
@@ -2315,12 +2053,8 @@ std::string ChromeContentBrowserClient::GetWorkerProcessTitle( |
const GURL& url, content::ResourceContext* context) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
#if defined(ENABLE_EXTENSIONS) |
- // Check if it's an extension-created worker, in which case we want to use |
- // the name of the extension. |
- ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); |
- const Extension* extension = |
- io_data->GetExtensionInfoMap()->extensions().GetByID(url.host()); |
- return extension ? extension->name() : std::string(); |
+ return ChromeContentBrowserClientExtensionsPart::GetWorkerProcessTitle( |
+ url, context); |
#else |
return std::string(); |
#endif |