| 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
|
|
|