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

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

Issue 399153002: Revert 283678 "Refactor code that defers extension background pa..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: 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"
37 #include "extensions/browser/process_manager_observer.h" 36 #include "extensions/browser/process_manager_observer.h"
38 #include "extensions/browser/view_type_utils.h" 37 #include "extensions/browser/view_type_utils.h"
39 #include "extensions/common/constants.h" 38 #include "extensions/common/constants.h"
40 #include "extensions/common/extension.h" 39 #include "extensions/common/extension.h"
41 #include "extensions/common/extension_messages.h" 40 #include "extensions/common/extension_messages.h"
42 #include "extensions/common/manifest_handlers/background_info.h" 41 #include "extensions/common/manifest_handlers/background_info.h"
43 #include "extensions/common/manifest_handlers/incognito_info.h" 42 #include "extensions/common/manifest_handlers/incognito_info.h"
44 #include "extensions/common/one_shot_event.h" 43 #include "extensions/common/one_shot_event.h"
45 #include "extensions/common/switches.h" 44 #include "extensions/common/switches.h"
46 45
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, 238 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
240 content::Source<BrowserContext>(original_context)); 239 content::Source<BrowserContext>(original_context));
241 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, 240 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
242 content::Source<BrowserContext>(context)); 241 content::Source<BrowserContext>(context));
243 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, 242 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
244 content::Source<BrowserContext>(context)); 243 content::Source<BrowserContext>(context));
245 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, 244 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
246 content::NotificationService::AllSources()); 245 content::NotificationService::AllSources());
247 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, 246 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
248 content::NotificationService::AllSources()); 247 content::NotificationService::AllSources());
248 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
249 content::Source<BrowserContext>(original_context));
249 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 250 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
250 content::Source<BrowserContext>(context)); 251 content::Source<BrowserContext>(context));
251 if (context->IsOffTheRecord()) { 252 if (context->IsOffTheRecord()) {
252 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 253 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
253 content::Source<BrowserContext>(original_context)); 254 content::Source<BrowserContext>(original_context));
254 } 255 }
255 256
256 // Note: event_page_idle_time_ must be sufficiently larger (e.g. 2x) than 257 // Note: event_page_idle_time_ must be sufficiently larger (e.g. 2x) than
257 // kKeepaliveThrottleIntervalInSeconds in ppapi/proxy/plugin_globals. 258 // kKeepaliveThrottleIntervalInSeconds in ppapi/proxy/plugin_globals.
258 event_page_idle_time_ = base::TimeDelta::FromSeconds(10); 259 event_page_idle_time_ = base::TimeDelta::FromSeconds(10);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 } 300 }
300 301
301 void ProcessManager::RemoveObserver(ProcessManagerObserver* observer) { 302 void ProcessManager::RemoveObserver(ProcessManagerObserver* observer) {
302 observer_list_.RemoveObserver(observer); 303 observer_list_.RemoveObserver(observer);
303 } 304 }
304 305
305 bool ProcessManager::CreateBackgroundHost(const Extension* extension, 306 bool ProcessManager::CreateBackgroundHost(const Extension* extension,
306 const GURL& url) { 307 const GURL& url) {
307 // Hosted apps are taken care of from BackgroundContentsService. Ignore them 308 // Hosted apps are taken care of from BackgroundContentsService. Ignore them
308 // here. 309 // here.
309 if (extension->is_hosted_app()) 310 if (extension->is_hosted_app() ||
311 !ExtensionsBrowserClient::Get()->
312 IsBackgroundPageAllowed(GetBrowserContext())) {
310 return false; 313 return false;
311 314 }
312 // Don't create hosts if the embedder doesn't allow it.
313 ProcessManagerDelegate* delegate =
314 ExtensionsBrowserClient::Get()->GetProcessManagerDelegate();
315 if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext()))
316 return false;
317 315
318 // Don't create multiple background hosts for an extension. 316 // Don't create multiple background hosts for an extension.
319 if (GetBackgroundHostForExtension(extension->id())) 317 if (GetBackgroundHostForExtension(extension->id()))
320 return true; // TODO(kalman): return false here? It might break things... 318 return true; // TODO(kalman): return false here? It might break things...
321 319
322 ExtensionHost* host = 320 ExtensionHost* host =
323 new ExtensionHost(extension, GetSiteInstanceForURL(url), url, 321 new ExtensionHost(extension, GetSiteInstanceForURL(url), url,
324 VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); 322 VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
325 host->CreateRenderViewSoon(); 323 host->CreateRenderViewSoon();
326 OnBackgroundHostCreated(host); 324 OnBackgroundHostCreated(host);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 new ExtensionMsg_CancelSuspend(extension->id())); 613 new ExtensionMsg_CancelSuspend(extension->id()));
616 // This increment / decrement is to simulate an instantaneous event. This 614 // This increment / decrement is to simulate an instantaneous event. This
617 // has the effect of invalidating close_sequence_id, preventing any in 615 // has the effect of invalidating close_sequence_id, preventing any in
618 // progress closes from completing and starting a new close process if 616 // progress closes from completing and starting a new close process if
619 // necessary. 617 // necessary.
620 IncrementLazyKeepaliveCount(extension); 618 IncrementLazyKeepaliveCount(extension);
621 DecrementLazyKeepaliveCount(extension); 619 DecrementLazyKeepaliveCount(extension);
622 } 620 }
623 } 621 }
624 622
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
625 content::BrowserContext* ProcessManager::GetBrowserContext() const { 633 content::BrowserContext* ProcessManager::GetBrowserContext() const {
626 return site_instance_->GetBrowserContext(); 634 return site_instance_->GetBrowserContext();
627 } 635 }
628 636
629 void ProcessManager::SetKeepaliveImpulseCallbackForTesting( 637 void ProcessManager::SetKeepaliveImpulseCallbackForTesting(
630 const ImpulseCallbackForTesting& callback) { 638 const ImpulseCallbackForTesting& callback) {
631 keepalive_impulse_callback_for_testing_ = callback; 639 keepalive_impulse_callback_for_testing_ = callback;
632 } 640 }
633 641
634 void ProcessManager::SetKeepaliveImpulseDecrementCallbackForTesting( 642 void ProcessManager::SetKeepaliveImpulseDecrementCallbackForTesting(
635 const ImpulseCallbackForTesting& callback) { 643 const ImpulseCallbackForTesting& callback) {
636 keepalive_impulse_decrement_callback_for_testing_ = callback; 644 keepalive_impulse_decrement_callback_for_testing_ = callback;
637 } 645 }
638 646
639 void ProcessManager::Observe(int type, 647 void ProcessManager::Observe(int type,
640 const content::NotificationSource& source, 648 const content::NotificationSource& source,
641 const content::NotificationDetails& details) { 649 const content::NotificationDetails& details) {
642 switch (type) { 650 switch (type) {
643 case chrome::NOTIFICATION_EXTENSIONS_READY: { 651 case chrome::NOTIFICATION_EXTENSIONS_READY:
644 // TODO(jamescook): Convert this to use ExtensionSystem::ready() instead 652 case chrome::NOTIFICATION_PROFILE_CREATED: {
645 // of a notification. 653 // Don't load background hosts now if the loading should be deferred.
646 MaybeCreateStartupBackgroundHosts(); 654 // Instead they will be loaded when a browser window for this profile
655 // (or an incognito profile from this profile) is ready.
656 if (DeferLoadingBackgroundHosts())
657 break;
658
659 CreateBackgroundHostsForProfileStartup();
647 break; 660 break;
648 } 661 }
649 662
650 case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: { 663 case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
651 BrowserContext* context = content::Source<BrowserContext>(source).ptr(); 664 BrowserContext* context = content::Source<BrowserContext>(source).ptr();
652 ExtensionSystem* system = ExtensionSystem::Get(context); 665 ExtensionSystem* system = ExtensionSystem::Get(context);
653 if (system->ready().is_signaled()) { 666 if (system->ready().is_signaled()) {
654 // The extension system is ready, so create the background host. 667 // The extension system is ready, so create the background host.
655 const Extension* extension = 668 const Extension* extension =
656 content::Details<const Extension>(details).ptr(); 669 content::Details<const Extension>(details).ptr();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 return; 777 return;
765 if (attached) { 778 if (attached) {
766 // Keep the lazy background page alive while it's being inspected. 779 // Keep the lazy background page alive while it's being inspected.
767 CancelSuspend(extension); 780 CancelSuspend(extension);
768 IncrementLazyKeepaliveCount(extension); 781 IncrementLazyKeepaliveCount(extension);
769 } else { 782 } else {
770 DecrementLazyKeepaliveCount(extension); 783 DecrementLazyKeepaliveCount(extension);
771 } 784 }
772 } 785 }
773 786
774 void ProcessManager::MaybeCreateStartupBackgroundHosts() { 787 void ProcessManager::CreateBackgroundHostsForProfileStartup() {
775 if (startup_background_hosts_created_) 788 if (startup_background_hosts_created_ ||
789 !ExtensionsBrowserClient::Get()->
790 IsBackgroundPageAllowed(GetBrowserContext())) {
776 return; 791 return;
792 }
777 793
778 // The embedder might disallow background pages entirely. 794 const ExtensionSet& enabled_extensions =
779 ProcessManagerDelegate* delegate = 795 ExtensionRegistry::Get(GetBrowserContext())->enabled_extensions();
780 ExtensionsBrowserClient::Get()->GetProcessManagerDelegate(); 796 for (ExtensionSet::const_iterator extension = enabled_extensions.begin();
781 if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext())) 797 extension != enabled_extensions.end();
782 return; 798 ++extension) {
799 CreateBackgroundHostForExtensionLoad(this, extension->get());
783 800
784 // The embedder might want to defer background page loading. For example, 801 FOR_EACH_OBSERVER(ProcessManagerObserver,
785 // Chrome defers background page loading when it is launched to show the app 802 observer_list_,
786 // list, then triggers a load later when a browser window opens. 803 OnBackgroundHostStartup(*extension));
787 if (delegate && 804 }
788 delegate->DeferCreatingStartupBackgroundHosts(GetBrowserContext()))
789 return;
790
791 CreateStartupBackgroundHosts();
792 startup_background_hosts_created_ = true; 805 startup_background_hosts_created_ = true;
793 806
794 // Background pages should only be loaded once. To prevent any further loads 807 // Background pages should only be loaded once. To prevent any further loads
795 // occurring, we remove the notification listeners. 808 // occurring, we remove the notification listeners.
796 BrowserContext* original_context = 809 BrowserContext* original_context =
797 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); 810 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext());
798 if (registrar_.IsRegistered( 811 if (registrar_.IsRegistered(
799 this, 812 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,
800 chrome::NOTIFICATION_EXTENSIONS_READY, 821 chrome::NOTIFICATION_EXTENSIONS_READY,
801 content::Source<BrowserContext>(original_context))) { 822 content::Source<BrowserContext>(original_context))) {
802 registrar_.Remove(this, 823 registrar_.Remove(this,
803 chrome::NOTIFICATION_EXTENSIONS_READY, 824 chrome::NOTIFICATION_EXTENSIONS_READY,
804 content::Source<BrowserContext>(original_context)); 825 content::Source<BrowserContext>(original_context));
805 } 826 }
806 } 827 }
807 828
808 void ProcessManager::CreateStartupBackgroundHosts() {
809 DCHECK(!startup_background_hosts_created_);
810 const ExtensionSet& enabled_extensions =
811 ExtensionRegistry::Get(GetBrowserContext())->enabled_extensions();
812 for (ExtensionSet::const_iterator extension = enabled_extensions.begin();
813 extension != enabled_extensions.end();
814 ++extension) {
815 CreateBackgroundHostForExtensionLoad(this, extension->get());
816
817 FOR_EACH_OBSERVER(ProcessManagerObserver,
818 observer_list_,
819 OnBackgroundHostStartup(*extension));
820 }
821 }
822
823 void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) { 829 void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) {
824 DCHECK_EQ(GetBrowserContext(), host->browser_context()); 830 DCHECK_EQ(GetBrowserContext(), host->browser_context());
825 background_hosts_.insert(host); 831 background_hosts_.insert(host);
826 832
827 if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) { 833 if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) {
828 linked_ptr<base::ElapsedTimer> since_suspended( 834 linked_ptr<base::ElapsedTimer> since_suspended(
829 background_page_data_[host->extension()->id()]. 835 background_page_data_[host->extension()->id()].
830 since_suspended.release()); 836 since_suspended.release());
831 if (since_suspended.get()) { 837 if (since_suspended.get()) {
832 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageIdleTime", 838 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageIdleTime",
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 // Re-register all RenderViews for this extension. We do this to restore 883 // Re-register all RenderViews for this extension. We do this to restore
878 // the lazy_keepalive_count (if any) to properly reflect the number of open 884 // the lazy_keepalive_count (if any) to properly reflect the number of open
879 // views. 885 // views.
880 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); 886 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin();
881 it != all_extension_views_.end(); ++it) { 887 it != all_extension_views_.end(); ++it) {
882 if (GetExtensionID(it->first) == extension_id) 888 if (GetExtensionID(it->first) == extension_id)
883 IncrementLazyKeepaliveCountForView(it->first); 889 IncrementLazyKeepaliveCountForView(it->first);
884 } 890 }
885 } 891 }
886 892
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
887 // 899 //
888 // IncognitoProcessManager 900 // IncognitoProcessManager
889 // 901 //
890 902
891 IncognitoProcessManager::IncognitoProcessManager( 903 IncognitoProcessManager::IncognitoProcessManager(
892 BrowserContext* incognito_context, 904 BrowserContext* incognito_context,
893 BrowserContext* original_context, 905 BrowserContext* original_context,
894 ProcessManager* original_manager) 906 ProcessManager* original_manager)
895 : ProcessManager(incognito_context, original_context), 907 : ProcessManager(incognito_context, original_context),
896 original_manager_(original_manager) { 908 original_manager_(original_manager) {
897 DCHECK(incognito_context->IsOffTheRecord()); 909 DCHECK(incognito_context->IsOffTheRecord());
898 910
899 // The original profile will have its own ProcessManager to 911 // The original profile will have its own ProcessManager to
900 // load the background pages of the spanning extensions. This process 912 // load the background pages of the spanning extensions. This process
901 // 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
902 // in the NOTIFICATION_BROWSER_WINDOW_READY notification handler. 914 // in the NOTIFICATION_BROWSER_WINDOW_READY notification handler.
903 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY, 915 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY,
904 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));
905 } 919 }
906 920
907 bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension, 921 bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension,
908 const GURL& url) { 922 const GURL& url) {
909 if (IncognitoInfo::IsSplitMode(extension)) { 923 if (IncognitoInfo::IsSplitMode(extension)) {
910 if (ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled( 924 if (ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled(
911 extension->id(), GetBrowserContext())) 925 extension->id(), GetBrowserContext()))
912 return ProcessManager::CreateBackgroundHost(extension, url); 926 return ProcessManager::CreateBackgroundHost(extension, url);
913 } else { 927 } else {
914 // Do nothing. If an extension is spanning, then its original-profile 928 // Do nothing. If an extension is spanning, then its original-profile
915 // background page is shared with incognito, so we don't create another. 929 // background page is shared with incognito, so we don't create another.
916 } 930 }
917 return false; 931 return false;
918 } 932 }
919 933
920 SiteInstance* IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) { 934 SiteInstance* IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) {
921 ExtensionRegistry* registry = ExtensionRegistry::Get(GetBrowserContext()); 935 ExtensionRegistry* registry = ExtensionRegistry::Get(GetBrowserContext());
922 if (registry) { 936 if (registry) {
923 const Extension* extension = 937 const Extension* extension =
924 registry->enabled_extensions().GetExtensionOrAppByURL(url); 938 registry->enabled_extensions().GetExtensionOrAppByURL(url);
925 if (extension && !IncognitoInfo::IsSplitMode(extension)) { 939 if (extension && !IncognitoInfo::IsSplitMode(extension)) {
926 return original_manager_->GetSiteInstanceForURL(url); 940 return original_manager_->GetSiteInstanceForURL(url);
927 } 941 }
928 } 942 }
929 return ProcessManager::GetSiteInstanceForURL(url); 943 return ProcessManager::GetSiteInstanceForURL(url);
930 } 944 }
931 945
932 } // namespace extensions 946 } // namespace extensions
OLDNEW
« no previous file with comments | « trunk/src/extensions/browser/process_manager.h ('k') | trunk/src/extensions/browser/process_manager_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698