shell_content_browser_client.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Copyright 2014 The Chromium Authors. All rights reserved. 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Use of this source code is governed by a BSD-style license that can be 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// found in the LICENSE file. 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner#include "extensions/shell/browser/shell_content_browser_client.h" 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "base/command_line.h" 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "content/public/browser/browser_thread.h" 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "content/public/browser/render_process_host.h" 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "content/public/browser/site_instance.h" 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "content/public/common/content_switches.h" 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "content/public/common/url_constants.h" 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "content/shell/browser/shell_browser_context.h" 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "extensions/browser/extension_message_filter.h" 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "extensions/browser/extension_protocols.h" 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "extensions/browser/extension_registry.h" 17af8fa25c0d4e0540952a50bbd06dc1558954ccd9Ted Kremenek#include "extensions/browser/info_map.h" 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "extensions/browser/process_map.h" 199c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek#include "extensions/common/constants.h" 20eb50ed88c2aa040fac08bf2a50bde4dd3da6eb19Chris Lattner#include "extensions/common/extension.h" 215d75de0f821023f4ed4815825bf3aea8a0b5e40dChris Lattner#include "extensions/common/switches.h" 226137dc99ef0c2b14050631367057758b0d596cb3Ted Kremenek#include "extensions/shell/browser/shell_browser_context.h" 231b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner#include "extensions/shell/browser/shell_browser_main_parts.h" 24d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer#include "extensions/shell/browser/shell_extension_system.h" 25c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "url/gurl.h" 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 27cc1a875f94630e58d24a55577ffbf0e89b7da8c7Chris Lattnerusing content::BrowserThread; 284f32786ac45210143654390177105eb749b614e9Ted Kremenek 290827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidisnamespace extensions { 30caaa7df2c78bbd40197823034c0275f3dcbd63e7Ted Kremeneknamespace { 31f4d5eb4866a27d497f0bb75b12c2ffd48ad4d9c0Benjamin Kramer 325b3284a9275a27f5c4410e25eb8933be540601d6Argyrios KyrtzidisShellContentBrowserClient* g_instance = NULL; 330ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek 342e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor} // namespace 355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 368fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin KramerShellContentBrowserClient::ShellContentBrowserClient( 378fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer ShellBrowserMainDelegate* browser_main_delegate) 388fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer : browser_main_parts_(NULL), browser_main_delegate_(browser_main_delegate) { 398fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer DCHECK(!g_instance); 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer g_instance = this; 411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4388a35862fbe473f2a4f0c19f24dbe536937e1dc6Douglas GregorShellContentBrowserClient::~ShellContentBrowserClient() { 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer g_instance = NULL; 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// static 485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerShellContentBrowserClient* ShellContentBrowserClient::Get() { 492e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor return g_instance; 505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencercontent::BrowserContext* ShellContentBrowserClient::GetBrowserContext() { 53f44e854ed1e3aa86d2ed6d615ccd109d50ddcff9Douglas Gregor return browser_main_parts_->browser_context(); 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5594dc8f640ebea52241412512ed48601626edbc58Douglas Gregor 566aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregorcontent::BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts( 57ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie const content::MainFunctionParams& parameters) { 58e5956bd2730c051835f9acd9e957c5d79f99e7c3Chris Lattner browser_main_parts_ = 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer new ShellBrowserMainParts(parameters, browser_main_delegate_); 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return browser_main_parts_; 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 63c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmithvoid ShellContentBrowserClient::RenderProcessWillLaunch( 64d7a3e2c5f61cd4893f95b69a424fe4def3aa0f69Benjamin Kramer content::RenderProcessHost* host) { 654e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie int render_process_id = host->GetID(); 66998b3d3e8528ebd9d2c5d78d3a82edd90a8953a4Douglas Gregor host->AddFilter(new ExtensionMessageFilter( 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer render_process_id, browser_main_parts_->browser_context())); 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool ShellContentBrowserClient::ShouldUseProcessPerSite( 716aa52ec6b969faabf3764baf79d89810b8249a7eDouglas Gregor content::BrowserContext* browser_context, 721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const GURL& effective_url) { 7388a35862fbe473f2a4f0c19f24dbe536937e1dc6Douglas Gregor // This ensures that all render views created for a single app will use the 7488a35862fbe473f2a4f0c19f24dbe536937e1dc6Douglas Gregor // same render process (see content::SiteInstance::GetProcess). Otherwise the 75a5d10c4df435964600e104ebef6a96b106e416b7Kovarththanan Rajaratnam // default behavior of ContentBrowserClient will lead to separate render 76ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie // processes for the background page and each app window view. 776137dc99ef0c2b14050631367057758b0d596cb3Ted Kremenek return true; 786137dc99ef0c2b14050631367057758b0d596cb3Ted Kremenek} 796f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith 801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnet::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext( 810ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek content::BrowserContext* content_browser_context, 820ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek content::ProtocolHandlerMap* protocol_handlers, 830ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek content::URLRequestInterceptorScopedVector request_interceptors) { 841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Handle only chrome-extension:// requests. app_shell does not support 855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // chrome-extension-resource:// requests (it does not store shared extension 865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // data in its installation directory). 875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer InfoMap* extension_info_map = 885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer browser_main_parts_->extension_system()->info_map(); 895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer (*protocol_handlers)[kExtensionScheme] = 905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer linked_ptr<net::URLRequestJobFactory::ProtocolHandler>( 91c1f9d828c733ec1eba06d01070735d1f36fda733Chris Lattner CreateExtensionProtocolHandler(false /* is_incognito */, 921ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall extension_info_map)); 931ef8a2e7675f3d8b6e8d9963b00378086e1dcdc7John McCall // Let content::ShellBrowserContext handle the rest of the setup. 94148772a841cae6f32db16d890e788b92a763bb3fChris Lattner return browser_main_parts_->browser_context()->CreateRequestContext( 95c1b5fa41f09512c74030b9a2a0d1564535e22a76Peter Collingbourne protocol_handlers, request_interceptors.Pass()); 96148772a841cae6f32db16d890e788b92a763bb3fChris Lattner} 97cae5095c116c29a4e52c91fa0ad88df09dd2b45fAnders Carlsson 9892bd8c70a6837b647a6c55964f8d0a50bf561dbcJohn Thompsonbool ShellContentBrowserClient::IsHandledURL(const GURL& url) { 9992bd8c70a6837b647a6c55964f8d0a50bf561dbcJohn Thompson if (!url.is_valid()) 100d768150ef57f617c8d9fef48f3c92e8f21698024Ted Kremenek return false; 1011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Keep in sync with ProtocolHandlers added in CreateRequestContext() and in 1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // content::ShellURLRequestContextGetter::GetURLRequestContext(). 103c1f9d828c733ec1eba06d01070735d1f36fda733Chris Lattner static const char* const kProtocolList[] = { 1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer url::kBlobScheme, 1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer content::kChromeDevToolsScheme, 1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer content::kChromeUIScheme, 1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer url::kDataScheme, 1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer url::kFileScheme, 1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer url::kFileSystemScheme, 1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer kExtensionScheme, 1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer kExtensionResourceScheme, 1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer }; 113f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman for (size_t i = 0; i < arraysize(kProtocolList); ++i) { 114ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie if (url.scheme() == kProtocolList[i]) 1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return false; 1185814e657c9ad9ef6049a2a4af0d2aad248a8a15cDaniel Dunbar} 1195814e657c9ad9ef6049a2a4af0d2aad248a8a15cDaniel Dunbar 1205814e657c9ad9ef6049a2a4af0d2aad248a8a15cDaniel Dunbarvoid ShellContentBrowserClient::SiteInstanceGotProcess( 1211d9c54df56391ac4740db27d551782e81189cb51Chris Lattner content::SiteInstance* site_instance) { 1221d9c54df56391ac4740db27d551782e81189cb51Chris Lattner // If this isn't an extension renderer there's nothing to do. 1231d9c54df56391ac4740db27d551782e81189cb51Chris Lattner const Extension* extension = GetExtension(site_instance); 1248c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie if (!extension) 1258c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie return; 1268c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie 1278c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie ProcessMap::Get(browser_main_parts_->browser_context()) 1288c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie ->Insert(extension->id(), 1298c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie site_instance->GetProcess()->GetID(), 1308c0b3787e7ccc7978b42dfbb84da2b802c743a5dDavid Blaikie site_instance->GetId()); 13188a35862fbe473f2a4f0c19f24dbe536937e1dc6Douglas Gregor 13288a35862fbe473f2a4f0c19f24dbe536937e1dc6Douglas Gregor BrowserThread::PostTask( 133a5d10c4df435964600e104ebef6a96b106e416b7Kovarththanan Rajaratnam BrowserThread::IO, 13414e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis FROM_HERE, 13514e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis base::Bind(&InfoMap::RegisterExtensionProcess, 13614e645557ae91c6770d62beb00a1c522e0bfd5d6Argyrios Kyrtzidis browser_main_parts_->extension_system()->info_map(), 1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer extension->id(), 1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer site_instance->GetProcess()->GetID(), 139c3222091e1ffa35d0264ca6b680a88c9dc84ede2Daniel Dunbar site_instance->GetId())); 1401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 14168d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff 14268d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroffvoid ShellContentBrowserClient::SiteInstanceDeleting( 1439e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth content::SiteInstance* site_instance) { 14468d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff // If this isn't an extension renderer there's nothing to do. 1451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const Extension* extension = GetExtension(site_instance); 14668d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff if (!extension) 147083abdf67f157e9d2ab5a8c9d5e71240479d3c99Sebastian Redl return; 14829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 1492e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor ProcessMap::Get(browser_main_parts_->browser_context()) 1501b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner ->Remove(extension->id(), 1511b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner site_instance->GetProcess()->GetID(), 1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump site_instance->GetId()); 1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer BrowserThread::PostTask( 1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer BrowserThread::IO, 1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump FROM_HERE, 1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump base::Bind(&InfoMap::UnregisterExtensionProcess, 1582e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor browser_main_parts_->extension_system()->info_map(), 1592e22253e03e175144aeb9d13350a12fd83f858beDouglas Gregor extension->id(), 1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump site_instance->GetProcess()->GetID(), 161e55329d6834647ba0e06f8a319e5d84c77310035Axel Naumann site_instance->GetId())); 162e55329d6834647ba0e06f8a319e5d84c77310035Axel Naumann} 163e55329d6834647ba0e06f8a319e5d84c77310035Axel Naumann 164e55329d6834647ba0e06f8a319e5d84c77310035Axel Naumannvoid ShellContentBrowserClient::AppendExtraCommandLineSwitches( 165f44e854ed1e3aa86d2ed6d615ccd109d50ddcff9Douglas Gregor CommandLine* command_line, 166f44e854ed1e3aa86d2ed6d615ccd109d50ddcff9Douglas Gregor int child_process_id) { 167ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie std::string process_type = 1682968442603b029949246467253eeac8139a5b6d8Douglas Gregor command_line->GetSwitchValueASCII(::switches::kProcessType); 1692968442603b029949246467253eeac8139a5b6d8Douglas Gregor if (process_type == ::switches::kRendererProcess) { 1702968442603b029949246467253eeac8139a5b6d8Douglas Gregor // TODO(jamescook): Should we check here if the process is in the extension 1717d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis // service process map, or can we assume all renderers are extension 1727d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis // renderers? 1737d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis command_line->AppendSwitch(switches::kExtensionProcess); 1747d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis } 1757d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis} 1767d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis 1777d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidisvoid ShellContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem( 1787d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis std::vector<std::string>* additional_allowed_schemes) { 1797d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis ContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem( 1807d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis additional_allowed_schemes); 1817d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis additional_allowed_schemes->push_back(kExtensionScheme); 1827d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis} 183c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregor 184c13a34b690d2dc2a03c2fea75a0a1438636c19ceDouglas Gregorconst Extension* ShellContentBrowserClient::GetExtension( 185b8db7cd9ac05c522855631670ec2e97255384f5aDouglas Gregor content::SiteInstance* site_instance) { 1868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ExtensionRegistry* registry = 187b514c792821a8f053027d88444e13bfaa8efef76Douglas Gregor ExtensionRegistry::Get(site_instance->GetBrowserContext()); 188b514c792821a8f053027d88444e13bfaa8efef76Douglas Gregor return registry->enabled_extensions().GetExtensionOrAppByURL( 189b514c792821a8f053027d88444e13bfaa8efef76Douglas Gregor site_instance->GetSiteURL()); 190b514c792821a8f053027d88444e13bfaa8efef76Douglas Gregor} 191b514c792821a8f053027d88444e13bfaa8efef76Douglas Gregor 192b514c792821a8f053027d88444e13bfaa8efef76Douglas Gregor} // namespace extensions 193b514c792821a8f053027d88444e13bfaa8efef76Douglas Gregor