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

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: -- Created 3 years, 9 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/stl_util.h" 7 #include "base/stl_util.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 #include "components/keyed_service/content/browser_context_dependency_manager.h" 9 #include "components/keyed_service/content/browser_context_dependency_manager.h"
10 #include "content/public/browser/browser_context.h"
10 #include "content/public/browser/notification_service.h" 11 #include "content/public/browser/notification_service.h"
11 #include "content/public/browser/notification_types.h" 12 #include "content/public/browser/notification_types.h"
12 #include "content/public/browser/render_process_host.h" 13 #include "content/public/browser/render_process_host.h"
13 #include "extensions/browser/extension_function_dispatcher.h" 14 #include "extensions/browser/extension_function_dispatcher.h"
14 #include "extensions/browser/extension_registry.h" 15 #include "extensions/browser/extension_registry.h"
16 #include "extensions/browser/extension_util.h"
15 #include "extensions/browser/extensions_browser_client.h" 17 #include "extensions/browser/extensions_browser_client.h"
16 #include "extensions/browser/guest_view/web_view/web_view_guest.h" 18 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
17 #include "extensions/common/extension_messages.h" 19 #include "extensions/common/extension_messages.h"
18 #include "extensions/common/extension_set.h" 20 #include "extensions/common/extension_set.h"
19 #include "extensions/common/extensions_client.h" 21 #include "extensions/common/extensions_client.h"
20 #include "extensions/common/features/feature_channel.h" 22 #include "extensions/common/features/feature_channel.h"
21 #include "extensions/common/features/feature_session_type.h" 23 #include "extensions/common/features/feature_session_type.h"
22 #include "ui/base/webui/web_ui_util.h" 24 #include "ui/base/webui/web_ui_util.h"
23 25
24 using content::BrowserContext; 26 using content::BrowserContext;
25 27
26 namespace extensions { 28 namespace extensions {
27 29
30 namespace {
31
32 // Returns whether the |extension| should be loaded in the given
33 // renderer |process|.
34 bool IsExtensionVisibleToProcess(const Extension& extension,
35 content::RenderProcessHost* process) {
36 // Renderers don't need to know about themes.
37 if (extension.is_theme())
38 return false;
39
40 // Only extensions enabled in incognito mode should be loaded in an incognito
41 // renderer. However extensions which can't be loaded in the incognito mode
42 // (e.g. platform apps) should also be loaded in an incognito renderer to
43 // ensure connections from incognito tabs to such extensions work fine.
Devlin 2017/03/23 22:08:37 nitty nit: omit ' fine' -> 'ensure connections fro
karandeepb 2017/04/04 03:44:15 Done.
44 content::BrowserContext* browser_context = process->GetBrowserContext();
45 return !browser_context->IsOffTheRecord() ||
46 !util::CanBeIncognitoEnabled(&extension) ||
47 util::IsIncognitoEnabled(extension.id(), browser_context);
48 }
49
50 } // namespace
51
28 RendererStartupHelper::RendererStartupHelper(BrowserContext* browser_context) 52 RendererStartupHelper::RendererStartupHelper(BrowserContext* browser_context)
29 : browser_context_(browser_context) { 53 : browser_context_(browser_context) {
30 DCHECK(browser_context); 54 DCHECK(browser_context);
31 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, 55 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
32 content::NotificationService::AllBrowserContextsAndSources()); 56 content::NotificationService::AllBrowserContextsAndSources());
33 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 57 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
34 content::NotificationService::AllBrowserContextsAndSources()); 58 content::NotificationService::AllBrowserContextsAndSources());
35 } 59 }
36 60
37 RendererStartupHelper::~RendererStartupHelper() {} 61 RendererStartupHelper::~RendererStartupHelper() {}
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 process->Send(new ExtensionMsg_SetWebViewPartitionID( 115 process->Send(new ExtensionMsg_SetWebViewPartitionID(
92 WebViewGuest::GetPartitionID(process))); 116 WebViewGuest::GetPartitionID(process)));
93 } 117 }
94 118
95 std::set<ExtensionId>* loaded_extensions = &loaded_extensions_[process]; 119 std::set<ExtensionId>* loaded_extensions = &loaded_extensions_[process];
96 // Load extensions. 120 // Load extensions.
97 std::vector<ExtensionMsg_Loaded_Params> loaded_extensions_params; 121 std::vector<ExtensionMsg_Loaded_Params> loaded_extensions_params;
98 const ExtensionSet& extensions = 122 const ExtensionSet& extensions =
99 ExtensionRegistry::Get(browser_context_)->enabled_extensions(); 123 ExtensionRegistry::Get(browser_context_)->enabled_extensions();
100 for (const auto& ext : extensions) { 124 for (const auto& ext : extensions) {
101 // Renderers don't need to know about themes. 125 if (!IsExtensionVisibleToProcess(*ext, process))
Devlin 2017/03/23 22:08:37 nitty nit: We actually only need the browser conte
karandeepb 2017/04/04 03:44:15 Done.
102 if (!ext->is_theme()) { 126 continue;
103 // TODO(kalman): Only include tab specific permissions for extension 127
104 // processes, no other process needs it, so it's mildly wasteful. 128 // TODO(kalman): Only include tab specific permissions for extension
105 // I am not sure this is possible to know this here, at such a low 129 // processes, no other process needs it, so it's mildly wasteful.
106 // level of the stack. Perhaps site isolation can help. 130 // I am not sure this is possible to know this here, at such a low
107 bool include_tab_permissions = true; 131 // level of the stack. Perhaps site isolation can help.
108 loaded_extensions_params.push_back( 132 bool include_tab_permissions = true;
109 ExtensionMsg_Loaded_Params(ext.get(), include_tab_permissions)); 133 loaded_extensions_params.push_back(
110 loaded_extensions->insert(ext->id()); 134 ExtensionMsg_Loaded_Params(ext.get(), include_tab_permissions));
111 } 135 loaded_extensions->insert(ext->id());
112 } 136 }
113 137
114 // Activate pending extensions. 138 // Activate pending extensions.
115 process->Send(new ExtensionMsg_Loaded(loaded_extensions_params)); 139 process->Send(new ExtensionMsg_Loaded(loaded_extensions_params));
116 auto iter = pending_active_extensions_.find(process); 140 auto iter = pending_active_extensions_.find(process);
117 if (iter != pending_active_extensions_.end()) { 141 if (iter != pending_active_extensions_.end()) {
118 for (const ExtensionId& id : iter->second) { 142 for (const ExtensionId& id : iter->second) {
119 DCHECK(extensions.Contains(id)); 143 DCHECK(extensions.Contains(id));
120 process->Send(new ExtensionMsg_ActivateExtension(id)); 144 process->Send(new ExtensionMsg_ActivateExtension(id));
121 } 145 }
122 } 146 }
123 147
124 pending_active_extensions_.erase(process); 148 pending_active_extensions_.erase(process);
125 } 149 }
126 150
127 void RendererStartupHelper::UntrackProcess( 151 void RendererStartupHelper::UntrackProcess(
128 content::RenderProcessHost* process) { 152 content::RenderProcessHost* process) {
129 if (!ExtensionsBrowserClient::Get()->IsSameContext( 153 if (!ExtensionsBrowserClient::Get()->IsSameContext(
130 browser_context_, process->GetBrowserContext())) { 154 browser_context_, process->GetBrowserContext())) {
131 return; 155 return;
132 } 156 }
133 157
134 loaded_extensions_.erase(process); 158 loaded_extensions_.erase(process);
135 pending_active_extensions_.erase(process); 159 pending_active_extensions_.erase(process);
136 } 160 }
137 161
138 void RendererStartupHelper::ActivateExtensionInProcess( 162 void RendererStartupHelper::ActivateExtensionInProcess(
139 const Extension& extension, 163 const Extension& extension,
140 content::RenderProcessHost* process) { 164 content::RenderProcessHost* process) {
141 // Renderers don't need to know about themes. We also don't normally 165 if (!IsExtensionVisibleToProcess(extension, process))
142 // "activate" themes, but this could happen if someone tries to open a tab
143 // to the e.g. theme's manifest.
144 if (extension.is_theme())
145 return; 166 return;
146 167
147 const auto& process_extensions_pair = loaded_extensions_.find(process); 168 const auto& process_extensions_pair = loaded_extensions_.find(process);
148 if (process_extensions_pair != loaded_extensions_.end()) { 169 if (process_extensions_pair != loaded_extensions_.end()) {
149 // The extension should have already been loaded in the process. 170 // The extension should have already been loaded in the process.
150 if (!base::ContainsKey(process_extensions_pair->second, extension.id())) { 171 if (!base::ContainsKey(process_extensions_pair->second, extension.id())) {
151 NOTREACHED() << "Extension " << extension.id() 172 NOTREACHED() << "Extension " << extension.id()
152 << " was not loaded for activation"; 173 << " was not loaded for activation";
153 return; 174 return;
154 } 175 }
155 process->Send(new ExtensionMsg_ActivateExtension(extension.id())); 176 process->Send(new ExtensionMsg_ActivateExtension(extension.id()));
156 } else { 177 } else {
157 pending_active_extensions_[process].insert(extension.id()); 178 pending_active_extensions_[process].insert(extension.id());
158 } 179 }
159 } 180 }
160 181
161 void RendererStartupHelper::OnExtensionLoaded(const Extension& extension) { 182 void RendererStartupHelper::OnExtensionLoaded(const Extension& extension) {
162 // Renderers don't need to know about themes.
163 if (extension.is_theme())
164 return;
Devlin 2017/03/23 22:08:37 I wonder if it's worth keeping this short-circuit,
karandeepb 2017/04/04 03:44:15 Centralizing the logic in IsExtensionVisibleToProc
Devlin 2017/04/04 15:15:05 Given it's somewhat performance-sensitive code, le
165
166 // We don't need to include tab permisisons here, since the extension 183 // We don't need to include tab permisisons here, since the extension
167 // was just loaded. 184 // was just loaded.
168 // Uninitialized renderers will be informed of the extension load during the 185 // Uninitialized renderers will be informed of the extension load during the
169 // first batch of messages. 186 // first batch of messages.
170 std::vector<ExtensionMsg_Loaded_Params> params( 187 std::vector<ExtensionMsg_Loaded_Params> params(
171 1, 188 1,
172 ExtensionMsg_Loaded_Params(&extension, false /* no tab permissions */)); 189 ExtensionMsg_Loaded_Params(&extension, false /* no tab permissions */));
173 190
174 for (auto& process_extensions_pair : loaded_extensions_) { 191 for (auto& process_extensions_pair : loaded_extensions_) {
175 // If extension is already loaded in process, do nothing. 192 // If extension is already loaded in process, do nothing.
176 if (base::ContainsKey(process_extensions_pair.second, extension.id())) 193 if (base::ContainsKey(process_extensions_pair.second, extension.id()))
177 continue; 194 continue;
178 195
179 content::RenderProcessHost* process = process_extensions_pair.first; 196 content::RenderProcessHost* process = process_extensions_pair.first;
197 if (!IsExtensionVisibleToProcess(extension, process))
198 continue;
199
180 process->Send(new ExtensionMsg_Loaded(params)); 200 process->Send(new ExtensionMsg_Loaded(params));
181 process_extensions_pair.second.insert(extension.id()); 201 process_extensions_pair.second.insert(extension.id());
182 } 202 }
183 } 203 }
184 204
185 void RendererStartupHelper::OnExtensionUnloaded(const Extension& extension) { 205 void RendererStartupHelper::OnExtensionUnloaded(const Extension& extension) {
186 for (auto& process_extensions_pair : loaded_extensions_) { 206 for (auto& process_extensions_pair : loaded_extensions_) {
187 // If extension is already unloaded, do nothing. 207 // If extension is already unloaded, do nothing.
188 if (!base::ContainsKey(process_extensions_pair.second, extension.id())) 208 if (!base::ContainsKey(process_extensions_pair.second, extension.id()))
189 continue; 209 continue;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 BrowserContext* context) const { 249 BrowserContext* context) const {
230 // Redirected in incognito. 250 // Redirected in incognito.
231 return ExtensionsBrowserClient::Get()->GetOriginalContext(context); 251 return ExtensionsBrowserClient::Get()->GetOriginalContext(context);
232 } 252 }
233 253
234 bool RendererStartupHelperFactory::ServiceIsCreatedWithBrowserContext() const { 254 bool RendererStartupHelperFactory::ServiceIsCreatedWithBrowserContext() const {
235 return true; 255 return true;
236 } 256 }
237 257
238 } // namespace extensions 258 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698