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

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

Issue 408523005: Reland: Refactor code that defers extension background page loading (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: dependency inject ExtensionRegistry Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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/process_manager.h" 5 #include "extensions/browser/process_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 15 matching lines...) Expand all
26 #include "content/public/browser/web_contents.h" 26 #include "content/public/browser/web_contents.h"
27 #include "content/public/browser/web_contents_delegate.h" 27 #include "content/public/browser/web_contents_delegate.h"
28 #include "content/public/browser/web_contents_observer.h" 28 #include "content/public/browser/web_contents_observer.h"
29 #include "content/public/browser/web_contents_user_data.h" 29 #include "content/public/browser/web_contents_user_data.h"
30 #include "content/public/common/renderer_preferences.h" 30 #include "content/public/common/renderer_preferences.h"
31 #include "content/public/common/url_constants.h" 31 #include "content/public/common/url_constants.h"
32 #include "extensions/browser/extension_host.h" 32 #include "extensions/browser/extension_host.h"
33 #include "extensions/browser/extension_registry.h" 33 #include "extensions/browser/extension_registry.h"
34 #include "extensions/browser/extension_system.h" 34 #include "extensions/browser/extension_system.h"
35 #include "extensions/browser/extensions_browser_client.h" 35 #include "extensions/browser/extensions_browser_client.h"
36 #include "extensions/browser/process_manager_delegate.h"
36 #include "extensions/browser/process_manager_observer.h" 37 #include "extensions/browser/process_manager_observer.h"
37 #include "extensions/browser/view_type_utils.h" 38 #include "extensions/browser/view_type_utils.h"
38 #include "extensions/common/constants.h" 39 #include "extensions/common/constants.h"
39 #include "extensions/common/extension.h" 40 #include "extensions/common/extension.h"
40 #include "extensions/common/extension_messages.h" 41 #include "extensions/common/extension_messages.h"
41 #include "extensions/common/manifest_handlers/background_info.h" 42 #include "extensions/common/manifest_handlers/background_info.h"
42 #include "extensions/common/manifest_handlers/incognito_info.h" 43 #include "extensions/common/manifest_handlers/incognito_info.h"
43 #include "extensions/common/one_shot_event.h" 44 #include "extensions/common/one_shot_event.h"
44 #include "extensions/common/switches.h" 45 #include "extensions/common/switches.h"
45 46
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 content::Details<RenderViewHost>(render_view_host)); 99 content::Details<RenderViewHost>(render_view_host));
99 } 100 }
100 101
101 // Incognito profiles use this process manager. It is mostly a shim that decides 102 // Incognito profiles use this process manager. It is mostly a shim that decides
102 // whether to fall back on the original profile's ProcessManager based 103 // whether to fall back on the original profile's ProcessManager based
103 // on whether a given extension uses "split" or "spanning" incognito behavior. 104 // on whether a given extension uses "split" or "spanning" incognito behavior.
104 class IncognitoProcessManager : public ProcessManager { 105 class IncognitoProcessManager : public ProcessManager {
105 public: 106 public:
106 IncognitoProcessManager(BrowserContext* incognito_context, 107 IncognitoProcessManager(BrowserContext* incognito_context,
107 BrowserContext* original_context, 108 BrowserContext* original_context,
108 ProcessManager* original_manager); 109 ProcessManager* original_manager,
110 ExtensionRegistry* extension_registry);
109 virtual ~IncognitoProcessManager() {} 111 virtual ~IncognitoProcessManager() {}
110 virtual bool CreateBackgroundHost(const Extension* extension, 112 virtual bool CreateBackgroundHost(const Extension* extension,
111 const GURL& url) OVERRIDE; 113 const GURL& url) OVERRIDE;
112 virtual SiteInstance* GetSiteInstanceForURL(const GURL& url) OVERRIDE; 114 virtual SiteInstance* GetSiteInstanceForURL(const GURL& url) OVERRIDE;
113 115
114 private: 116 private:
115 ProcessManager* original_manager_; 117 ProcessManager* original_manager_;
116 118
117 DISALLOW_COPY_AND_ASSIGN(IncognitoProcessManager); 119 DISALLOW_COPY_AND_ASSIGN(IncognitoProcessManager);
118 }; 120 };
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 is_closing(false), 185 is_closing(false),
184 close_sequence_id(0) {} 186 close_sequence_id(0) {}
185 }; 187 };
186 188
187 // 189 //
188 // ProcessManager 190 // ProcessManager
189 // 191 //
190 192
191 // static 193 // static
192 ProcessManager* ProcessManager::Create(BrowserContext* context) { 194 ProcessManager* ProcessManager::Create(BrowserContext* context) {
195 ExtensionRegistry* extension_registry = ExtensionRegistry::Get(context);
193 ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); 196 ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get();
194 if (client->IsGuestSession(context)) { 197 if (client->IsGuestSession(context)) {
195 // In the guest session, there is a single off-the-record context. Unlike 198 // In the guest session, there is a single off-the-record context. Unlike
196 // a regular incognito mode, background pages of extensions must be 199 // a regular incognito mode, background pages of extensions must be
197 // created regardless of whether extensions use "spanning" or "split" 200 // created regardless of whether extensions use "spanning" or "split"
198 // incognito behavior. 201 // incognito behavior.
199 BrowserContext* original_context = client->GetOriginalContext(context); 202 BrowserContext* original_context = client->GetOriginalContext(context);
200 return new ProcessManager(context, original_context); 203 return new ProcessManager(context, original_context, extension_registry);
201 } 204 }
202 205
203 if (context->IsOffTheRecord()) { 206 if (context->IsOffTheRecord()) {
204 BrowserContext* original_context = client->GetOriginalContext(context); 207 BrowserContext* original_context = client->GetOriginalContext(context);
205 ProcessManager* original_manager = 208 ProcessManager* original_manager =
206 ExtensionSystem::Get(original_context)->process_manager(); 209 ExtensionSystem::Get(original_context)->process_manager();
207 return new IncognitoProcessManager( 210 return new IncognitoProcessManager(
208 context, original_context, original_manager); 211 context, original_context, original_manager, extension_registry);
209 } 212 }
210 213
211 return new ProcessManager(context, context); 214 return new ProcessManager(context, context, extension_registry);
215 }
216
217 // static
218 ProcessManager* ProcessManager::CreateForTesting(
219 BrowserContext* context,
220 ExtensionRegistry* extension_registry) {
221 DCHECK(!context->IsOffTheRecord());
222 return new ProcessManager(context, context, extension_registry);
212 } 223 }
213 224
214 // static 225 // static
215 ProcessManager* ProcessManager::CreateIncognitoForTesting( 226 ProcessManager* ProcessManager::CreateIncognitoForTesting(
216 BrowserContext* incognito_context, 227 BrowserContext* incognito_context,
217 BrowserContext* original_context, 228 BrowserContext* original_context,
218 ProcessManager* original_manager) { 229 ProcessManager* original_manager,
230 ExtensionRegistry* extension_registry) {
219 DCHECK(incognito_context->IsOffTheRecord()); 231 DCHECK(incognito_context->IsOffTheRecord());
220 DCHECK(!original_context->IsOffTheRecord()); 232 DCHECK(!original_context->IsOffTheRecord());
221 return new IncognitoProcessManager( 233 return new IncognitoProcessManager(incognito_context,
222 incognito_context, original_context, original_manager); 234 original_context,
235 original_manager,
236 extension_registry);
223 } 237 }
224 238
225 ProcessManager::ProcessManager(BrowserContext* context, 239 ProcessManager::ProcessManager(BrowserContext* context,
226 BrowserContext* original_context) 240 BrowserContext* original_context,
241 ExtensionRegistry* extension_registry)
227 : site_instance_(SiteInstance::Create(context)), 242 : site_instance_(SiteInstance::Create(context)),
243 extension_registry_(extension_registry),
228 startup_background_hosts_created_(false), 244 startup_background_hosts_created_(false),
229 devtools_callback_(base::Bind(&ProcessManager::OnDevToolsStateChanged, 245 devtools_callback_(base::Bind(&ProcessManager::OnDevToolsStateChanged,
230 base::Unretained(this))), 246 base::Unretained(this))),
231 last_background_close_sequence_id_(0), 247 last_background_close_sequence_id_(0),
232 weak_ptr_factory_(this) { 248 weak_ptr_factory_(this) {
249 // ExtensionRegistry is shared between incognito and regular contexts.
250 DCHECK_EQ(original_context, extension_registry_->browser_context());
233 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, 251 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
234 content::Source<BrowserContext>(original_context)); 252 content::Source<BrowserContext>(original_context));
235 registrar_.Add(this, 253 registrar_.Add(this,
236 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, 254 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
237 content::Source<BrowserContext>(original_context)); 255 content::Source<BrowserContext>(original_context));
238 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, 256 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
239 content::Source<BrowserContext>(original_context)); 257 content::Source<BrowserContext>(original_context));
240 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, 258 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
241 content::Source<BrowserContext>(context)); 259 content::Source<BrowserContext>(context));
242 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, 260 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
243 content::Source<BrowserContext>(context)); 261 content::Source<BrowserContext>(context));
244 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, 262 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
245 content::NotificationService::AllSources()); 263 content::NotificationService::AllSources());
246 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, 264 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
247 content::NotificationService::AllSources()); 265 content::NotificationService::AllSources());
248 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
249 content::Source<BrowserContext>(original_context));
250 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 266 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
251 content::Source<BrowserContext>(context)); 267 content::Source<BrowserContext>(context));
252 if (context->IsOffTheRecord()) { 268 if (context->IsOffTheRecord()) {
253 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 269 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
254 content::Source<BrowserContext>(original_context)); 270 content::Source<BrowserContext>(original_context));
255 } 271 }
256 272
257 // Note: event_page_idle_time_ must be sufficiently larger (e.g. 2x) than 273 // Note: event_page_idle_time_ must be sufficiently larger (e.g. 2x) than
258 // kKeepaliveThrottleIntervalInSeconds in ppapi/proxy/plugin_globals. 274 // kKeepaliveThrottleIntervalInSeconds in ppapi/proxy/plugin_globals.
259 event_page_idle_time_ = base::TimeDelta::FromSeconds(10); 275 event_page_idle_time_ = base::TimeDelta::FromSeconds(10);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 } 316 }
301 317
302 void ProcessManager::RemoveObserver(ProcessManagerObserver* observer) { 318 void ProcessManager::RemoveObserver(ProcessManagerObserver* observer) {
303 observer_list_.RemoveObserver(observer); 319 observer_list_.RemoveObserver(observer);
304 } 320 }
305 321
306 bool ProcessManager::CreateBackgroundHost(const Extension* extension, 322 bool ProcessManager::CreateBackgroundHost(const Extension* extension,
307 const GURL& url) { 323 const GURL& url) {
308 // Hosted apps are taken care of from BackgroundContentsService. Ignore them 324 // Hosted apps are taken care of from BackgroundContentsService. Ignore them
309 // here. 325 // here.
310 if (extension->is_hosted_app() || 326 if (extension->is_hosted_app())
311 !ExtensionsBrowserClient::Get()->
312 IsBackgroundPageAllowed(GetBrowserContext())) {
313 return false; 327 return false;
314 } 328
329 // Don't create hosts if the embedder doesn't allow it.
330 ProcessManagerDelegate* delegate =
331 ExtensionsBrowserClient::Get()->GetProcessManagerDelegate();
332 if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext()))
333 return false;
315 334
316 // Don't create multiple background hosts for an extension. 335 // Don't create multiple background hosts for an extension.
317 if (GetBackgroundHostForExtension(extension->id())) 336 if (GetBackgroundHostForExtension(extension->id()))
318 return true; // TODO(kalman): return false here? It might break things... 337 return true; // TODO(kalman): return false here? It might break things...
319 338
320 ExtensionHost* host = 339 ExtensionHost* host =
321 new ExtensionHost(extension, GetSiteInstanceForURL(url), url, 340 new ExtensionHost(extension, GetSiteInstanceForURL(url), url,
322 VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); 341 VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
323 host->CreateRenderViewSoon(); 342 host->CreateRenderViewSoon();
324 OnBackgroundHostCreated(host); 343 OnBackgroundHostCreated(host);
(...skipping 28 matching lines...) Expand all
353 } 372 }
354 373
355 return result; 374 return result;
356 } 375 }
357 376
358 const Extension* ProcessManager::GetExtensionForRenderViewHost( 377 const Extension* ProcessManager::GetExtensionForRenderViewHost(
359 RenderViewHost* render_view_host) { 378 RenderViewHost* render_view_host) {
360 if (!render_view_host->GetSiteInstance()) 379 if (!render_view_host->GetSiteInstance())
361 return NULL; 380 return NULL;
362 381
363 ExtensionRegistry* registry = ExtensionRegistry::Get(GetBrowserContext()); 382 return extension_registry_->enabled_extensions().GetByID(
364 if (!registry)
365 return NULL;
366
367 return registry->enabled_extensions().GetByID(
368 GetExtensionID(render_view_host)); 383 GetExtensionID(render_view_host));
369 } 384 }
370 385
371 void ProcessManager::UnregisterRenderViewHost( 386 void ProcessManager::UnregisterRenderViewHost(
372 RenderViewHost* render_view_host) { 387 RenderViewHost* render_view_host) {
373 ExtensionRenderViews::iterator view = 388 ExtensionRenderViews::iterator view =
374 all_extension_views_.find(render_view_host); 389 all_extension_views_.find(render_view_host);
375 if (view == all_extension_views_.end()) 390 if (view == all_extension_views_.end())
376 return; 391 return;
377 392
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 void ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) { 448 void ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) {
434 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) 449 if (!BackgroundInfo::HasLazyBackgroundPage(extension))
435 return; 450 return;
436 DecrementLazyKeepaliveCount(extension->id()); 451 DecrementLazyKeepaliveCount(extension->id());
437 } 452 }
438 453
439 void ProcessManager::DecrementLazyKeepaliveCount( 454 void ProcessManager::DecrementLazyKeepaliveCount(
440 const std::string& extension_id) { 455 const std::string& extension_id) {
441 int& count = background_page_data_[extension_id].lazy_keepalive_count; 456 int& count = background_page_data_[extension_id].lazy_keepalive_count;
442 DCHECK(count > 0 || 457 DCHECK(count > 0 ||
443 !ExtensionRegistry::Get(GetBrowserContext()) 458 !extension_registry_->enabled_extensions().Contains(extension_id));
444 ->enabled_extensions()
445 .Contains(extension_id));
446 459
447 // If we reach a zero keepalive count when the lazy background page is about 460 // If we reach a zero keepalive count when the lazy background page is about
448 // to be closed, incrementing close_sequence_id will cancel the close 461 // to be closed, incrementing close_sequence_id will cancel the close
449 // sequence and cause the background page to linger. So check is_closing 462 // sequence and cause the background page to linger. So check is_closing
450 // before initiating another close sequence. 463 // before initiating another close sequence.
451 if (--count == 0 && !background_page_data_[extension_id].is_closing) { 464 if (--count == 0 && !background_page_data_[extension_id].is_closing) {
452 background_page_data_[extension_id].close_sequence_id = 465 background_page_data_[extension_id].close_sequence_id =
453 ++last_background_close_sequence_id_; 466 ++last_background_close_sequence_id_;
454 base::MessageLoop::current()->PostDelayedTask( 467 base::MessageLoop::current()->PostDelayedTask(
455 FROM_HERE, 468 FROM_HERE,
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 new ExtensionMsg_CancelSuspend(extension->id())); 626 new ExtensionMsg_CancelSuspend(extension->id()));
614 // This increment / decrement is to simulate an instantaneous event. This 627 // This increment / decrement is to simulate an instantaneous event. This
615 // has the effect of invalidating close_sequence_id, preventing any in 628 // has the effect of invalidating close_sequence_id, preventing any in
616 // progress closes from completing and starting a new close process if 629 // progress closes from completing and starting a new close process if
617 // necessary. 630 // necessary.
618 IncrementLazyKeepaliveCount(extension); 631 IncrementLazyKeepaliveCount(extension);
619 DecrementLazyKeepaliveCount(extension); 632 DecrementLazyKeepaliveCount(extension);
620 } 633 }
621 } 634 }
622 635
623 void ProcessManager::OnBrowserWindowReady() {
624 // If the extension system isn't ready yet the background hosts will be
625 // created via NOTIFICATION_EXTENSIONS_READY below.
626 ExtensionSystem* system = ExtensionSystem::Get(GetBrowserContext());
627 if (!system->ready().is_signaled())
628 return;
629
630 CreateBackgroundHostsForProfileStartup();
631 }
632
633 content::BrowserContext* ProcessManager::GetBrowserContext() const { 636 content::BrowserContext* ProcessManager::GetBrowserContext() const {
634 return site_instance_->GetBrowserContext(); 637 return site_instance_->GetBrowserContext();
635 } 638 }
636 639
637 void ProcessManager::SetKeepaliveImpulseCallbackForTesting( 640 void ProcessManager::SetKeepaliveImpulseCallbackForTesting(
638 const ImpulseCallbackForTesting& callback) { 641 const ImpulseCallbackForTesting& callback) {
639 keepalive_impulse_callback_for_testing_ = callback; 642 keepalive_impulse_callback_for_testing_ = callback;
640 } 643 }
641 644
642 void ProcessManager::SetKeepaliveImpulseDecrementCallbackForTesting( 645 void ProcessManager::SetKeepaliveImpulseDecrementCallbackForTesting(
643 const ImpulseCallbackForTesting& callback) { 646 const ImpulseCallbackForTesting& callback) {
644 keepalive_impulse_decrement_callback_for_testing_ = callback; 647 keepalive_impulse_decrement_callback_for_testing_ = callback;
645 } 648 }
646 649
647 void ProcessManager::Observe(int type, 650 void ProcessManager::Observe(int type,
648 const content::NotificationSource& source, 651 const content::NotificationSource& source,
649 const content::NotificationDetails& details) { 652 const content::NotificationDetails& details) {
650 switch (type) { 653 switch (type) {
651 case chrome::NOTIFICATION_EXTENSIONS_READY: 654 case chrome::NOTIFICATION_EXTENSIONS_READY: {
652 case chrome::NOTIFICATION_PROFILE_CREATED: { 655 // TODO(jamescook): Convert this to use ExtensionSystem::ready() instead
653 // Don't load background hosts now if the loading should be deferred. 656 // of a notification.
654 // Instead they will be loaded when a browser window for this profile 657 MaybeCreateStartupBackgroundHosts();
655 // (or an incognito profile from this profile) is ready.
656 if (DeferLoadingBackgroundHosts())
657 break;
658
659 CreateBackgroundHostsForProfileStartup();
660 break; 658 break;
661 } 659 }
662 660
663 case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: { 661 case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
664 BrowserContext* context = content::Source<BrowserContext>(source).ptr(); 662 BrowserContext* context = content::Source<BrowserContext>(source).ptr();
665 ExtensionSystem* system = ExtensionSystem::Get(context); 663 ExtensionSystem* system = ExtensionSystem::Get(context);
666 if (system->ready().is_signaled()) { 664 if (system->ready().is_signaled()) {
667 // The extension system is ready, so create the background host. 665 // The extension system is ready, so create the background host.
668 const Extension* extension = 666 const Extension* extension =
669 content::Details<const Extension>(details).ptr(); 667 content::Details<const Extension>(details).ptr();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 return; 775 return;
778 if (attached) { 776 if (attached) {
779 // Keep the lazy background page alive while it's being inspected. 777 // Keep the lazy background page alive while it's being inspected.
780 CancelSuspend(extension); 778 CancelSuspend(extension);
781 IncrementLazyKeepaliveCount(extension); 779 IncrementLazyKeepaliveCount(extension);
782 } else { 780 } else {
783 DecrementLazyKeepaliveCount(extension); 781 DecrementLazyKeepaliveCount(extension);
784 } 782 }
785 } 783 }
786 784
787 void ProcessManager::CreateBackgroundHostsForProfileStartup() { 785 void ProcessManager::MaybeCreateStartupBackgroundHosts() {
788 if (startup_background_hosts_created_ || 786 if (startup_background_hosts_created_)
789 !ExtensionsBrowserClient::Get()->
790 IsBackgroundPageAllowed(GetBrowserContext())) {
791 return; 787 return;
792 }
793 788
794 const ExtensionSet& enabled_extensions = 789 // The embedder might disallow background pages entirely.
795 ExtensionRegistry::Get(GetBrowserContext())->enabled_extensions(); 790 ProcessManagerDelegate* delegate =
796 for (ExtensionSet::const_iterator extension = enabled_extensions.begin(); 791 ExtensionsBrowserClient::Get()->GetProcessManagerDelegate();
797 extension != enabled_extensions.end(); 792 if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext()))
798 ++extension) { 793 return;
799 CreateBackgroundHostForExtensionLoad(this, extension->get());
800 794
801 FOR_EACH_OBSERVER(ProcessManagerObserver, 795 // The embedder might want to defer background page loading. For example,
802 observer_list_, 796 // Chrome defers background page loading when it is launched to show the app
803 OnBackgroundHostStartup(*extension)); 797 // list, then triggers a load later when a browser window opens.
804 } 798 if (delegate &&
799 delegate->DeferCreatingStartupBackgroundHosts(GetBrowserContext()))
800 return;
801
802 CreateStartupBackgroundHosts();
805 startup_background_hosts_created_ = true; 803 startup_background_hosts_created_ = true;
806 804
807 // Background pages should only be loaded once. To prevent any further loads 805 // Background pages should only be loaded once. To prevent any further loads
808 // occurring, we remove the notification listeners. 806 // occurring, we remove the notification listeners.
809 BrowserContext* original_context = 807 BrowserContext* original_context =
810 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); 808 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext());
811 if (registrar_.IsRegistered( 809 if (registrar_.IsRegistered(
812 this, 810 this,
813 chrome::NOTIFICATION_PROFILE_CREATED,
814 content::Source<BrowserContext>(original_context))) {
815 registrar_.Remove(this,
816 chrome::NOTIFICATION_PROFILE_CREATED,
817 content::Source<BrowserContext>(original_context));
818 }
819 if (registrar_.IsRegistered(
820 this,
821 chrome::NOTIFICATION_EXTENSIONS_READY, 811 chrome::NOTIFICATION_EXTENSIONS_READY,
822 content::Source<BrowserContext>(original_context))) { 812 content::Source<BrowserContext>(original_context))) {
823 registrar_.Remove(this, 813 registrar_.Remove(this,
824 chrome::NOTIFICATION_EXTENSIONS_READY, 814 chrome::NOTIFICATION_EXTENSIONS_READY,
825 content::Source<BrowserContext>(original_context)); 815 content::Source<BrowserContext>(original_context));
826 } 816 }
827 } 817 }
828 818
819 void ProcessManager::CreateStartupBackgroundHosts() {
820 DCHECK(!startup_background_hosts_created_);
821 const ExtensionSet& enabled_extensions =
822 extension_registry_->enabled_extensions();
823 for (ExtensionSet::const_iterator extension = enabled_extensions.begin();
824 extension != enabled_extensions.end();
825 ++extension) {
826 CreateBackgroundHostForExtensionLoad(this, extension->get());
827
828 FOR_EACH_OBSERVER(ProcessManagerObserver,
829 observer_list_,
830 OnBackgroundHostStartup(*extension));
831 }
832 }
833
829 void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) { 834 void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) {
830 DCHECK_EQ(GetBrowserContext(), host->browser_context()); 835 DCHECK_EQ(GetBrowserContext(), host->browser_context());
831 background_hosts_.insert(host); 836 background_hosts_.insert(host);
832 837
833 if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) { 838 if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) {
834 linked_ptr<base::ElapsedTimer> since_suspended( 839 linked_ptr<base::ElapsedTimer> since_suspended(
835 background_page_data_[host->extension()->id()]. 840 background_page_data_[host->extension()->id()].
836 since_suspended.release()); 841 since_suspended.release());
837 if (since_suspended.get()) { 842 if (since_suspended.get()) {
838 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageIdleTime", 843 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageIdleTime",
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 // Re-register all RenderViews for this extension. We do this to restore 888 // Re-register all RenderViews for this extension. We do this to restore
884 // the lazy_keepalive_count (if any) to properly reflect the number of open 889 // the lazy_keepalive_count (if any) to properly reflect the number of open
885 // views. 890 // views.
886 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); 891 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin();
887 it != all_extension_views_.end(); ++it) { 892 it != all_extension_views_.end(); ++it) {
888 if (GetExtensionID(it->first) == extension_id) 893 if (GetExtensionID(it->first) == extension_id)
889 IncrementLazyKeepaliveCountForView(it->first); 894 IncrementLazyKeepaliveCountForView(it->first);
890 } 895 }
891 } 896 }
892 897
893 bool ProcessManager::DeferLoadingBackgroundHosts() const {
894 // The extensions embedder may have special rules about background hosts.
895 return ExtensionsBrowserClient::Get()->DeferLoadingBackgroundHosts(
896 GetBrowserContext());
897 }
898
899 // 898 //
900 // IncognitoProcessManager 899 // IncognitoProcessManager
901 // 900 //
902 901
903 IncognitoProcessManager::IncognitoProcessManager( 902 IncognitoProcessManager::IncognitoProcessManager(
904 BrowserContext* incognito_context, 903 BrowserContext* incognito_context,
905 BrowserContext* original_context, 904 BrowserContext* original_context,
906 ProcessManager* original_manager) 905 ProcessManager* original_manager,
907 : ProcessManager(incognito_context, original_context), 906 ExtensionRegistry* extension_registry)
907 : ProcessManager(incognito_context, original_context, extension_registry),
908 original_manager_(original_manager) { 908 original_manager_(original_manager) {
909 DCHECK(incognito_context->IsOffTheRecord()); 909 DCHECK(incognito_context->IsOffTheRecord());
910 910
911 // The original profile will have its own ProcessManager to 911 // The original profile will have its own ProcessManager to
912 // load the background pages of the spanning extensions. This process 912 // load the background pages of the spanning extensions. This process
913 // manager need only worry about the split mode extensions, which is handled 913 // manager need only worry about the split mode extensions, which is handled
914 // in the NOTIFICATION_BROWSER_WINDOW_READY notification handler. 914 // in the NOTIFICATION_BROWSER_WINDOW_READY notification handler.
915 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY, 915 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY,
916 content::Source<BrowserContext>(original_context)); 916 content::Source<BrowserContext>(original_context));
917 registrar_.Remove(this, chrome::NOTIFICATION_PROFILE_CREATED,
918 content::Source<BrowserContext>(original_context));
919 } 917 }
920 918
921 bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension, 919 bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension,
922 const GURL& url) { 920 const GURL& url) {
923 if (IncognitoInfo::IsSplitMode(extension)) { 921 if (IncognitoInfo::IsSplitMode(extension)) {
924 if (ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled( 922 if (ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled(
925 extension->id(), GetBrowserContext())) 923 extension->id(), GetBrowserContext()))
926 return ProcessManager::CreateBackgroundHost(extension, url); 924 return ProcessManager::CreateBackgroundHost(extension, url);
927 } else { 925 } else {
928 // Do nothing. If an extension is spanning, then its original-profile 926 // Do nothing. If an extension is spanning, then its original-profile
929 // background page is shared with incognito, so we don't create another. 927 // background page is shared with incognito, so we don't create another.
930 } 928 }
931 return false; 929 return false;
932 } 930 }
933 931
934 SiteInstance* IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) { 932 SiteInstance* IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) {
935 ExtensionRegistry* registry = ExtensionRegistry::Get(GetBrowserContext()); 933 const Extension* extension =
936 if (registry) { 934 extension_registry_->enabled_extensions().GetExtensionOrAppByURL(url);
937 const Extension* extension = 935 if (extension && !IncognitoInfo::IsSplitMode(extension))
938 registry->enabled_extensions().GetExtensionOrAppByURL(url); 936 return original_manager_->GetSiteInstanceForURL(url);
939 if (extension && !IncognitoInfo::IsSplitMode(extension)) { 937
940 return original_manager_->GetSiteInstanceForURL(url);
941 }
942 }
943 return ProcessManager::GetSiteInstanceForURL(url); 938 return ProcessManager::GetSiteInstanceForURL(url);
944 } 939 }
945 940
946 } // namespace extensions 941 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698