| 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 |