shell_content_browser_client.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "extensions/shell/browser/shell_content_browser_client.h" 6 7#include "base/command_line.h" 8#include "content/public/browser/browser_thread.h" 9#include "content/public/browser/render_process_host.h" 10#include "content/public/browser/site_instance.h" 11#include "content/public/common/content_switches.h" 12#include "content/public/common/url_constants.h" 13#include "content/shell/browser/shell_browser_context.h" 14#include "extensions/browser/extension_message_filter.h" 15#include "extensions/browser/extension_protocols.h" 16#include "extensions/browser/extension_registry.h" 17#include "extensions/browser/info_map.h" 18#include "extensions/browser/process_map.h" 19#include "extensions/common/constants.h" 20#include "extensions/common/extension.h" 21#include "extensions/common/switches.h" 22#include "extensions/shell/browser/shell_browser_context.h" 23#include "extensions/shell/browser/shell_browser_main_parts.h" 24#include "extensions/shell/browser/shell_extension_system.h" 25#include "url/gurl.h" 26 27using content::BrowserThread; 28 29namespace extensions { 30namespace { 31 32ShellContentBrowserClient* g_instance = NULL; 33 34} // namespace 35 36ShellContentBrowserClient::ShellContentBrowserClient( 37 ShellBrowserMainDelegate* browser_main_delegate) 38 : browser_main_parts_(NULL), browser_main_delegate_(browser_main_delegate) { 39 DCHECK(!g_instance); 40 g_instance = this; 41} 42 43ShellContentBrowserClient::~ShellContentBrowserClient() { 44 g_instance = NULL; 45} 46 47// static 48ShellContentBrowserClient* ShellContentBrowserClient::Get() { 49 return g_instance; 50} 51 52content::BrowserContext* ShellContentBrowserClient::GetBrowserContext() { 53 return browser_main_parts_->browser_context(); 54} 55 56content::BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts( 57 const content::MainFunctionParams& parameters) { 58 browser_main_parts_ = 59 new ShellBrowserMainParts(parameters, browser_main_delegate_); 60 return browser_main_parts_; 61} 62 63void ShellContentBrowserClient::RenderProcessWillLaunch( 64 content::RenderProcessHost* host) { 65 int render_process_id = host->GetID(); 66 host->AddFilter(new ExtensionMessageFilter( 67 render_process_id, browser_main_parts_->browser_context())); 68} 69 70bool ShellContentBrowserClient::ShouldUseProcessPerSite( 71 content::BrowserContext* browser_context, 72 const GURL& effective_url) { 73 // This ensures that all render views created for a single app will use the 74 // same render process (see content::SiteInstance::GetProcess). Otherwise the 75 // default behavior of ContentBrowserClient will lead to separate render 76 // processes for the background page and each app window view. 77 return true; 78} 79 80net::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext( 81 content::BrowserContext* content_browser_context, 82 content::ProtocolHandlerMap* protocol_handlers, 83 content::URLRequestInterceptorScopedVector request_interceptors) { 84 // Handle only chrome-extension:// requests. app_shell does not support 85 // chrome-extension-resource:// requests (it does not store shared extension 86 // data in its installation directory). 87 InfoMap* extension_info_map = 88 browser_main_parts_->extension_system()->info_map(); 89 (*protocol_handlers)[kExtensionScheme] = 90 linked_ptr<net::URLRequestJobFactory::ProtocolHandler>( 91 CreateExtensionProtocolHandler(false /* is_incognito */, 92 extension_info_map)); 93 // Let content::ShellBrowserContext handle the rest of the setup. 94 return browser_main_parts_->browser_context()->CreateRequestContext( 95 protocol_handlers, request_interceptors.Pass()); 96} 97 98bool ShellContentBrowserClient::IsHandledURL(const GURL& url) { 99 if (!url.is_valid()) 100 return false; 101 // Keep in sync with ProtocolHandlers added in CreateRequestContext() and in 102 // content::ShellURLRequestContextGetter::GetURLRequestContext(). 103 static const char* const kProtocolList[] = { 104 url::kBlobScheme, 105 content::kChromeDevToolsScheme, 106 content::kChromeUIScheme, 107 url::kDataScheme, 108 url::kFileScheme, 109 url::kFileSystemScheme, 110 kExtensionScheme, 111 kExtensionResourceScheme, 112 }; 113 for (size_t i = 0; i < arraysize(kProtocolList); ++i) { 114 if (url.scheme() == kProtocolList[i]) 115 return true; 116 } 117 return false; 118} 119 120void ShellContentBrowserClient::SiteInstanceGotProcess( 121 content::SiteInstance* site_instance) { 122 // If this isn't an extension renderer there's nothing to do. 123 const Extension* extension = GetExtension(site_instance); 124 if (!extension) 125 return; 126 127 ProcessMap::Get(browser_main_parts_->browser_context()) 128 ->Insert(extension->id(), 129 site_instance->GetProcess()->GetID(), 130 site_instance->GetId()); 131 132 BrowserThread::PostTask( 133 BrowserThread::IO, 134 FROM_HERE, 135 base::Bind(&InfoMap::RegisterExtensionProcess, 136 browser_main_parts_->extension_system()->info_map(), 137 extension->id(), 138 site_instance->GetProcess()->GetID(), 139 site_instance->GetId())); 140} 141 142void ShellContentBrowserClient::SiteInstanceDeleting( 143 content::SiteInstance* site_instance) { 144 // If this isn't an extension renderer there's nothing to do. 145 const Extension* extension = GetExtension(site_instance); 146 if (!extension) 147 return; 148 149 ProcessMap::Get(browser_main_parts_->browser_context()) 150 ->Remove(extension->id(), 151 site_instance->GetProcess()->GetID(), 152 site_instance->GetId()); 153 154 BrowserThread::PostTask( 155 BrowserThread::IO, 156 FROM_HERE, 157 base::Bind(&InfoMap::UnregisterExtensionProcess, 158 browser_main_parts_->extension_system()->info_map(), 159 extension->id(), 160 site_instance->GetProcess()->GetID(), 161 site_instance->GetId())); 162} 163 164void ShellContentBrowserClient::AppendExtraCommandLineSwitches( 165 CommandLine* command_line, 166 int child_process_id) { 167 std::string process_type = 168 command_line->GetSwitchValueASCII(::switches::kProcessType); 169 if (process_type == ::switches::kRendererProcess) { 170 // TODO(jamescook): Should we check here if the process is in the extension 171 // service process map, or can we assume all renderers are extension 172 // renderers? 173 command_line->AppendSwitch(switches::kExtensionProcess); 174 } 175} 176 177void ShellContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem( 178 std::vector<std::string>* additional_allowed_schemes) { 179 ContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem( 180 additional_allowed_schemes); 181 additional_allowed_schemes->push_back(kExtensionScheme); 182} 183 184const Extension* ShellContentBrowserClient::GetExtension( 185 content::SiteInstance* site_instance) { 186 ExtensionRegistry* registry = 187 ExtensionRegistry::Get(site_instance->GetBrowserContext()); 188 return registry->enabled_extensions().GetExtensionOrAppByURL( 189 site_instance->GetSiteURL()); 190} 191 192} // namespace extensions 193