| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/extensions/extension_process_manager.h" | 5 #include "chrome/browser/extensions/extension_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" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 16 #include "chrome/browser/chrome_notification_types.h" | 16 #include "chrome/browser/chrome_notification_types.h" |
| 17 #include "chrome/browser/extensions/api/runtime/runtime_api.h" | 17 #include "chrome/browser/extensions/api/runtime/runtime_api.h" |
| 18 #include "chrome/browser/extensions/extension_host.h" | 18 #include "chrome/browser/extensions/extension_host.h" |
| 19 #include "chrome/browser/extensions/extension_info_map.h" | 19 #include "chrome/browser/extensions/extension_info_map.h" |
| 20 #include "chrome/browser/extensions/extension_service.h" | 20 #include "chrome/browser/extensions/extension_service.h" |
| 21 #include "chrome/browser/extensions/extension_system.h" | 21 #include "chrome/browser/extensions/extension_system.h" |
| 22 #include "chrome/browser/extensions/extension_util.h" | 22 #include "chrome/browser/extensions/extension_util.h" |
| 23 #include "chrome/browser/profiles/profile.h" | |
| 24 #include "chrome/browser/ui/browser.h" | 23 #include "chrome/browser/ui/browser.h" |
| 25 #include "chrome/common/extensions/background_info.h" | 24 #include "chrome/common/extensions/background_info.h" |
| 26 #include "chrome/common/extensions/extension.h" | 25 #include "chrome/common/extensions/extension.h" |
| 27 #include "chrome/common/extensions/extension_messages.h" | 26 #include "chrome/common/extensions/extension_messages.h" |
| 28 #include "chrome/common/extensions/incognito_handler.h" | 27 #include "chrome/common/extensions/incognito_handler.h" |
| 29 #include "chrome/common/extensions/manifest_url_handler.h" | 28 #include "chrome/common/extensions/manifest_url_handler.h" |
| 30 #include "chrome/common/url_constants.h" | 29 #include "chrome/common/url_constants.h" |
| 31 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
| 32 #include "content/public/browser/devtools_agent_host.h" | 31 #include "content/public/browser/devtools_agent_host.h" |
| 33 #include "content/public/browser/devtools_manager.h" | 32 #include "content/public/browser/devtools_manager.h" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 virtual ExtensionHost* CreateViewHost( | 91 virtual ExtensionHost* CreateViewHost( |
| 93 const Extension* extension, | 92 const Extension* extension, |
| 94 const GURL& url, | 93 const GURL& url, |
| 95 Browser* browser, | 94 Browser* browser, |
| 96 extensions::ViewType view_type) OVERRIDE; | 95 extensions::ViewType view_type) OVERRIDE; |
| 97 virtual ExtensionHost* CreateBackgroundHost(const Extension* extension, | 96 virtual ExtensionHost* CreateBackgroundHost(const Extension* extension, |
| 98 const GURL& url) OVERRIDE; | 97 const GURL& url) OVERRIDE; |
| 99 virtual SiteInstance* GetSiteInstanceForURL(const GURL& url) OVERRIDE; | 98 virtual SiteInstance* GetSiteInstanceForURL(const GURL& url) OVERRIDE; |
| 100 | 99 |
| 101 private: | 100 private: |
| 102 // content::NotificationObserver: | |
| 103 virtual void Observe(int type, | |
| 104 const content::NotificationSource& source, | |
| 105 const content::NotificationDetails& details) OVERRIDE; | |
| 106 | |
| 107 // Returns true if the extension is allowed to run in incognito mode. | 101 // Returns true if the extension is allowed to run in incognito mode. |
| 108 bool IsIncognitoEnabled(const Extension* extension); | 102 bool IsIncognitoEnabled(const Extension* extension); |
| 109 | 103 |
| 110 ExtensionProcessManager* original_manager_; | 104 ExtensionProcessManager* original_manager_; |
| 105 |
| 106 DISALLOW_COPY_AND_ASSIGN(IncognitoExtensionProcessManager); |
| 111 }; | 107 }; |
| 112 | 108 |
| 113 static void CreateBackgroundHostForExtensionLoad( | 109 static void CreateBackgroundHostForExtensionLoad( |
| 114 ExtensionProcessManager* manager, const Extension* extension) { | 110 ExtensionProcessManager* manager, const Extension* extension) { |
| 115 DVLOG(1) << "CreateBackgroundHostForExtensionLoad"; | 111 DVLOG(1) << "CreateBackgroundHostForExtensionLoad"; |
| 116 if (BackgroundInfo::HasPersistentBackgroundPage(extension)) | 112 if (BackgroundInfo::HasPersistentBackgroundPage(extension)) |
| 117 manager->CreateBackgroundHost(extension, | 113 manager->CreateBackgroundHost(extension, |
| 118 BackgroundInfo::GetBackgroundURL(extension)); | 114 BackgroundInfo::GetBackgroundURL(extension)); |
| 119 } | 115 } |
| 120 | 116 |
| 121 } // namespace | 117 } // namespace |
| 122 | 118 |
| 123 class RenderViewHostDestructionObserver | 119 class RenderViewHostDestructionObserver |
| 124 : public content::WebContentsObserver, | 120 : public content::WebContentsObserver, |
| 125 public content::WebContentsUserData<RenderViewHostDestructionObserver> { | 121 public content::WebContentsUserData<RenderViewHostDestructionObserver> { |
| 126 public: | 122 public: |
| 127 virtual ~RenderViewHostDestructionObserver() {} | 123 virtual ~RenderViewHostDestructionObserver() {} |
| 128 | 124 |
| 129 private: | 125 private: |
| 130 explicit RenderViewHostDestructionObserver(WebContents* web_contents) | 126 explicit RenderViewHostDestructionObserver(WebContents* web_contents) |
| 131 : WebContentsObserver(web_contents) { | 127 : WebContentsObserver(web_contents) { |
| 132 Profile* profile = | 128 BrowserContext* context = web_contents->GetBrowserContext(); |
| 133 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | |
| 134 process_manager_ = | 129 process_manager_ = |
| 135 extensions::ExtensionSystem::Get(profile)->process_manager(); | 130 ExtensionSystem::GetForBrowserContext(context)->process_manager(); |
| 136 } | 131 } |
| 137 | 132 |
| 138 friend class content::WebContentsUserData<RenderViewHostDestructionObserver>; | 133 friend class content::WebContentsUserData<RenderViewHostDestructionObserver>; |
| 139 | 134 |
| 140 // content::WebContentsObserver overrides. | 135 // content::WebContentsObserver overrides. |
| 141 virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE { | 136 virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE { |
| 142 process_manager_->UnregisterRenderViewHost(render_view_host); | 137 process_manager_->UnregisterRenderViewHost(render_view_host); |
| 143 } | 138 } |
| 144 | 139 |
| 145 ExtensionProcessManager* process_manager_; | 140 ExtensionProcessManager* process_manager_; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 return new IncognitoExtensionProcessManager(context, original_context); | 176 return new IncognitoExtensionProcessManager(context, original_context); |
| 182 } | 177 } |
| 183 return new ExtensionProcessManager(context, context); | 178 return new ExtensionProcessManager(context, context); |
| 184 } | 179 } |
| 185 | 180 |
| 186 ExtensionProcessManager::ExtensionProcessManager( | 181 ExtensionProcessManager::ExtensionProcessManager( |
| 187 BrowserContext* context, | 182 BrowserContext* context, |
| 188 BrowserContext* original_context) | 183 BrowserContext* original_context) |
| 189 : site_instance_(SiteInstance::Create(context)), | 184 : site_instance_(SiteInstance::Create(context)), |
| 190 defer_background_host_creation_(false), | 185 defer_background_host_creation_(false), |
| 186 startup_background_hosts_created_(false), |
| 191 devtools_callback_(base::Bind( | 187 devtools_callback_(base::Bind( |
| 192 &ExtensionProcessManager::OnDevToolsStateChanged, | 188 &ExtensionProcessManager::OnDevToolsStateChanged, |
| 193 base::Unretained(this))), | 189 base::Unretained(this))), |
| 194 weak_ptr_factory_(this) { | 190 weak_ptr_factory_(this) { |
| 195 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, | |
| 196 content::NotificationService::AllSources()); | |
| 197 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, | 191 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
| 198 content::Source<BrowserContext>(original_context)); | 192 content::Source<BrowserContext>(original_context)); |
| 199 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 193 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| 200 content::Source<BrowserContext>(original_context)); | 194 content::Source<BrowserContext>(original_context)); |
| 201 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 195 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 202 content::Source<BrowserContext>(original_context)); | 196 content::Source<BrowserContext>(original_context)); |
| 203 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 197 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
| 204 content::Source<BrowserContext>(context)); | 198 content::Source<BrowserContext>(context)); |
| 205 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, | 199 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, |
| 206 content::Source<BrowserContext>(context)); | 200 content::Source<BrowserContext>(context)); |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 void ExtensionProcessManager::DeferBackgroundHostCreation(bool defer) { | 589 void ExtensionProcessManager::DeferBackgroundHostCreation(bool defer) { |
| 596 bool previous = defer_background_host_creation_; | 590 bool previous = defer_background_host_creation_; |
| 597 defer_background_host_creation_ = defer; | 591 defer_background_host_creation_ = defer; |
| 598 | 592 |
| 599 // If we were deferred, and we switch to non-deferred, then create the | 593 // If we were deferred, and we switch to non-deferred, then create the |
| 600 // background hosts. | 594 // background hosts. |
| 601 if (previous && !defer_background_host_creation_) | 595 if (previous && !defer_background_host_creation_) |
| 602 CreateBackgroundHostsForProfileStartup(); | 596 CreateBackgroundHostsForProfileStartup(); |
| 603 } | 597 } |
| 604 | 598 |
| 599 void ExtensionProcessManager::OnBrowserWindowReady() { |
| 600 ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| 601 GetBrowserContext())->extension_service(); |
| 602 // On Chrome OS, a login screen is implemented as a browser. |
| 603 // This browser has no extension service. In this case, |
| 604 // service will be NULL. |
| 605 if (!service || !service->is_ready()) |
| 606 return; |
| 607 |
| 608 CreateBackgroundHostsForProfileStartup(); |
| 609 } |
| 610 |
| 611 content::BrowserContext* ExtensionProcessManager::GetBrowserContext() const { |
| 612 return site_instance_->GetBrowserContext(); |
| 613 } |
| 614 |
| 605 void ExtensionProcessManager::Observe( | 615 void ExtensionProcessManager::Observe( |
| 606 int type, | 616 int type, |
| 607 const content::NotificationSource& source, | 617 const content::NotificationSource& source, |
| 608 const content::NotificationDetails& details) { | 618 const content::NotificationDetails& details) { |
| 609 switch (type) { | 619 switch (type) { |
| 610 case chrome::NOTIFICATION_BROWSER_WINDOW_READY: { | |
| 611 // If a window for this profile, or this profile's incognito profile, | |
| 612 // has been opened, make sure this profile's background hosts have | |
| 613 // been loaded. | |
| 614 Browser* browser = content::Source<Browser>(source).ptr(); | |
| 615 if (browser->profile() != GetProfile() && | |
| 616 !(GetProfile()->HasOffTheRecordProfile() && | |
| 617 browser->profile() == GetProfile()->GetOffTheRecordProfile())) | |
| 618 break; | |
| 619 | |
| 620 ExtensionService* service = ExtensionSystem::GetForBrowserContext( | |
| 621 GetBrowserContext())->extension_service(); | |
| 622 if (!service || !service->is_ready()) | |
| 623 break; | |
| 624 | |
| 625 CreateBackgroundHostsForProfileStartup(); | |
| 626 break; | |
| 627 } | |
| 628 case chrome::NOTIFICATION_EXTENSIONS_READY: | 620 case chrome::NOTIFICATION_EXTENSIONS_READY: |
| 629 case chrome::NOTIFICATION_PROFILE_CREATED: { | 621 case chrome::NOTIFICATION_PROFILE_CREATED: { |
| 630 CreateBackgroundHostsForProfileStartup(); | 622 CreateBackgroundHostsForProfileStartup(); |
| 631 break; | 623 break; |
| 632 } | 624 } |
| 633 | 625 |
| 634 case chrome::NOTIFICATION_EXTENSION_LOADED: { | 626 case chrome::NOTIFICATION_EXTENSION_LOADED: { |
| 635 Profile* profile = content::Source<Profile>(source).ptr(); | 627 BrowserContext* context = content::Source<BrowserContext>(source).ptr(); |
| 636 ExtensionService* service = | 628 ExtensionService* service = |
| 637 extensions::ExtensionSystem::Get(profile)->extension_service(); | 629 ExtensionSystem::GetForBrowserContext(context)->extension_service(); |
| 638 if (service->is_ready()) { | 630 if (service->is_ready()) { |
| 639 const Extension* extension = | 631 const Extension* extension = |
| 640 content::Details<const Extension>(details).ptr(); | 632 content::Details<const Extension>(details).ptr(); |
| 641 CreateBackgroundHostForExtensionLoad(this, extension); | 633 CreateBackgroundHostForExtensionLoad(this, extension); |
| 642 } | 634 } |
| 643 break; | 635 break; |
| 644 } | 636 } |
| 645 | 637 |
| 646 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | 638 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
| 647 const Extension* extension = | 639 const Extension* extension = |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 if (attached) { | 741 if (attached) { |
| 750 // Keep the lazy background page alive while it's being inspected. | 742 // Keep the lazy background page alive while it's being inspected. |
| 751 CancelSuspend(extension); | 743 CancelSuspend(extension); |
| 752 IncrementLazyKeepaliveCount(extension); | 744 IncrementLazyKeepaliveCount(extension); |
| 753 } else { | 745 } else { |
| 754 DecrementLazyKeepaliveCount(extension); | 746 DecrementLazyKeepaliveCount(extension); |
| 755 } | 747 } |
| 756 } | 748 } |
| 757 | 749 |
| 758 void ExtensionProcessManager::CreateBackgroundHostsForProfileStartup() { | 750 void ExtensionProcessManager::CreateBackgroundHostsForProfileStartup() { |
| 759 DVLOG(1) << "CreateBackgroundHostsForProfileStartup"; | 751 if (startup_background_hosts_created_) |
| 752 return; |
| 753 |
| 760 // Don't load background hosts now if the loading should be deferred. | 754 // Don't load background hosts now if the loading should be deferred. |
| 761 // Instead they will be loaded when a browser window for this profile | 755 // Instead they will be loaded when a browser window for this profile |
| 762 // (or an incognito profile from this profile) is ready, or when | 756 // (or an incognito profile from this profile) is ready, or when |
| 763 // DeferBackgroundHostCreation is called with false. | 757 // DeferBackgroundHostCreation is called with false. |
| 764 if (DeferLoadingBackgroundHosts()) | 758 if (DeferLoadingBackgroundHosts()) |
| 765 return; | 759 return; |
| 766 | 760 |
| 767 ExtensionService* service = ExtensionSystem::GetForBrowserContext( | 761 ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| 768 GetBrowserContext())->extension_service(); | 762 GetBrowserContext())->extension_service(); |
| 769 DCHECK(service); | 763 DCHECK(service); |
| 770 for (ExtensionSet::const_iterator extension = service->extensions()->begin(); | 764 for (ExtensionSet::const_iterator extension = service->extensions()->begin(); |
| 771 extension != service->extensions()->end(); ++extension) { | 765 extension != service->extensions()->end(); ++extension) { |
| 772 CreateBackgroundHostForExtensionLoad(this, extension->get()); | 766 CreateBackgroundHostForExtensionLoad(this, extension->get()); |
| 773 | 767 |
| 774 extensions::RuntimeEventRouter::DispatchOnStartupEvent( | 768 extensions::RuntimeEventRouter::DispatchOnStartupEvent( |
| 775 GetBrowserContext(), (*extension)->id()); | 769 GetBrowserContext(), (*extension)->id()); |
| 776 } | 770 } |
| 771 startup_background_hosts_created_ = true; |
| 777 | 772 |
| 778 // Background pages should only be loaded once. To prevent any further loads | 773 // Background pages should only be loaded once. To prevent any further loads |
| 779 // occurring, we remove the notification listeners. | 774 // occurring, we remove the notification listeners. |
| 780 BrowserContext* original_context = | 775 BrowserContext* original_context = |
| 781 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); | 776 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); |
| 782 registrar_.Remove(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY, | |
| 783 content::NotificationService::AllSources()); | |
| 784 if (registrar_.IsRegistered( | 777 if (registrar_.IsRegistered( |
| 785 this, | 778 this, |
| 786 chrome::NOTIFICATION_PROFILE_CREATED, | 779 chrome::NOTIFICATION_PROFILE_CREATED, |
| 787 content::Source<BrowserContext>(original_context))) { | 780 content::Source<BrowserContext>(original_context))) { |
| 788 registrar_.Remove(this, | 781 registrar_.Remove(this, |
| 789 chrome::NOTIFICATION_PROFILE_CREATED, | 782 chrome::NOTIFICATION_PROFILE_CREATED, |
| 790 content::Source<BrowserContext>(original_context)); | 783 content::Source<BrowserContext>(original_context)); |
| 791 } | 784 } |
| 792 if (registrar_.IsRegistered( | 785 if (registrar_.IsRegistered( |
| 793 this, | 786 this, |
| 794 chrome::NOTIFICATION_EXTENSIONS_READY, | 787 chrome::NOTIFICATION_EXTENSIONS_READY, |
| 795 content::Source<BrowserContext>(original_context))) { | 788 content::Source<BrowserContext>(original_context))) { |
| 796 registrar_.Remove(this, | 789 registrar_.Remove(this, |
| 797 chrome::NOTIFICATION_EXTENSIONS_READY, | 790 chrome::NOTIFICATION_EXTENSIONS_READY, |
| 798 content::Source<BrowserContext>(original_context)); | 791 content::Source<BrowserContext>(original_context)); |
| 799 } | 792 } |
| 800 } | 793 } |
| 801 | 794 |
| 802 Profile* ExtensionProcessManager::GetProfile() const { | |
| 803 return Profile::FromBrowserContext(site_instance_->GetBrowserContext()); | |
| 804 } | |
| 805 | |
| 806 content::BrowserContext* ExtensionProcessManager::GetBrowserContext() const { | |
| 807 return site_instance_->GetBrowserContext(); | |
| 808 } | |
| 809 | |
| 810 void ExtensionProcessManager::OnExtensionHostCreated(ExtensionHost* host, | 795 void ExtensionProcessManager::OnExtensionHostCreated(ExtensionHost* host, |
| 811 bool is_background) { | 796 bool is_background) { |
| 812 DCHECK_EQ(site_instance_->GetBrowserContext(), host->browser_context()); | 797 DCHECK_EQ(site_instance_->GetBrowserContext(), host->browser_context()); |
| 813 if (is_background) { | 798 if (is_background) { |
| 814 background_hosts_.insert(host); | 799 background_hosts_.insert(host); |
| 815 | 800 |
| 816 if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) { | 801 if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) { |
| 817 linked_ptr<base::ElapsedTimer> since_suspended( | 802 linked_ptr<base::ElapsedTimer> since_suspended( |
| 818 background_page_data_[host->extension()->id()]. | 803 background_page_data_[host->extension()->id()]. |
| 819 since_suspended.release()); | 804 since_suspended.release()); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 return ExtensionProcessManager::GetSiteInstanceForURL(url); | 950 return ExtensionProcessManager::GetSiteInstanceForURL(url); |
| 966 } | 951 } |
| 967 | 952 |
| 968 bool IncognitoExtensionProcessManager::IsIncognitoEnabled( | 953 bool IncognitoExtensionProcessManager::IsIncognitoEnabled( |
| 969 const Extension* extension) { | 954 const Extension* extension) { |
| 970 // Keep in sync with duplicate in extension_info_map.cc. | 955 // Keep in sync with duplicate in extension_info_map.cc. |
| 971 ExtensionService* service = ExtensionSystem::GetForBrowserContext( | 956 ExtensionService* service = ExtensionSystem::GetForBrowserContext( |
| 972 GetBrowserContext())->extension_service(); | 957 GetBrowserContext())->extension_service(); |
| 973 return extension_util::IsIncognitoEnabled(extension->id(), service); | 958 return extension_util::IsIncognitoEnabled(extension->id(), service); |
| 974 } | 959 } |
| 975 | |
| 976 void IncognitoExtensionProcessManager::Observe( | |
| 977 int type, | |
| 978 const content::NotificationSource& source, | |
| 979 const content::NotificationDetails& details) { | |
| 980 switch (type) { | |
| 981 // Do not use ExtensionProcessManager's handler for | |
| 982 // NOTIFICATION_BROWSER_WINDOW_READY. | |
| 983 case chrome::NOTIFICATION_BROWSER_WINDOW_READY: { | |
| 984 // We want to spawn our background hosts as soon as the user opens an | |
| 985 // incognito window. Watch for new browsers and create the hosts if | |
| 986 // it matches our profile. | |
| 987 Browser* browser = content::Source<Browser>(source).ptr(); | |
| 988 if (browser->profile() == site_instance_->GetBrowserContext()) { | |
| 989 // On Chrome OS, a login screen is implemented as a browser. | |
| 990 // This browser has no extension service. In this case, | |
| 991 // service will be NULL. | |
| 992 ExtensionService* service = ExtensionSystem::GetForBrowserContext( | |
| 993 GetBrowserContext())->extension_service(); | |
| 994 if (service && service->is_ready()) | |
| 995 CreateBackgroundHostsForProfileStartup(); | |
| 996 } | |
| 997 break; | |
| 998 } | |
| 999 default: | |
| 1000 ExtensionProcessManager::Observe(type, source, details); | |
| 1001 break; | |
| 1002 } | |
| 1003 } | |
| OLD | NEW |