| 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" | 14 #include "base/version.h" |
| 15 #include "chrome/browser/chrome_notification_types.h" | 15 #include "chrome/browser/chrome_notification_types.h" |
| 16 #include "chrome/browser/extensions/activity_log/activity_log.h" | 16 #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" | 17 #include "chrome/browser/extensions/api/web_request/web_request_api.h" |
| 19 #include "chrome/browser/extensions/extension_host.h" | 18 #include "chrome/browser/extensions/extension_host.h" |
| 20 #include "chrome/browser/extensions/extension_prefs.h" | 19 #include "chrome/browser/extensions/extension_prefs.h" |
| 21 #include "chrome/browser/extensions/extension_service.h" | 20 #include "chrome/browser/extensions/extension_service.h" |
| 22 #include "chrome/browser/extensions/extension_system.h" | 21 #include "chrome/browser/extensions/extension_system.h" |
| 23 #include "chrome/browser/extensions/extension_util.h" | 22 #include "chrome/browser/extensions/extension_util.h" |
| 24 #include "chrome/browser/extensions/process_map.h" | 23 #include "chrome/browser/extensions/process_map.h" |
| 25 #include "chrome/common/extensions/extension.h" | 24 #include "chrome/common/extensions/extension.h" |
| 26 #include "chrome/common/extensions/extension_messages.h" | 25 #include "chrome/common/extensions/extension_messages.h" |
| 27 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 44 namespace { | 43 namespace { |
| 45 | 44 |
| 46 void NotifyEventListenerRemovedOnIOThread( | 45 void NotifyEventListenerRemovedOnIOThread( |
| 47 void* browser_context, | 46 void* browser_context, |
| 48 const std::string& extension_id, | 47 const std::string& extension_id, |
| 49 const std::string& sub_event_name) { | 48 const std::string& sub_event_name) { |
| 50 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | 49 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
| 51 browser_context, extension_id, sub_event_name); | 50 browser_context, extension_id, sub_event_name); |
| 52 } | 51 } |
| 53 | 52 |
| 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) {} | 53 void DoNothing(ExtensionHost* host) {} |
| 68 | 54 |
| 69 // A dictionary of event names to lists of filters that this extension has | 55 // A dictionary of event names to lists of filters that this extension has |
| 70 // registered from its lazy background page. | 56 // registered from its lazy background page. |
| 71 const char kFilteredEvents[] = "filtered_events"; | 57 const char kFilteredEvents[] = "filtered_events"; |
| 72 | 58 |
| 73 } // namespace | 59 } // namespace |
| 74 | 60 |
| 75 const char EventRouter::kRegisteredEvents[] = "events"; | 61 const char EventRouter::kRegisteredEvents[] = "events"; |
| 76 | 62 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 FROM_HERE, | 153 FROM_HERE, |
| 168 base::Bind(&EventRouter::IncrementInFlightEventsOnUI, | 154 base::Bind(&EventRouter::IncrementInFlightEventsOnUI, |
| 169 browser_context_id, | 155 browser_context_id, |
| 170 extension_id)); | 156 extension_id)); |
| 171 } | 157 } |
| 172 | 158 |
| 173 EventRouter::EventRouter(BrowserContext* browser_context, | 159 EventRouter::EventRouter(BrowserContext* browser_context, |
| 174 ExtensionPrefs* extension_prefs) | 160 ExtensionPrefs* extension_prefs) |
| 175 : browser_context_(browser_context), | 161 : browser_context_(browser_context), |
| 176 extension_prefs_(extension_prefs), | 162 extension_prefs_(extension_prefs), |
| 177 listeners_(this), | 163 listeners_(this) { |
| 178 dispatch_chrome_updated_event_(false) { | |
| 179 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 164 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 180 content::NotificationService::AllSources()); | 165 content::NotificationService::AllSources()); |
| 181 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 166 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 182 content::NotificationService::AllSources()); | 167 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, | 168 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_ENABLED, |
| 186 content::Source<BrowserContext>(browser_context_)); | 169 content::Source<BrowserContext>(browser_context_)); |
| 187 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 170 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| 188 content::Source<BrowserContext>(browser_context_)); | 171 content::Source<BrowserContext>(browser_context_)); |
| 189 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 172 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 190 content::Source<BrowserContext>(browser_context_)); | 173 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 } | 174 } |
| 199 | 175 |
| 200 EventRouter::~EventRouter() {} | 176 EventRouter::~EventRouter() {} |
| 201 | 177 |
| 202 void EventRouter::AddEventListener(const std::string& event_name, | 178 void EventRouter::AddEventListener(const std::string& event_name, |
| 203 content::RenderProcessHost* process, | 179 content::RenderProcessHost* process, |
| 204 const std::string& extension_id) { | 180 const std::string& extension_id) { |
| 205 listeners_.AddListener(scoped_ptr<EventListener>(new EventListener( | 181 listeners_.AddListener(scoped_ptr<EventListener>(new EventListener( |
| 206 event_name, extension_id, process, scoped_ptr<DictionaryValue>()))); | 182 event_name, extension_id, process, scoped_ptr<DictionaryValue>()))); |
| 207 } | 183 } |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 const content::NotificationDetails& details) { | 691 const content::NotificationDetails& details) { |
| 716 switch (type) { | 692 switch (type) { |
| 717 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | 693 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
| 718 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | 694 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
| 719 content::RenderProcessHost* renderer = | 695 content::RenderProcessHost* renderer = |
| 720 content::Source<content::RenderProcessHost>(source).ptr(); | 696 content::Source<content::RenderProcessHost>(source).ptr(); |
| 721 // Remove all event listeners associated with this renderer. | 697 // Remove all event listeners associated with this renderer. |
| 722 listeners_.RemoveListenersForProcess(renderer); | 698 listeners_.RemoveListenersForProcess(renderer); |
| 723 break; | 699 break; |
| 724 } | 700 } |
| 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: { | 701 case chrome::NOTIFICATION_EXTENSION_ENABLED: { |
| 731 // If the extension has a lazy background page, make sure it gets loaded | 702 // If the extension has a lazy background page, make sure it gets loaded |
| 732 // to register the events the extension is interested in. | 703 // to register the events the extension is interested in. |
| 733 const Extension* extension = | 704 const Extension* extension = |
| 734 content::Details<const Extension>(details).ptr(); | 705 content::Details<const Extension>(details).ptr(); |
| 735 if (BackgroundInfo::HasLazyBackgroundPage(extension)) { | 706 if (BackgroundInfo::HasLazyBackgroundPage(extension)) { |
| 736 LazyBackgroundTaskQueue* queue = ExtensionSystem::GetForBrowserContext( | 707 LazyBackgroundTaskQueue* queue = ExtensionSystem::GetForBrowserContext( |
| 737 browser_context_)->lazy_background_task_queue(); | 708 browser_context_)->lazy_background_task_queue(); |
| 738 queue->AddPendingTask(browser_context_, extension->id(), | 709 queue->AddPendingTask(browser_context_, extension->id(), |
| 739 base::Bind(&DoNothing)); | 710 base::Bind(&DoNothing)); |
| 740 } | 711 } |
| 741 break; | 712 break; |
| 742 } | 713 } |
| 743 case chrome::NOTIFICATION_EXTENSION_LOADED: { | 714 case chrome::NOTIFICATION_EXTENSION_LOADED: { |
| 744 // Add all registered lazy listeners to our cache. | 715 // Add all registered lazy listeners to our cache. |
| 745 const Extension* extension = | 716 const Extension* extension = |
| 746 content::Details<const Extension>(details).ptr(); | 717 content::Details<const Extension>(details).ptr(); |
| 747 std::set<std::string> registered_events = | 718 std::set<std::string> registered_events = |
| 748 GetRegisteredEvents(extension->id()); | 719 GetRegisteredEvents(extension->id()); |
| 749 listeners_.LoadUnfilteredLazyListeners(extension->id(), | 720 listeners_.LoadUnfilteredLazyListeners(extension->id(), |
| 750 registered_events); | 721 registered_events); |
| 751 const DictionaryValue* filtered_events = | 722 const DictionaryValue* filtered_events = |
| 752 GetFilteredEvents(extension->id()); | 723 GetFilteredEvents(extension->id()); |
| 753 if (filtered_events) | 724 if (filtered_events) |
| 754 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); | 725 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; | 726 break; |
| 766 } | 727 } |
| 767 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | 728 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { |
| 768 // Remove all registered lazy listeners from our cache. | 729 // Remove all registered lazy listeners from our cache. |
| 769 UnloadedExtensionInfo* unloaded = | 730 UnloadedExtensionInfo* unloaded = |
| 770 content::Details<UnloadedExtensionInfo>(details).ptr(); | 731 content::Details<UnloadedExtensionInfo>(details).ptr(); |
| 771 listeners_.RemoveLazyListenersForExtension(unloaded->extension->id()); | 732 listeners_.RemoveLazyListenersForExtension(unloaded->extension->id()); |
| 772 break; | 733 break; |
| 773 } | 734 } |
| 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: | 735 default: |
| 797 NOTREACHED(); | 736 NOTREACHED(); |
| 798 return; | 737 return; |
| 799 } | 738 } |
| 800 } | 739 } |
| 801 | 740 |
| 802 Event::Event(const std::string& event_name, | 741 Event::Event(const std::string& event_name, |
| 803 scoped_ptr<base::ListValue> event_args) | 742 scoped_ptr<base::ListValue> event_args) |
| 804 : event_name(event_name), | 743 : event_name(event_name), |
| 805 event_args(event_args.Pass()), | 744 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; | 784 copy->will_dispatch_callback = will_dispatch_callback; |
| 846 return copy; | 785 return copy; |
| 847 } | 786 } |
| 848 | 787 |
| 849 EventListenerInfo::EventListenerInfo(const std::string& event_name, | 788 EventListenerInfo::EventListenerInfo(const std::string& event_name, |
| 850 const std::string& extension_id) | 789 const std::string& extension_id) |
| 851 : event_name(event_name), | 790 : event_name(event_name), |
| 852 extension_id(extension_id) {} | 791 extension_id(extension_id) {} |
| 853 | 792 |
| 854 } // namespace extensions | 793 } // namespace extensions |
| OLD | NEW |