15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/extensions/chrome_content_browser_client_extensions_part.h"
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <set>
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/command_line.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/browser_process.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/extensions/browser_permissions_policy_delegate.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/extensions/extension_web_ui.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/extensions/extension_webkit_preferences.h"
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/profiles/profile_io_data.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/renderer_host/chrome_extension_message_filter.h"
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/common/chrome_constants.h"
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/common/extensions/extension_process_policy.h"
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/browser_url_handler.h"
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/render_process_host.h"
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/render_view_host.h"
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/site_instance.h"
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/web_contents.h"
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/common/content_switches.h"
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/web_request_api.h"
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/web_request_api_helpers.h"
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_host.h"
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/browser/extension_message_filter.h"
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_registry.h"
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_system.h"
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/info_map.h"
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/view_type_utils.h"
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/constants.h"
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h"
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/manifest_handlers/web_accessible_resources_info.h"
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/switches.h"
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using content::BrowserThread;
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using content::BrowserURLHandler;
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using content::RenderViewHost;
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using content::SiteInstance;
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using content::WebContents;
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using content::WebPreferences;
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace extensions {
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Used by the GetPrivilegeRequiredByUrl() and GetProcessPrivilege() functions
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// below.  Extension, and isolated apps require different privileges to be
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// granted to their RenderProcessHosts.  This classification allows us to make
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// sure URLs are served by hosts with the right set of privileges.
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)enum RenderProcessHostPrivilege {
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PRIV_NORMAL,
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PRIV_HOSTED,
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PRIV_ISOLATED,
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PRIV_EXTENSION,
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)RenderProcessHostPrivilege GetPrivilegeRequiredByUrl(
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& url,
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ExtensionService* service) {
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Default to a normal renderer cause it is lower privileged. This should only
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // occur if the URL on a site instance is either malformed, or uninitialized.
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If it is malformed, then there is no need for better privileges anyways.
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If it is uninitialized, but eventually settles on being an a scheme other
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // than normal webrenderer, the navigation logic will correct us out of band
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // anyways.
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!url.is_valid())
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return PRIV_NORMAL;
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!url.SchemeIs(kExtensionScheme))
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return PRIV_NORMAL;
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const Extension* extension = service->extensions()->GetByID(url.host());
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (extension && AppIsolationInfo::HasIsolatedStorage(extension))
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return PRIV_ISOLATED;
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (extension && extension->is_hosted_app())
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return PRIV_HOSTED;
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return PRIV_EXTENSION;
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)RenderProcessHostPrivilege GetProcessPrivilege(
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::RenderProcessHost* process_host,
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ProcessMap* process_map,
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ExtensionService* service) {
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::set<std::string> extension_ids =
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      process_map->GetExtensionsInProcess(process_host->GetID());
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (extension_ids.empty())
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return PRIV_NORMAL;
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (std::set<std::string>::iterator iter = extension_ids.begin();
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       iter != extension_ids.end(); ++iter) {
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const Extension* extension = service->GetExtensionById(*iter, false);
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (extension && AppIsolationInfo::HasIsolatedStorage(extension))
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return PRIV_ISOLATED;
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (extension && extension->is_hosted_app())
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return PRIV_HOSTED;
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return PRIV_EXTENSION;
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ChromeContentBrowserClientExtensionsPart::
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ChromeContentBrowserClientExtensionsPart() {
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  permissions_policy_delegate_.reset(new BrowserPermissionsPolicyDelegate());
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ChromeContentBrowserClientExtensionsPart::
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ~ChromeContentBrowserClientExtensionsPart() {
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)GURL ChromeContentBrowserClientExtensionsPart::GetEffectiveURL(
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Profile* profile, const GURL& url) {
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If the input |url| is part of an installed app, the effective URL is an
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // extension URL with the ID of that extension as the host. This has the
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // effect of grouping apps together in a common SiteInstance.
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* extension_service =
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ExtensionSystem::Get(profile)->extension_service();
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!extension_service)
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return url;
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const Extension* extension =
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extension_service->extensions()->GetHostedAppByURL(url);
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!extension)
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return url;
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Bookmark apps do not use the hosted app process model, and should be
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // treated as normal URLs.
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (extension->from_bookmark())
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return url;
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If the URL is part of an extension's web extent, convert it to an
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // extension URL.
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return extension->GetResourceURL(url.path());
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ChromeContentBrowserClientExtensionsPart::ShouldUseProcessPerSite(
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Profile* profile, const GURL& effective_url) {
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!effective_url.SchemeIs(kExtensionScheme))
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* extension_service =
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ExtensionSystem::Get(profile)->extension_service();
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!extension_service)
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const Extension* extension =
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extension_service->extensions()->GetExtensionOrAppByURL(effective_url);
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!extension)
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If the URL is part of a hosted app that does not have the background
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // permission, or that does not allow JavaScript access to the background
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // page, we want to give each instance its own process to improve
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // responsiveness.
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (extension->GetType() == Manifest::TYPE_HOSTED_APP) {
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!extension->permissions_data()->HasAPIPermission(
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            APIPermission::kBackground) ||
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        !BackgroundInfo::AllowJSAccess(extension)) {
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Hosted apps that have script access to their background page must use
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // process per site, since all instances can make synchronous calls to the
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // background window.  Other extensions should use process per site as well.
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ChromeContentBrowserClientExtensionsPart::CanCommitURL(
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::RenderProcessHost* process_host, const GURL& url) {
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // We need to let most extension URLs commit in any process, since this can
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // be allowed due to web_accessible_resources.  Most hosted app URLs may also
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // load in any process (e.g., in an iframe).  However, the Chrome Web Store
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // cannot be loaded in iframes and should never be requested outside its
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // process.
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Profile* profile =
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Profile::FromBrowserContext(process_host->GetBrowserContext());
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* service =
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ExtensionSystem::Get(profile)->extension_service();
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!service)
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const Extension* new_extension =
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      service->extensions()->GetExtensionOrAppByURL(url);
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (new_extension &&
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new_extension->is_hosted_app() &&
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new_extension->id() == extensions::kWebStoreAppId &&
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      !ProcessMap::Get(profile)->Contains(
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          new_extension->id(), process_host->GetID())) {
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ChromeContentBrowserClientExtensionsPart::IsSuitableHost(
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Profile* profile,
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::RenderProcessHost* process_host,
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& site_url) {
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(profile);
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* service =
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ExtensionSystem::Get(profile)->extension_service();
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ProcessMap* process_map = ProcessMap::Get(profile);
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // These may be NULL during tests. In that case, just assume any site can
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // share any host.
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!service || !process_map)
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Otherwise, just make sure the process privilege matches the privilege
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // required by the site.
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RenderProcessHostPrivilege privilege_required =
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetPrivilegeRequiredByUrl(site_url, service);
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return GetProcessPrivilege(process_host, process_map, service) ==
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      privilege_required;
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ChromeContentBrowserClientExtensionsPart::ShouldTryToUseExistingProcessHost(
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Profile* profile, const GURL& url) {
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // This function is trying to limit the amount of processes used by extensions
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // with background pages. It uses a globally set percentage of processes to
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // run such extensions and if the limit is exceeded, it returns true, to
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // indicate to the content module to group extensions together.
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* service = profile ?
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ExtensionSystem::Get(profile)->extension_service() : NULL;
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!service)
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // We have to have a valid extension with background page to proceed.
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const Extension* extension =
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      service->extensions()->GetExtensionOrAppByURL(url);
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!extension)
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!BackgroundInfo::HasBackgroundPage(extension))
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::set<int> process_ids;
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  size_t max_process_count =
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      content::RenderProcessHost::GetMaxRendererProcessCount();
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Go through all profiles to ensure we have total count of extension
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // processes containing background pages, otherwise one profile can
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // starve the other.
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<Profile*> profiles = g_browser_process->profile_manager()->
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetLoadedProfiles();
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < profiles.size(); ++i) {
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ProcessManager* epm = ExtensionSystem::Get(profiles[i])->process_manager();
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for (ProcessManager::const_iterator iter = epm->background_hosts().begin();
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         iter != epm->background_hosts().end(); ++iter) {
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const ExtensionHost* host = *iter;
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      process_ids.insert(host->render_process_host()->GetID());
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return (process_ids.size() >
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          (max_process_count * chrome::kMaxShareOfExtensionProcesses));
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ChromeContentBrowserClientExtensionsPart::
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ShouldSwapBrowsingInstancesForNavigation(SiteInstance* site_instance,
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             const GURL& current_url,
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                             const GURL& new_url) {
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If we don't have an ExtensionService, then rely on the SiteInstance logic
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // in RenderFrameHostManager to decide when to swap.
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Profile* profile =
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Profile::FromBrowserContext(site_instance->GetBrowserContext());
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* service =
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ExtensionSystem::Get(profile)->extension_service();
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!service)
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // We must use a new BrowsingInstance (forcing a process swap and disabling
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // scripting by existing tabs) if one of the URLs is an extension and the
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // other is not the exact same extension.
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  //
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // We ignore hosted apps here so that other tabs in their BrowsingInstance can
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // use postMessage with them.  (The exception is the Chrome Web Store, which
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // is a hosted app that requires its own BrowsingInstance.)  Navigations
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // to/from a hosted app will still trigger a SiteInstance swap in
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // RenderFrameHostManager.
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const Extension* current_extension =
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      service->extensions()->GetExtensionOrAppByURL(current_url);
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (current_extension &&
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      current_extension->is_hosted_app() &&
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      current_extension->id() != extensions::kWebStoreAppId)
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    current_extension = NULL;
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const Extension* new_extension =
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      service->extensions()->GetExtensionOrAppByURL(new_url);
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (new_extension &&
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new_extension->is_hosted_app() &&
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new_extension->id() != extensions::kWebStoreAppId)
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    new_extension = NULL;
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // First do a process check.  We should force a BrowsingInstance swap if the
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // current process doesn't know about new_extension, even if current_extension
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // is somehow the same as new_extension.
3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ProcessMap* process_map = ProcessMap::Get(profile);
3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (new_extension &&
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      site_instance->HasProcess() &&
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      !process_map->Contains(
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          new_extension->id(), site_instance->GetProcess()->GetID()))
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Otherwise, swap BrowsingInstances if current_extension and new_extension
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // differ.
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return current_extension != new_extension;
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ChromeContentBrowserClientExtensionsPart::ShouldSwapProcessesForRedirect(
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::ResourceContext* resource_context,
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& current_url,
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& new_url) {
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return CrossesExtensionProcessBoundary(
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      io_data->GetExtensionInfoMap()->extensions(),
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      current_url, new_url, false);
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ChromeContentBrowserClientExtensionsPart::ShouldAllowOpenURL(
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::SiteInstance* site_instance,
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& from_url,
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& to_url,
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool* result) {
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(result);
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Do not allow pages from the web or other extensions navigate to
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // non-web-accessible extension resources.
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (to_url.SchemeIs(kExtensionScheme) &&
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      (from_url.SchemeIsHTTPOrHTTPS() || from_url.SchemeIs(kExtensionScheme))) {
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Profile* profile = Profile::FromBrowserContext(
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        site_instance->GetProcess()->GetBrowserContext());
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ExtensionService* service =
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ExtensionSystem::Get(profile)->extension_service();
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!service) {
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *result = true;
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return true;
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const Extension* extension =
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        service->extensions()->GetExtensionOrAppByURL(to_url);
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!extension) {
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *result = true;
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return true;
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const Extension* from_extension =
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        service->extensions()->GetExtensionOrAppByURL(
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            site_instance->GetSiteURL());
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (from_extension && from_extension->id() == extension->id()) {
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *result = true;
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return true;
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!WebAccessibleResourcesInfo::IsResourceWebAccessible(
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            extension, to_url.path())) {
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *result = false;
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return true;
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return false;
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChromeContentBrowserClientExtensionsPart::SetSigninProcess(
3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::SiteInstance* site_instance) {
3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Profile* profile =
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Profile::FromBrowserContext(site_instance->GetBrowserContext());
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(profile);
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BrowserThread::PostTask(
3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BrowserThread::IO,
3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      FROM_HERE,
3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&InfoMap::SetSigninProcess,
3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 ExtensionSystem::Get(profile)->info_map(),
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 site_instance->GetProcess()->GetID()));
3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChromeContentBrowserClientExtensionsPart::RenderProcessWillLaunch(
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::RenderProcessHost* host) {
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int id = host->GetID();
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  host->AddFilter(new ChromeExtensionMessageFilter(id, profile));
4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  host->AddFilter(new ExtensionMessageFilter(id, profile));
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  extension_web_request_api_helpers::SendExtensionWebRequestStatusToHost(host);
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChromeContentBrowserClientExtensionsPart::SiteInstanceGotProcess(
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SiteInstance* site_instance) {
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Profile* profile = Profile::FromBrowserContext(
4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      site_instance->GetProcess()->GetBrowserContext());
4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* service =
4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ExtensionSystem::Get(profile)->extension_service();
4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!service)
4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const Extension* extension = service->extensions()->GetExtensionOrAppByURL(
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      site_instance->GetSiteURL());
4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!extension)
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ProcessMap::Get(profile)->Insert(extension->id(),
4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   site_instance->GetProcess()->GetID(),
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   site_instance->GetId());
4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BrowserThread::PostTask(BrowserThread::IO,
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          FROM_HERE,
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          base::Bind(&InfoMap::RegisterExtensionProcess,
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     ExtensionSystem::Get(profile)->info_map(),
4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     extension->id(),
4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     site_instance->GetProcess()->GetID(),
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     site_instance->GetId()));
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChromeContentBrowserClientExtensionsPart::SiteInstanceDeleting(
4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SiteInstance* site_instance) {
4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Profile* profile =
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Profile::FromBrowserContext(site_instance->GetBrowserContext());
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* service =
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ExtensionSystem::Get(profile)->extension_service();
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!service)
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const Extension* extension = service->extensions()->GetExtensionOrAppByURL(
4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      site_instance->GetSiteURL());
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!extension)
4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ProcessMap::Get(profile)->Remove(extension->id(),
4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   site_instance->GetProcess()->GetID(),
4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   site_instance->GetId());
4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BrowserThread::PostTask(BrowserThread::IO,
4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          FROM_HERE,
4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          base::Bind(&InfoMap::UnregisterExtensionProcess,
4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     ExtensionSystem::Get(profile)->info_map(),
4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     extension->id(),
4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     site_instance->GetProcess()->GetID(),
4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     site_instance->GetId()));
4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChromeContentBrowserClientExtensionsPart::OverrideWebkitPrefs(
4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RenderViewHost* rvh,
4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& url,
4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WebPreferences* web_prefs) {
4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Profile* profile =
4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Profile::FromBrowserContext(rvh->GetProcess()->GetBrowserContext());
4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ExtensionService* service =
4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ExtensionSystem::Get(profile)->extension_service();
4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!service)
4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Note: it's not possible for kExtensionsScheme to change during the lifetime
4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // of the process.
4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  //
4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Ensure that we are only granting extension preferences to URLs with
4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // the correct scheme. Without this check, chrome-guest:// schemes used by
4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // webview tags as well as hosts that happen to match the id of an
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // installed extension would get the wrong preferences.
4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const GURL& site_url = rvh->GetSiteInstance()->GetSiteURL();
4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!site_url.SchemeIs(kExtensionScheme))
4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ViewType view_type = GetViewType(web_contents);
4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const Extension* extension = service->extensions()->GetByID(site_url.host());
4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  extension_webkit_preferences::SetPreferences(extension, view_type, web_prefs);
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChromeContentBrowserClientExtensionsPart::BrowserURLHandlerCreated(
4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BrowserURLHandler* handler) {
4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  handler->AddHandlerPair(&ExtensionWebUI::HandleChromeURLOverride,
4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          BrowserURLHandler::null_handler());
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  handler->AddHandlerPair(BrowserURLHandler::null_handler(),
4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          &ExtensionWebUI::HandleChromeURLOverrideReverse);
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChromeContentBrowserClientExtensionsPart::
4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GetAdditionalAllowedSchemesForFileSystem(
4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        std::vector<std::string>* additional_allowed_schemes) {
4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  additional_allowed_schemes->push_back(kExtensionScheme);
5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChromeContentBrowserClientExtensionsPart::GetURLRequestAutoMountHandlers(
50303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::vector<storage::URLRequestAutoMountHandler>* handlers) {
5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  handlers->push_back(
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(MediaFileSystemBackend::AttemptAutoMountForURLRequest));
5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChromeContentBrowserClientExtensionsPart::GetAdditionalFileSystemBackends(
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::BrowserContext* browser_context,
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::FilePath& storage_partition_path,
51103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ScopedVector<storage::FileSystemBackend>* additional_backends) {
5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  additional_backends->push_back(new MediaFileSystemBackend(
5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      storage_partition_path,
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      pool->GetSequencedTaskRunner(
5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                pool->GetNamedSequenceToken(
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    MediaFileSystemBackend::kMediaTaskRunnerName)).get()));
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  additional_backends->push_back(new sync_file_system::SyncFileSystemBackend(
5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Profile::FromBrowserContext(browser_context)));
5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChromeContentBrowserClientExtensionsPart::
5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    AppendExtraRendererCommandLineSwitches(base::CommandLine* command_line,
5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                           content::RenderProcessHost* process,
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                           Profile* profile) {
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!process)
5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(profile);
5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (ProcessMap::Get(profile)->Contains(process->GetID())) {
5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    command_line->AppendSwitch(switches::kExtensionProcess);
5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_WEBRTC)
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    command_line->AppendSwitch(::switches::kEnableWebRtcHWH264Encoding);
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace extensions
539