Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: extensions/browser/renderer_startup_helper.cc

Issue 2766263003: Extensions: Only load incognito-enabled extensions in an incognito renderer. (Closed)
Patch Set: Address review Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/renderer_startup_helper.h" 5 #include "extensions/browser/renderer_startup_helper.h"
6 6
7 #include "base/debug/dump_without_crashing.h" 7 #include "base/debug/dump_without_crashing.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/values.h" 10 #include "base/values.h"
11 #include "components/keyed_service/content/browser_context_dependency_manager.h" 11 #include "components/keyed_service/content/browser_context_dependency_manager.h"
12 #include "content/public/browser/browser_context.h"
12 #include "content/public/browser/notification_service.h" 13 #include "content/public/browser/notification_service.h"
13 #include "content/public/browser/notification_types.h" 14 #include "content/public/browser/notification_types.h"
14 #include "content/public/browser/render_process_host.h" 15 #include "content/public/browser/render_process_host.h"
15 #include "extensions/browser/extension_function_dispatcher.h" 16 #include "extensions/browser/extension_function_dispatcher.h"
16 #include "extensions/browser/extension_registry.h" 17 #include "extensions/browser/extension_registry.h"
18 #include "extensions/browser/extension_util.h"
17 #include "extensions/browser/extensions_browser_client.h" 19 #include "extensions/browser/extensions_browser_client.h"
18 #include "extensions/browser/guest_view/web_view/web_view_guest.h" 20 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
19 #include "extensions/common/extension_messages.h" 21 #include "extensions/common/extension_messages.h"
20 #include "extensions/common/extension_set.h" 22 #include "extensions/common/extension_set.h"
21 #include "extensions/common/extensions_client.h" 23 #include "extensions/common/extensions_client.h"
22 #include "extensions/common/features/feature_channel.h" 24 #include "extensions/common/features/feature_channel.h"
23 #include "extensions/common/features/feature_session_type.h" 25 #include "extensions/common/features/feature_session_type.h"
24 #include "ui/base/webui/web_ui_util.h" 26 #include "ui/base/webui/web_ui_util.h"
25 27
26 using content::BrowserContext; 28 using content::BrowserContext;
27 29
28 namespace extensions { 30 namespace extensions {
29 31
32 namespace {
33
34 // Returns whether the |extension| should be loaded in the given
35 // |browser_context|.
36 bool IsExtensionVisibleToContext(const Extension& extension,
37 content::BrowserContext* browser_context) {
38 // Renderers don't need to know about themes.
39 if (extension.is_theme())
40 return false;
41
42 // Only extensions enabled in incognito mode should be loaded in an incognito
43 // renderer. However extensions which can't be enabled in the incognito mode
44 // (e.g. platform apps) should also be loaded in an incognito renderer to
45 // ensure connections from incognito tabs to such extensions work.
46 return !browser_context->IsOffTheRecord() ||
47 !util::CanBeIncognitoEnabled(&extension) ||
48 util::IsIncognitoEnabled(extension.id(), browser_context);
49 }
50
51 } // namespace
52
30 RendererStartupHelper::RendererStartupHelper(BrowserContext* browser_context) 53 RendererStartupHelper::RendererStartupHelper(BrowserContext* browser_context)
31 : browser_context_(browser_context) { 54 : browser_context_(browser_context) {
32 DCHECK(browser_context); 55 DCHECK(browser_context);
33 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, 56 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
34 content::NotificationService::AllBrowserContextsAndSources()); 57 content::NotificationService::AllBrowserContextsAndSources());
35 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 58 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
36 content::NotificationService::AllBrowserContextsAndSources()); 59 content::NotificationService::AllBrowserContextsAndSources());
37 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 60 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
38 content::NotificationService::AllBrowserContextsAndSources()); 61 content::NotificationService::AllBrowserContextsAndSources());
39 } 62 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 // If the new render process is a WebView guest process, propagate the WebView 118 // If the new render process is a WebView guest process, propagate the WebView
96 // partition ID to it. 119 // partition ID to it.
97 std::string webview_partition_id = WebViewGuest::GetPartitionID(process); 120 std::string webview_partition_id = WebViewGuest::GetPartitionID(process);
98 if (!webview_partition_id.empty()) { 121 if (!webview_partition_id.empty()) {
99 process->Send(new ExtensionMsg_SetWebViewPartitionID( 122 process->Send(new ExtensionMsg_SetWebViewPartitionID(
100 WebViewGuest::GetPartitionID(process))); 123 WebViewGuest::GetPartitionID(process)));
101 } 124 }
102 125
103 // Loaded extensions. 126 // Loaded extensions.
104 std::vector<ExtensionMsg_Loaded_Params> loaded_extensions; 127 std::vector<ExtensionMsg_Loaded_Params> loaded_extensions;
128 BrowserContext* renderer_context = process->GetBrowserContext();
105 const ExtensionSet& extensions = 129 const ExtensionSet& extensions =
106 ExtensionRegistry::Get(browser_context_)->enabled_extensions(); 130 ExtensionRegistry::Get(browser_context_)->enabled_extensions();
107 for (const auto& ext : extensions) { 131 for (const auto& ext : extensions) {
108 // OnLoadedExtension should have already been called for the extension. 132 // OnLoadedExtension should have already been called for the extension.
109 DCHECK(base::ContainsKey(extension_process_map_, ext->id())); 133 DCHECK(base::ContainsKey(extension_process_map_, ext->id()));
110 DCHECK(!base::ContainsKey(extension_process_map_[ext->id()], process)); 134 DCHECK(!base::ContainsKey(extension_process_map_[ext->id()], process));
111 135
112 // Renderers don't need to know about themes. 136 if (!IsExtensionVisibleToContext(*ext, renderer_context))
113 if (!ext->is_theme()) { 137 continue;
114 // TODO(kalman): Only include tab specific permissions for extension 138
115 // processes, no other process needs it, so it's mildly wasteful. 139 // TODO(kalman): Only include tab specific permissions for extension
116 // I am not sure this is possible to know this here, at such a low 140 // processes, no other process needs it, so it's mildly wasteful.
117 // level of the stack. Perhaps site isolation can help. 141 // I am not sure this is possible to know this here, at such a low
118 bool include_tab_permissions = true; 142 // level of the stack. Perhaps site isolation can help.
119 loaded_extensions.push_back( 143 bool include_tab_permissions = true;
120 ExtensionMsg_Loaded_Params(ext.get(), include_tab_permissions)); 144 loaded_extensions.push_back(
121 extension_process_map_[ext->id()].insert(process); 145 ExtensionMsg_Loaded_Params(ext.get(), include_tab_permissions));
122 } 146 extension_process_map_[ext->id()].insert(process);
123 } 147 }
148
149 // Activate pending extensions.
124 process->Send(new ExtensionMsg_Loaded(loaded_extensions)); 150 process->Send(new ExtensionMsg_Loaded(loaded_extensions));
125 auto iter = pending_active_extensions_.find(process); 151 auto iter = pending_active_extensions_.find(process);
126 if (iter != pending_active_extensions_.end()) { 152 if (iter != pending_active_extensions_.end()) {
127 for (const ExtensionId& id : iter->second) { 153 for (const ExtensionId& id : iter->second) {
128 // The extension should be loaded in the process. 154 // The extension should be loaded in the process.
129 DCHECK(extensions.Contains(id)); 155 DCHECK(extensions.Contains(id));
130 DCHECK(base::ContainsKey(extension_process_map_, id)); 156 DCHECK(base::ContainsKey(extension_process_map_, id));
131 DCHECK(base::ContainsKey(extension_process_map_[id], process)); 157 DCHECK(base::ContainsKey(extension_process_map_[id], process));
132 process->Send(new ExtensionMsg_ActivateExtension(id)); 158 process->Send(new ExtensionMsg_ActivateExtension(id));
133 } 159 }
(...skipping 24 matching lines...) Expand all
158 if (!base::ContainsKey(extension_process_map_, extension.id())) { 184 if (!base::ContainsKey(extension_process_map_, extension.id())) {
159 #if DCHECK_IS_ON() 185 #if DCHECK_IS_ON()
160 NOTREACHED() << "Extension " << extension.id() 186 NOTREACHED() << "Extension " << extension.id()
161 << "activated before loading"; 187 << "activated before loading";
162 #else 188 #else
163 base::debug::DumpWithoutCrashing(); 189 base::debug::DumpWithoutCrashing();
164 return; 190 return;
165 #endif 191 #endif
166 } 192 }
167 193
168 // Renderers don't need to know about themes. We also don't normally 194 if (!IsExtensionVisibleToContext(extension, process->GetBrowserContext()))
169 // "activate" themes, but this could happen if someone tries to open a tab
170 // to the e.g. theme's manifest.
171 if (extension.is_theme())
172 return; 195 return;
173 196
174 if (base::ContainsKey(initialized_processes_, process)) { 197 if (base::ContainsKey(initialized_processes_, process)) {
175 DCHECK(base::ContainsKey(extension_process_map_[extension.id()], process)); 198 DCHECK(base::ContainsKey(extension_process_map_[extension.id()], process));
176 process->Send(new ExtensionMsg_ActivateExtension(extension.id())); 199 process->Send(new ExtensionMsg_ActivateExtension(extension.id()));
177 } else { 200 } else {
178 pending_active_extensions_[process].insert(extension.id()); 201 pending_active_extensions_[process].insert(extension.id());
179 } 202 }
180 } 203 }
181 204
182 void RendererStartupHelper::OnExtensionLoaded(const Extension& extension) { 205 void RendererStartupHelper::OnExtensionLoaded(const Extension& extension) {
183 // Extension was already loaded. 206 // Extension was already loaded.
184 // TODO(crbug.com/708230): Ensure that clients don't call this for an 207 // TODO(crbug.com/708230): Ensure that clients don't call this for an
185 // already loaded extension and change this to a DCHECK. 208 // already loaded extension and change this to a DCHECK.
186 if (base::ContainsKey(extension_process_map_, extension.id())) 209 if (base::ContainsKey(extension_process_map_, extension.id()))
187 return; 210 return;
188 211
189 // Mark the extension as loaded. 212 // Mark the extension as loaded.
190 std::set<content::RenderProcessHost*>& loaded_process_set = 213 std::set<content::RenderProcessHost*>& loaded_process_set =
191 extension_process_map_[extension.id()]; 214 extension_process_map_[extension.id()];
192 215
193 // Renderers don't need to know about themes. 216 // IsExtensionVisibleToContext() would filter out themes, but we choose to
217 // return early for performance reasons.
194 if (extension.is_theme()) 218 if (extension.is_theme())
195 return; 219 return;
196 220
197 // We don't need to include tab permisisons here, since the extension 221 // We don't need to include tab permisisons here, since the extension
198 // was just loaded. 222 // was just loaded.
199 // Uninitialized renderers will be informed of the extension load during the 223 // Uninitialized renderers will be informed of the extension load during the
200 // first batch of messages. 224 // first batch of messages.
201 std::vector<ExtensionMsg_Loaded_Params> params( 225 std::vector<ExtensionMsg_Loaded_Params> params(
202 1, 226 1,
203 ExtensionMsg_Loaded_Params(&extension, false /* no tab permissions */)); 227 ExtensionMsg_Loaded_Params(&extension, false /* no tab permissions */));
204 for (content::RenderProcessHost* process : initialized_processes_) { 228 for (content::RenderProcessHost* process : initialized_processes_) {
229 if (!IsExtensionVisibleToContext(extension, process->GetBrowserContext()))
230 continue;
205 process->Send(new ExtensionMsg_Loaded(params)); 231 process->Send(new ExtensionMsg_Loaded(params));
206 loaded_process_set.insert(process); 232 loaded_process_set.insert(process);
207 } 233 }
208 } 234 }
209 235
210 void RendererStartupHelper::OnExtensionUnloaded(const Extension& extension) { 236 void RendererStartupHelper::OnExtensionUnloaded(const Extension& extension) {
211 // Extension is not loaded. 237 // Extension is not loaded.
212 // TODO(crbug.com/708230): Ensure that clients call this for a loaded 238 // TODO(crbug.com/708230): Ensure that clients call this for a loaded
213 // extension only and change this to a DCHECK. 239 // extension only and change this to a DCHECK.
214 if (!base::ContainsKey(extension_process_map_, extension.id())) 240 if (!base::ContainsKey(extension_process_map_, extension.id()))
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 BrowserContext* context) const { 286 BrowserContext* context) const {
261 // Redirected in incognito. 287 // Redirected in incognito.
262 return ExtensionsBrowserClient::Get()->GetOriginalContext(context); 288 return ExtensionsBrowserClient::Get()->GetOriginalContext(context);
263 } 289 }
264 290
265 bool RendererStartupHelperFactory::ServiceIsCreatedWithBrowserContext() const { 291 bool RendererStartupHelperFactory::ServiceIsCreatedWithBrowserContext() const {
266 return true; 292 return true;
267 } 293 }
268 294
269 } // namespace extensions 295 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_messages_apitest.cc ('k') | extensions/browser/renderer_startup_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698