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