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 |