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/event_router.h" | 5 #include "chrome/browser/extensions/event_router.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "base/values.h" | 13 #include "base/values.h" |
14 #include "base/version.h" | |
15 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
16 #include "chrome/browser/extensions/activity_log/activity_log.h" | 15 #include "chrome/browser/extensions/activity_log/activity_log.h" |
17 #include "chrome/browser/extensions/api/runtime/runtime_api.h" | |
18 #include "chrome/browser/extensions/api/web_request/web_request_api.h" | 16 #include "chrome/browser/extensions/api/web_request/web_request_api.h" |
19 #include "chrome/browser/extensions/extension_host.h" | 17 #include "chrome/browser/extensions/extension_host.h" |
20 #include "chrome/browser/extensions/extension_prefs.h" | 18 #include "chrome/browser/extensions/extension_prefs.h" |
21 #include "chrome/browser/extensions/extension_service.h" | 19 #include "chrome/browser/extensions/extension_service.h" |
22 #include "chrome/browser/extensions/extension_system.h" | 20 #include "chrome/browser/extensions/extension_system.h" |
23 #include "chrome/browser/extensions/extension_util.h" | 21 #include "chrome/browser/extensions/extension_util.h" |
24 #include "chrome/common/extensions/extension.h" | 22 #include "chrome/common/extensions/extension.h" |
25 #include "chrome/common/extensions/extension_messages.h" | 23 #include "chrome/common/extensions/extension_messages.h" |
26 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
27 #include "content/public/browser/render_process_host.h" | 25 #include "content/public/browser/render_process_host.h" |
(...skipping 16 matching lines...) Expand all Loading... |
44 namespace { | 42 namespace { |
45 | 43 |
46 void NotifyEventListenerRemovedOnIOThread( | 44 void NotifyEventListenerRemovedOnIOThread( |
47 void* browser_context, | 45 void* browser_context, |
48 const std::string& extension_id, | 46 const std::string& extension_id, |
49 const std::string& sub_event_name) { | 47 const std::string& sub_event_name) { |
50 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | 48 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
51 browser_context, extension_id, sub_event_name); | 49 browser_context, extension_id, sub_event_name); |
52 } | 50 } |
53 | 51 |
54 // TODO(jamescook): Move this to RuntimeEventRouter. | |
55 void DispatchOnInstalledEvent( | |
56 BrowserContext* browser_context, | |
57 const std::string& extension_id, | |
58 const Version& old_version, | |
59 bool chrome_updated) { | |
60 if (!ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) | |
61 return; | |
62 | |
63 RuntimeEventRouter::DispatchOnInstalledEvent(browser_context, extension_id, | |
64 old_version, chrome_updated); | |
65 } | |
66 | |
67 void DoNothing(ExtensionHost* host) {} | 52 void DoNothing(ExtensionHost* host) {} |
68 | 53 |
69 // A dictionary of event names to lists of filters that this extension has | 54 // A dictionary of event names to lists of filters that this extension has |
70 // registered from its lazy background page. | 55 // registered from its lazy background page. |
71 const char kFilteredEvents[] = "filtered_events"; | 56 const char kFilteredEvents[] = "filtered_events"; |
72 | 57 |
73 } // namespace | 58 } // namespace |
74 | 59 |
75 const char EventRouter::kRegisteredEvents[] = "events"; | 60 const char EventRouter::kRegisteredEvents[] = "events"; |
76 | 61 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 FROM_HERE, | 152 FROM_HERE, |
168 base::Bind(&EventRouter::IncrementInFlightEventsOnUI, | 153 base::Bind(&EventRouter::IncrementInFlightEventsOnUI, |
169 browser_context_id, | 154 browser_context_id, |
170 extension_id)); | 155 extension_id)); |
171 } | 156 } |
172 | 157 |
173 EventRouter::EventRouter(BrowserContext* browser_context, | 158 EventRouter::EventRouter(BrowserContext* browser_context, |
174 ExtensionPrefs* extension_prefs) | 159 ExtensionPrefs* extension_prefs) |
175 : browser_context_(browser_context), | 160 : browser_context_(browser_context), |
176 extension_prefs_(extension_prefs), | 161 extension_prefs_(extension_prefs), |
177 listeners_(this), | 162 listeners_(this) { |
178 dispatch_chrome_updated_event_(false) { | |
179 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 163 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
180 content::NotificationService::AllSources()); | 164 content::NotificationService::AllSources()); |
181 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 165 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
182 content::NotificationService::AllSources()); | 166 content::NotificationService::AllSources()); |
183 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, | |
184 content::Source<BrowserContext>(browser_context_)); | |
185 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_ENABLED, | 167 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_ENABLED, |
186 content::Source<BrowserContext>(browser_context_)); | 168 content::Source<BrowserContext>(browser_context_)); |
187 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 169 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
188 content::Source<BrowserContext>(browser_context_)); | 170 content::Source<BrowserContext>(browser_context_)); |
189 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 171 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
190 content::Source<BrowserContext>(browser_context_)); | 172 content::Source<BrowserContext>(browser_context_)); |
191 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, | |
192 content::Source<BrowserContext>(browser_context_)); | |
193 | |
194 // Check if registered events are up-to-date. We can only do this once | |
195 // per browser context, since it updates internal state when called. | |
196 dispatch_chrome_updated_event_ = | |
197 ExtensionsBrowserClient::Get()->DidVersionUpdate(extension_prefs_); | |
198 } | 173 } |
199 | 174 |
200 EventRouter::~EventRouter() {} | 175 EventRouter::~EventRouter() {} |
201 | 176 |
202 void EventRouter::AddEventListener(const std::string& event_name, | 177 void EventRouter::AddEventListener(const std::string& event_name, |
203 content::RenderProcessHost* process, | 178 content::RenderProcessHost* process, |
204 const std::string& extension_id) { | 179 const std::string& extension_id) { |
205 listeners_.AddListener(scoped_ptr<EventListener>(new EventListener( | 180 listeners_.AddListener(scoped_ptr<EventListener>(new EventListener( |
206 event_name, extension_id, process, scoped_ptr<DictionaryValue>()))); | 181 event_name, extension_id, process, scoped_ptr<DictionaryValue>()))); |
207 } | 182 } |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 const content::NotificationDetails& details) { | 690 const content::NotificationDetails& details) { |
716 switch (type) { | 691 switch (type) { |
717 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | 692 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
718 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | 693 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
719 content::RenderProcessHost* renderer = | 694 content::RenderProcessHost* renderer = |
720 content::Source<content::RenderProcessHost>(source).ptr(); | 695 content::Source<content::RenderProcessHost>(source).ptr(); |
721 // Remove all event listeners associated with this renderer. | 696 // Remove all event listeners associated with this renderer. |
722 listeners_.RemoveListenersForProcess(renderer); | 697 listeners_.RemoveListenersForProcess(renderer); |
723 break; | 698 break; |
724 } | 699 } |
725 case chrome::NOTIFICATION_EXTENSIONS_READY: { | |
726 // We're done restarting Chrome after an update. | |
727 dispatch_chrome_updated_event_ = false; | |
728 break; | |
729 } | |
730 case chrome::NOTIFICATION_EXTENSION_ENABLED: { | 700 case chrome::NOTIFICATION_EXTENSION_ENABLED: { |
731 // If the extension has a lazy background page, make sure it gets loaded | 701 // If the extension has a lazy background page, make sure it gets loaded |
732 // to register the events the extension is interested in. | 702 // to register the events the extension is interested in. |
733 const Extension* extension = | 703 const Extension* extension = |
734 content::Details<const Extension>(details).ptr(); | 704 content::Details<const Extension>(details).ptr(); |
735 if (BackgroundInfo::HasLazyBackgroundPage(extension)) { | 705 if (BackgroundInfo::HasLazyBackgroundPage(extension)) { |
736 LazyBackgroundTaskQueue* queue = ExtensionSystem::GetForBrowserContext( | 706 LazyBackgroundTaskQueue* queue = ExtensionSystem::GetForBrowserContext( |
737 browser_context_)->lazy_background_task_queue(); | 707 browser_context_)->lazy_background_task_queue(); |
738 queue->AddPendingTask(browser_context_, extension->id(), | 708 queue->AddPendingTask(browser_context_, extension->id(), |
739 base::Bind(&DoNothing)); | 709 base::Bind(&DoNothing)); |
740 } | 710 } |
741 break; | 711 break; |
742 } | 712 } |
743 case chrome::NOTIFICATION_EXTENSION_LOADED: { | 713 case chrome::NOTIFICATION_EXTENSION_LOADED: { |
744 // Add all registered lazy listeners to our cache. | 714 // Add all registered lazy listeners to our cache. |
745 const Extension* extension = | 715 const Extension* extension = |
746 content::Details<const Extension>(details).ptr(); | 716 content::Details<const Extension>(details).ptr(); |
747 std::set<std::string> registered_events = | 717 std::set<std::string> registered_events = |
748 GetRegisteredEvents(extension->id()); | 718 GetRegisteredEvents(extension->id()); |
749 listeners_.LoadUnfilteredLazyListeners(extension->id(), | 719 listeners_.LoadUnfilteredLazyListeners(extension->id(), |
750 registered_events); | 720 registered_events); |
751 const DictionaryValue* filtered_events = | 721 const DictionaryValue* filtered_events = |
752 GetFilteredEvents(extension->id()); | 722 GetFilteredEvents(extension->id()); |
753 if (filtered_events) | 723 if (filtered_events) |
754 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); | 724 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); |
755 | |
756 if (dispatch_chrome_updated_event_) { | |
757 base::MessageLoop::current()->PostTask( | |
758 FROM_HERE, | |
759 base::Bind(&DispatchOnInstalledEvent, | |
760 browser_context_, | |
761 extension->id(), | |
762 Version(), | |
763 true)); | |
764 } | |
765 break; | 725 break; |
766 } | 726 } |
767 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | 727 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
768 // Remove all registered lazy listeners from our cache. | 728 // Remove all registered lazy listeners from our cache. |
769 UnloadedExtensionInfo* unloaded = | 729 UnloadedExtensionInfo* unloaded = |
770 content::Details<UnloadedExtensionInfo>(details).ptr(); | 730 content::Details<UnloadedExtensionInfo>(details).ptr(); |
771 listeners_.RemoveLazyListenersForExtension(unloaded->extension->id()); | 731 listeners_.RemoveLazyListenersForExtension(unloaded->extension->id()); |
772 break; | 732 break; |
773 } | 733 } |
774 case chrome::NOTIFICATION_EXTENSION_INSTALLED: { | |
775 // Dispatch the onInstalled event. | |
776 const Extension* extension = | |
777 content::Details<const InstalledExtensionInfo>(details)->extension; | |
778 | |
779 // Get the previous version, if this is an upgrade. | |
780 ExtensionService* service = ExtensionSystem::GetForBrowserContext( | |
781 browser_context_)->extension_service(); | |
782 const Extension* old = service->GetExtensionById(extension->id(), true); | |
783 Version old_version; | |
784 if (old) | |
785 old_version = *old->version(); | |
786 | |
787 base::MessageLoop::current()->PostTask( | |
788 FROM_HERE, | |
789 base::Bind(&DispatchOnInstalledEvent, | |
790 browser_context_, | |
791 extension->id(), | |
792 old_version, | |
793 false)); | |
794 break; | |
795 } | |
796 default: | 734 default: |
797 NOTREACHED(); | 735 NOTREACHED(); |
798 return; | 736 return; |
799 } | 737 } |
800 } | 738 } |
801 | 739 |
802 Event::Event(const std::string& event_name, | 740 Event::Event(const std::string& event_name, |
803 scoped_ptr<base::ListValue> event_args) | 741 scoped_ptr<base::ListValue> event_args) |
804 : event_name(event_name), | 742 : event_name(event_name), |
805 event_args(event_args.Pass()), | 743 event_args(event_args.Pass()), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 copy->will_dispatch_callback = will_dispatch_callback; | 783 copy->will_dispatch_callback = will_dispatch_callback; |
846 return copy; | 784 return copy; |
847 } | 785 } |
848 | 786 |
849 EventListenerInfo::EventListenerInfo(const std::string& event_name, | 787 EventListenerInfo::EventListenerInfo(const std::string& event_name, |
850 const std::string& extension_id) | 788 const std::string& extension_id) |
851 : event_name(event_name), | 789 : event_name(event_name), |
852 extension_id(extension_id) {} | 790 extension_id(extension_id) {} |
853 | 791 |
854 } // namespace extensions | 792 } // namespace extensions |
OLD | NEW |