diff options
Diffstat (limited to 'chrome')
53 files changed, 339 insertions, 2098 deletions
diff --git a/chrome/browser/accessibility/accessibility_extension_api.cc b/chrome/browser/accessibility/accessibility_extension_api.cc index e2c9fa9..981bf0b 100644 --- a/chrome/browser/accessibility/accessibility_extension_api.cc +++ b/chrome/browser/accessibility/accessibility_extension_api.cc @@ -164,7 +164,7 @@ void ExtensionAccessibilityEventRouter::DispatchEvent( const std::string& json_args) { if (enabled_ && profile && profile->GetExtensionEventRouter()) { profile->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, json_args, NULL, GURL(), extensions::EventFilteringInfo()); + event_name, json_args, NULL, GURL()); } } diff --git a/chrome/browser/bookmarks/bookmark_extension_api.cc b/chrome/browser/bookmarks/bookmark_extension_api.cc index 96ac5b2..410267e 100644 --- a/chrome/browser/bookmarks/bookmark_extension_api.cc +++ b/chrome/browser/bookmarks/bookmark_extension_api.cc @@ -148,7 +148,7 @@ void BookmarkExtensionEventRouter::DispatchEvent(Profile *profile, const std::string& json_args) { if (profile->GetExtensionEventRouter()) { profile->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, json_args, NULL, GURL(), extensions::EventFilteringInfo()); + event_name, json_args, NULL, GURL()); } } diff --git a/chrome/browser/bookmarks/bookmark_manager_extension_api.cc b/chrome/browser/bookmarks/bookmark_manager_extension_api.cc index 4679096..159d7f8 100644 --- a/chrome/browser/bookmarks/bookmark_manager_extension_api.cc +++ b/chrome/browser/bookmarks/bookmark_manager_extension_api.cc @@ -173,7 +173,7 @@ void BookmarkManagerExtensionEventRouter::DispatchEvent(const char* event_name, std::string json_args; base::JSONWriter::Write(args, &json_args); profile_->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, json_args, NULL, GURL(), extensions::EventFilteringInfo()); + event_name, json_args, NULL, GURL()); } void BookmarkManagerExtensionEventRouter::DispatchDragEvent( diff --git a/chrome/browser/extensions/api/cookies/cookies_api.cc b/chrome/browser/extensions/api/cookies/cookies_api.cc index cb17f30..e2cb2b0 100644 --- a/chrome/browser/extensions/api/cookies/cookies_api.cc +++ b/chrome/browser/extensions/api/cookies/cookies_api.cc @@ -115,7 +115,7 @@ void ExtensionCookiesEventRouter::DispatchEvent(Profile* profile, GURL& cookie_domain) { if (profile && profile->GetExtensionEventRouter()) { profile->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, json_args, profile, cookie_domain, EventFilteringInfo()); + event_name, json_args, profile, cookie_domain); } } diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc index 49e8f77..ca56cf9 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api.cc @@ -1090,8 +1090,7 @@ void ExtensionDownloadsEventRouter::DispatchEvent( event_name, json_args, profile_, - GURL(), - extensions::EventFilteringInfo()); + GURL()); DownloadsNotificationSource notification_source; notification_source.event_name = event_name; diff --git a/chrome/browser/extensions/api/offscreen_tabs/offscreen_tabs_api.cc b/chrome/browser/extensions/api/offscreen_tabs/offscreen_tabs_api.cc index 28bb985..5d3c596 100644 --- a/chrome/browser/extensions/api/offscreen_tabs/offscreen_tabs_api.cc +++ b/chrome/browser/extensions/api/offscreen_tabs/offscreen_tabs_api.cc @@ -276,8 +276,7 @@ void OffscreenTab::Observe(int type, // event. Profile* profile = parent_tab_->tab_contents()->profile(); profile->GetExtensionEventRouter()->DispatchEventToRenderers( - events::kOnOffscreenTabUpdated, json_args, profile, GURL(), - extensions::EventFilteringInfo()); + events::kOnOffscreenTabUpdated, json_args, profile, GURL()); } ParentTab::ParentTab() : tab_contents_(NULL) {} diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc index 82fe920..906294a 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc @@ -20,7 +20,6 @@ #include "chrome/browser/view_type_utils.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/extensions/api/web_navigation.h" -#include "chrome/common/extensions/event_filtering_info.h" #include "chrome/common/url_constants.h" #include "content/public/browser/resource_request_details.h" #include "content/public/browser/navigation_details.h" @@ -75,18 +74,11 @@ double MilliSecondsFromTime(const base::Time& time) { // Dispatches events to the extension message service. void DispatchEvent(BrowserContext* browser_context, const char* event_name, - const ListValue& args, - const GURL& url) { - std::string json_args; - base::JSONWriter::Write(&args, &json_args); - - extensions::EventFilteringInfo info; - info.SetURL(url); - + const std::string& json_args) { Profile* profile = Profile::FromBrowserContext(browser_context); if (profile && profile->GetExtensionEventRouter()) { profile->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, json_args, profile, GURL(), info); + event_name, json_args, profile, GURL()); } } @@ -103,10 +95,11 @@ void DispatchOnBeforeNavigate(WebContents* web_contents, dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); args.Append(dict); + std::string json_args; + base::JSONWriter::Write(&args, &json_args); DispatchEvent(web_contents->GetBrowserContext(), keys::kOnBeforeNavigate, - args, - validated_url); + json_args); } // Constructs and dispatches an onCommitted or onReferenceFragmentUpdated @@ -138,7 +131,9 @@ void DispatchOnCommitted(const char* event_name, dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); args.Append(dict); - DispatchEvent(web_contents->GetBrowserContext(), event_name, args, url); + std::string json_args; + base::JSONWriter::Write(&args, &json_args); + DispatchEvent(web_contents->GetBrowserContext(), event_name, json_args); } // Constructs and dispatches an onDOMContentLoaded event. @@ -155,10 +150,11 @@ void DispatchOnDOMContentLoaded(WebContents* web_contents, dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); args.Append(dict); + std::string json_args; + base::JSONWriter::Write(&args, &json_args); DispatchEvent(web_contents->GetBrowserContext(), keys::kOnDOMContentLoaded, - args, - url); + json_args); } // Constructs and dispatches an onCompleted event. @@ -175,8 +171,10 @@ void DispatchOnCompleted(WebContents* web_contents, dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); args.Append(dict); - DispatchEvent(web_contents->GetBrowserContext(), keys::kOnCompleted, args, - url); + std::string json_args; + base::JSONWriter::Write(&args, &json_args); + DispatchEvent(web_contents->GetBrowserContext(), + keys::kOnCompleted, json_args); } // Constructs and dispatches an onCreatedNavigationTarget event. @@ -206,8 +204,10 @@ void DispatchOnCreatedNavigationTarget( dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); args.Append(dict); - DispatchEvent(browser_context, keys::kOnCreatedNavigationTarget, args, - target_url); + std::string json_args; + base::JSONWriter::Write(&args, &json_args); + DispatchEvent( + browser_context, keys::kOnCreatedNavigationTarget, json_args); } // Constructs and dispatches an onErrorOccurred event. @@ -225,8 +225,11 @@ void DispatchOnErrorOccurred(WebContents* web_contents, dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); args.Append(dict); - DispatchEvent(web_contents->GetBrowserContext(), keys::kOnErrorOccurred, - args, url); + std::string json_args; + base::JSONWriter::Write(&args, &json_args); + DispatchEvent(web_contents->GetBrowserContext(), + keys::kOnErrorOccurred, + json_args); } } // namespace diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc index 28c0f32..e793f9c 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc @@ -33,7 +33,6 @@ using content::WebContents; #define MAYBE_WebNavigationReferenceFragment \ DISABLED_WebNavigationReferenceFragment #define MAYBE_WebNavigationOpenTab DISABLED_WebNavigationOpenTab -#define MAYBE_WebNavigationFilteredTest DISABLED_WebNavigationFilteredTest #else #define MAYBE_WebNavigationIFrame WebNavigationIFrame #define MAYBE_WebNavigationFailures WebNavigationFailures @@ -43,7 +42,6 @@ using content::WebContents; #define MAYBE_WebNavigationSimpleLoad WebNavigationSimpleLoad #define MAYBE_WebNavigationReferenceFragment WebNavigationReferenceFragment #define MAYBE_WebNavigationOpenTab WebNavigationOpenTab -#define MAYBE_WebNavigationFilteredTest WebNavigationFilteredTest #endif namespace extensions { @@ -176,16 +174,6 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_WebNavigationFailures) { RunExtensionSubtest("webnavigation", "test_failures.html")) << message_; } -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_WebNavigationFilteredTest) { - FrameNavigationState::set_allow_extension_scheme(true); - - CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kAllowLegacyExtensionManifests); - - ASSERT_TRUE( - RunExtensionSubtest("webnavigation", "test_filtered.html")) << message_; -} - IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WebNavigationUserAction) { FrameNavigationState::set_allow_extension_scheme(true); diff --git a/chrome/browser/extensions/api/web_request/web_request_api.cc b/chrome/browser/extensions/api/web_request/web_request_api.cc index fb5aa99..d79316e 100644 --- a/chrome/browser/extensions/api/web_request/web_request_api.cc +++ b/chrome/browser/extensions/api/web_request/web_request_api.cc @@ -937,8 +937,7 @@ bool ExtensionWebRequestEventRouter::DispatchEvent( ExtensionEventRouter::DispatchEvent( (*it)->ipc_sender.get(), (*it)->extension_id, (*it)->sub_event_name, - json_args, GURL(), ExtensionEventRouter::USER_GESTURE_UNKNOWN, - EventFilteringInfo()); + json_args, GURL(), ExtensionEventRouter::USER_GESTURE_UNKNOWN); if ((*it)->extra_info_spec & (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) { (*it)->blocked_requests.insert(request->identifier()); diff --git a/chrome/browser/extensions/event_listener_map.cc b/chrome/browser/extensions/event_listener_map.cc deleted file mode 100644 index 5384d97..0000000 --- a/chrome/browser/extensions/event_listener_map.cc +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/extensions/event_listener_map.h" - -#include "base/values.h" - -#include "chrome/browser/extensions/extension_event_router.h" - -namespace extensions { - -typedef EventFilter::MatcherID MatcherID; - -EventListener::EventListener(const std::string& event_name, - const std::string& extension_id, - content::RenderProcessHost* process, - scoped_ptr<DictionaryValue> filter) - : event_name(event_name), - extension_id(extension_id), - process(process), - filter(filter.Pass()), - matcher_id(-1) {} - -EventListener::~EventListener() {} - -bool EventListener::Equals(const EventListener* other) const { - // We don't check matcher_id equality because we want a listener with a - // filter that hasn't been added to EventFilter to match one that is - // equivalent but has. - return event_name == other->event_name && - extension_id == other->extension_id && - process == other->process && - ((!!filter.get()) == (!!other->filter.get())) && - (!filter.get() || filter->Equals(other->filter.get())); -} - -scoped_ptr<EventListener> EventListener::Copy() const { - scoped_ptr<DictionaryValue> filter_copy; - if (filter.get()) - filter_copy.reset(filter->DeepCopy()); - return scoped_ptr<EventListener>(new EventListener(event_name, extension_id, - process, - filter_copy.Pass())); -} - -EventListenerMap::EventListenerMap(Delegate* delegate) - : delegate_(delegate) { -} - -EventListenerMap::~EventListenerMap() {} - -bool EventListenerMap::AddListener(scoped_ptr<EventListener> listener) { - if (HasListener(listener.get())) - return false; - if (listener->filter.get()) { - scoped_ptr<EventMatcher> matcher(ParseEventMatcher(listener->filter.get())); - MatcherID id = event_filter_.AddEventMatcher(listener->event_name, - matcher.Pass()); - listener->matcher_id = id; - listeners_by_matcher_id_[id] = listener.get(); - filtered_events_.insert(listener->event_name); - } - linked_ptr<EventListener> listener_ptr(listener.release()); - listeners_[listener_ptr->event_name].push_back(listener_ptr); - - delegate_->OnListenerAdded(listener_ptr.get()); - - return true; -} - -scoped_ptr<EventMatcher> EventListenerMap::ParseEventMatcher( - DictionaryValue* filter_dict) { - return scoped_ptr<EventMatcher>(new EventMatcher( - scoped_ptr<DictionaryValue>(filter_dict->DeepCopy()))); -} - -bool EventListenerMap::RemoveListener(const EventListener* listener) { - ListenerList& listeners = listeners_[listener->event_name]; - for (ListenerList::iterator it = listeners.begin(); it != listeners.end(); - it++) { - if ((*it)->Equals(listener)) { - delegate_->OnListenerRemoved(it->get()); - CleanupListener(it->get()); - // Popping from the back should be cheaper than erase(it). - std::swap(*it, listeners.back()); - listeners.pop_back(); - return true; - } - } - return false; -} - -bool EventListenerMap::HasListenerForEvent(const std::string& event_name) { - ListenerMap::iterator it = listeners_.find(event_name); - return it != listeners_.end() && !it->second.empty(); -} - -bool EventListenerMap::HasListenerForExtension( - const std::string& extension_id, - const std::string& event_name) { - ListenerMap::iterator it = listeners_.find(event_name); - if (it == listeners_.end()) - return false; - - for (ListenerList::iterator it2 = it->second.begin(); - it2 != it->second.end(); it2++) { - if ((*it2)->extension_id == extension_id) - return true; - } - return false; -} - -bool EventListenerMap::HasListener(const EventListener* listener) { - ListenerMap::iterator it = listeners_.find(listener->event_name); - if (it == listeners_.end()) - return false; - for (ListenerList::iterator it2 = it->second.begin(); - it2 != it->second.end(); it2++) { - if ((*it2)->Equals(listener)) { - return true; - } - } - return false; -} - -bool EventListenerMap::HasProcessListener(content::RenderProcessHost* process, - const std::string& extension_id) { - for (ListenerMap::iterator it = listeners_.begin(); it != listeners_.end(); - it++) { - for (ListenerList::iterator it2 = it->second.begin(); - it2 != it->second.end(); it2++) { - if ((*it2)->process == process && (*it2)->extension_id == extension_id) - return true; - } - } - return false; -} - -void EventListenerMap::RemoveLazyListenersForExtension( - const std::string& extension_id) { - for (ListenerMap::iterator it = listeners_.begin(); it != listeners_.end(); - it++) { - for (ListenerList::iterator it2 = it->second.begin(); - it2 != it->second.end();) { - if (!(*it2)->process && (*it2)->extension_id == extension_id) { - CleanupListener(it2->get()); - it2 = it->second.erase(it2); - } else { - it2++; - } - } - } -} - -void EventListenerMap::LoadUnfilteredLazyListeners( - const std::string& extension_id, - const std::set<std::string>& event_names) { - for (std::set<std::string>::const_iterator it = event_names.begin(); - it != event_names.end(); ++it) { - AddListener(scoped_ptr<EventListener>(new EventListener( - *it, extension_id, NULL, scoped_ptr<DictionaryValue>()))); - } -} - -void EventListenerMap::LoadFilteredLazyListeners( - const std::string& extension_id, - const DictionaryValue& filtered) { - for (DictionaryValue::key_iterator it = filtered.begin_keys(); - it != filtered.end_keys(); ++it) { - // We skip entries if they are malformed. - ListValue* filter_list = NULL; - if (!filtered.GetList(*it, &filter_list)) - continue; - for (size_t i = 0; i < filter_list->GetSize(); i++) { - DictionaryValue* filter = NULL; - if (!filter_list->GetDictionary(i, &filter)) - continue; - AddListener(scoped_ptr<EventListener>(new EventListener( - *it, extension_id, NULL, - scoped_ptr<DictionaryValue>(filter->DeepCopy())))); - } - } -} - -std::set<const EventListener*> EventListenerMap::GetEventListeners( - const ExtensionEvent& event) { - std::set<const EventListener*> interested_listeners; - if (IsFilteredEvent(event)) { - // Look up the interested listeners via the EventFilter. - std::set<MatcherID> ids = - event_filter_.MatchEvent(event.event_name, event.info); - for (std::set<MatcherID>::iterator id = ids.begin(); id != ids.end(); - id++) { - EventListener* listener = listeners_by_matcher_id_[*id]; - CHECK(listener); - interested_listeners.insert(listener); - } - } else { - ListenerList& listeners = listeners_[event.event_name]; - for (ListenerList::const_iterator it = listeners.begin(); - it != listeners.end(); it++) { - interested_listeners.insert(it->get()); - } - } - - return interested_listeners; -} - -void EventListenerMap::RemoveListenersForProcess( - const content::RenderProcessHost* process) { - CHECK(process); - for (ListenerMap::iterator it = listeners_.begin(); it != listeners_.end(); - it++) { - for (ListenerList::iterator it2 = it->second.begin(); - it2 != it->second.end();) { - if ((*it2)->process == process) { - delegate_->OnListenerRemoved(it2->get()); - CleanupListener(it2->get()); - it2 = it->second.erase(it2); - } else { - it2++; - } - } - } -} - -void EventListenerMap::CleanupListener(EventListener* listener) { - // If the listener doesn't have a filter then we have nothing to clean up. - if (listener->matcher_id == -1) - return; - event_filter_.RemoveEventMatcher(listener->matcher_id); - CHECK_EQ(1u, listeners_by_matcher_id_.erase(listener->matcher_id)); -} - -bool EventListenerMap::IsFilteredEvent(const ExtensionEvent& event) const { - return filtered_events_.count(event.event_name) > 0u; -} - -} // namespace extensions diff --git a/chrome/browser/extensions/event_listener_map.h b/chrome/browser/extensions/event_listener_map.h deleted file mode 100644 index 1965598..0000000 --- a/chrome/browser/extensions/event_listener_map.h +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_EXTENSIONS_EVENT_LISTENER_MAP_H_ -#define CHROME_BROWSER_EXTENSIONS_EVENT_LISTENER_MAP_H_ -#pragma once - -#include "base/memory/scoped_ptr.h" -#include "chrome/common/extensions/event_filter.h" - -#include <map> -#include <set> -#include <string> -#include <vector> - -namespace base { -class DictionaryValue; -} - -namespace content { -class RenderProcessHost; -} - -struct ExtensionEvent; -class ListenerRemovalListener; - -using base::DictionaryValue; - -namespace extensions { - -// A listener for an extension event. A listener is essentially an endpoint -// that an event can be dispatched to. This is a lazy listener if |process| is -// NULL and a filtered listener if |filter| is defined. -// -// A lazy listener is added to an event to indicate that a lazy background page -// is listening to the event. It is associated with no process, so to dispatch -// an event to a lazy listener one must start a process running the associated -// extension and dispatch the event to that. -// -struct EventListener { - // |filter| represents a generic filter structure that EventFilter knows how - // to filter events with. A typical filter instance will look like - // - // { - // url: [{hostSuffix: 'google.com'}], - // tabId: 5 - // } - EventListener(const std::string& event_name, - const std::string& extension_id, - content::RenderProcessHost* process, - scoped_ptr<DictionaryValue> filter); - ~EventListener(); - - bool Equals(const EventListener* other) const; - - scoped_ptr<EventListener> Copy() const; - - const std::string event_name; - const std::string extension_id; - content::RenderProcessHost* process; - scoped_ptr<DictionaryValue> filter; - EventFilter::MatcherID matcher_id; - - private: - DISALLOW_COPY_AND_ASSIGN(EventListener); -}; - -// Holds listeners for extension events and can answer questions about which -// listeners are interested in what events. -class EventListenerMap { - public: - typedef std::vector<linked_ptr<EventListener> > ListenerList; - - class Delegate { - public: - virtual ~Delegate() {} - virtual void OnListenerAdded(const EventListener* listener) = 0; - virtual void OnListenerRemoved(const EventListener* listener) = 0; - }; - - explicit EventListenerMap(Delegate* delegate); - ~EventListenerMap(); - - // Add a listener for a particular event. GetEventListeners() will include a - // weak pointer to |listener| in its results if passed a relevant - // ExtensionEvent. - // Returns true if the listener was added (in the case that it has never been - // seen before). - bool AddListener(scoped_ptr<EventListener> listener); - - // Remove a listener that .Equals() |listener|. - // Returns true if the listener was removed . - bool RemoveListener(const EventListener* listener); - - // Returns the set of listeners that want to be notified of |event|. - std::set<const EventListener*> GetEventListeners( - const ExtensionEvent& event); - - // Removes all listeners with process equal to |process|. - void RemoveListenersForProcess(const content::RenderProcessHost* process); - - // Returns true if there are any listeners on the event named |event_name|. - bool HasListenerForEvent(const std::string& event_name); - - // Returns true if there are any listeners on |event_name| from - // |extension_id|. - bool HasListenerForExtension(const std::string& extension_id, - const std::string& event_name); - - // Returns true if this map contains an EventListener that .Equals() - // |listener|. - bool HasListener(const EventListener* listener); - - // Returns true if there is a listener for |extension_id| in |process|. - bool HasProcessListener(content::RenderProcessHost* process, - const std::string& extension_id); - - // Removes any lazy listeners that |extension_id| has added. - void RemoveLazyListenersForExtension(const std::string& extension_id); - - // Adds unfiltered lazy listeners as described their serialised descriptions. - // |event_names| the names of the lazy events. - // Note that we can only load lazy listeners in this fashion, because there - // is no way to serialise a RenderProcessHost*. - void LoadUnfilteredLazyListeners(const std::string& extension_id, - const std::set<std::string>& event_names); - - // Adds filtered lazy listeners as described their serialised descriptions. - // |filtered| contains a map from event names to filters, each pairing - // defining a lazy filtered listener. - void LoadFilteredLazyListeners( - const std::string& extension_id, - const DictionaryValue& filtered); - - private: - // The key here is an event name. - typedef std::map<std::string, ListenerList> ListenerMap; - - void CleanupListener(EventListener* listener); - bool IsFilteredEvent(const ExtensionEvent& event) const; - scoped_ptr<EventMatcher> ParseEventMatcher(DictionaryValue* filter_dict); - - // Listens for removals from this map. - Delegate* delegate_; - - std::set<std::string> filtered_events_; - ListenerMap listeners_; - - std::map<EventFilter::MatcherID, EventListener*> listeners_by_matcher_id_; - - EventFilter event_filter_; - - DISALLOW_COPY_AND_ASSIGN(EventListenerMap); -}; - -} // namespace extensions - -#endif // CHROME_BROWSER_EXTENSIONS_EVENT_LISTENER_MAP_H_ diff --git a/chrome/browser/extensions/event_listener_map_unittest.cc b/chrome/browser/extensions/event_listener_map_unittest.cc deleted file mode 100644 index 3cb2511..0000000 --- a/chrome/browser/extensions/event_listener_map_unittest.cc +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "testing/gtest/include/gtest/gtest.h" - -#include "chrome/browser/extensions/event_listener_map.h" -#include "chrome/browser/extensions/extension_event_router.h" -#include "content/public/test/mock_render_process_host.h" -#include "content/public/test/test_browser_context.h" - -namespace { - -const char kExt1Id[] = "extension_1"; -const char kExt2Id[] = "extension_2"; -const char kEvent1Name[] = "event1"; -const char kEvent2Name[] = "event2"; - -class EmptyDelegate : public EventListenerMap::Delegate { - virtual void OnListenerAdded(const EventListener* listener) OVERRIDE {}; - virtual void OnListenerRemoved(const EventListener* listener) OVERRIDE {}; -}; - -class EventListenerMapUnittest : public testing::Test { - public: - EventListenerMapUnittest() - : delegate_(new EmptyDelegate), - listeners_(new EventListenerMap(delegate_.get())), - process_(new content::MockRenderProcessHost( - new content::TestBrowserContext)) { - } - - scoped_ptr<DictionaryValue> CreateHostSuffixFilter( - const std::string& suffix) { - scoped_ptr<DictionaryValue> filter(new DictionaryValue); - scoped_ptr<ListValue> filter_list(new ListValue); - scoped_ptr<DictionaryValue> filter_dict(new DictionaryValue); - - filter_dict->Set("hostSuffix", new StringValue(suffix)); - - filter_list->Append(filter_dict.release()); - filter->Set("url", filter_list.release()); - return filter.Pass(); - } - - scoped_ptr<ExtensionEvent> CreateNamedEvent(const std::string& event_name) { - return CreateEvent(event_name, GURL()); - } - - scoped_ptr<ExtensionEvent> CreateEvent(const std::string& event_name, - const GURL& url) { - EventFilteringInfo info; - info.SetURL(url); - scoped_ptr<ExtensionEvent> result(new ExtensionEvent(event_name, "", GURL(), - NULL, "", ExtensionEventRouter::USER_GESTURE_UNKNOWN, info)); - return result.Pass(); - } - - protected: - scoped_ptr<EventListenerMap::Delegate> delegate_; - scoped_ptr<EventListenerMap> listeners_; - scoped_ptr<content::MockRenderProcessHost> process_; -}; - -TEST_F(EventListenerMapUnittest, UnfilteredEventsGoToAllListeners) { - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, scoped_ptr<DictionaryValue>()))); - - scoped_ptr<ExtensionEvent> event(CreateNamedEvent(kEvent1Name)); - std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); - ASSERT_EQ(1u, targets.size()); -} - -TEST_F(EventListenerMapUnittest, FilteredEventsGoToAllMatchingListeners) { - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com")))); - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, scoped_ptr<DictionaryValue>( - new DictionaryValue)))); - - scoped_ptr<ExtensionEvent> event(CreateNamedEvent(kEvent1Name)); - event->info.SetURL(GURL("http://www.google.com")); - std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); - ASSERT_EQ(2u, targets.size()); -} - -TEST_F(EventListenerMapUnittest, FilteredEventsOnlyGoToMatchingListeners) { - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com")))); - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("yahoo.com")))); - - scoped_ptr<ExtensionEvent> event(CreateNamedEvent(kEvent1Name)); - event->info.SetURL(GURL("http://www.google.com")); - std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); - ASSERT_EQ(1u, targets.size()); -} - -TEST_F(EventListenerMapUnittest, LazyAndUnlazyListenersGetReturned) { - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com")))); - - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, process_.get(), - CreateHostSuffixFilter("google.com")))); - - scoped_ptr<ExtensionEvent> event(CreateNamedEvent(kEvent1Name)); - event->info.SetURL(GURL("http://www.google.com")); - std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); - ASSERT_EQ(2u, targets.size()); -} - -TEST_F(EventListenerMapUnittest, TestRemovingByProcess) { - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com")))); - - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, process_.get(), - CreateHostSuffixFilter("google.com")))); - - listeners_->RemoveListenersForProcess(process_.get()); - - scoped_ptr<ExtensionEvent> event(CreateNamedEvent(kEvent1Name)); - event->info.SetURL(GURL("http://www.google.com")); - std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); - ASSERT_EQ(1u, targets.size()); -} - -TEST_F(EventListenerMapUnittest, TestRemovingByListener) { - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com")))); - - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, process_.get(), - CreateHostSuffixFilter("google.com")))); - - scoped_ptr<EventListener> listener(new EventListener(kEvent1Name, kExt1Id, - process_.get(), CreateHostSuffixFilter("google.com"))); - listeners_->RemoveListener(listener.get()); - - scoped_ptr<ExtensionEvent> event(CreateNamedEvent(kEvent1Name)); - event->info.SetURL(GURL("http://www.google.com")); - std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); - ASSERT_EQ(1u, targets.size()); -} - -TEST_F(EventListenerMapUnittest, TestLazyDoubleAddIsUndoneByRemove) { - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com")))); - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com")))); - - scoped_ptr<EventListener> listener(new EventListener( - kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com"))); - listeners_->RemoveListener(listener.get()); - - scoped_ptr<ExtensionEvent> event(CreateNamedEvent(kEvent1Name)); - event->info.SetURL(GURL("http://www.google.com")); - std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); - ASSERT_EQ(0u, targets.size()); -} - -TEST_F(EventListenerMapUnittest, HostSuffixFilterEquality) { - scoped_ptr<DictionaryValue> filter1(CreateHostSuffixFilter("google.com")); - scoped_ptr<DictionaryValue> filter2(CreateHostSuffixFilter("google.com")); - ASSERT_TRUE(filter1->Equals(filter2.get())); -} - -TEST_F(EventListenerMapUnittest, RemoveLazyListenersForExtension) { - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com")))); - listeners_->AddListener(scoped_ptr<EventListener>(new EventListener( - kEvent2Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com")))); - - listeners_->RemoveLazyListenersForExtension(kExt1Id); - - scoped_ptr<ExtensionEvent> event(CreateNamedEvent(kEvent1Name)); - event->info.SetURL(GURL("http://www.google.com")); - std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); - ASSERT_EQ(0u, targets.size()); - - event->event_name = kEvent2Name; - targets = listeners_->GetEventListeners(*event); - ASSERT_EQ(0u, targets.size()); -} - -TEST_F(EventListenerMapUnittest, AddExistingFilteredListener) { - bool first_new = listeners_->AddListener(scoped_ptr<EventListener>( - new EventListener(kEvent1Name, kExt1Id, NULL, - CreateHostSuffixFilter("google.com")))); - bool second_new = listeners_->AddListener(scoped_ptr<EventListener>( - new EventListener(kEvent1Name, kExt1Id, NULL, - CreateHostSuffixFilter("google.com")))); - - ASSERT_TRUE(first_new); - ASSERT_FALSE(second_new); -} - -TEST_F(EventListenerMapUnittest, AddExistingUnfilteredListener) { - bool first_add = listeners_->AddListener(scoped_ptr<EventListener>( - new EventListener(kEvent1Name, kExt1Id, NULL, - scoped_ptr<DictionaryValue>()))); - bool second_add = listeners_->AddListener(scoped_ptr<EventListener>( - new EventListener(kEvent1Name, kExt1Id, NULL, - scoped_ptr<DictionaryValue>()))); - - scoped_ptr<EventListener> listener( - new EventListener(kEvent1Name, kExt1Id, NULL, - scoped_ptr<DictionaryValue>())); - bool first_remove = listeners_->RemoveListener(listener.get()); - bool second_remove = listeners_->RemoveListener(listener.get()); - - ASSERT_TRUE(first_add); - ASSERT_FALSE(second_add); - ASSERT_TRUE(first_remove); - ASSERT_FALSE(second_remove); -} - -TEST_F(EventListenerMapUnittest, RemovingRouters) { - listeners_->AddListener(scoped_ptr<EventListener>( - new EventListener(kEvent1Name, kExt1Id, process_.get(), - scoped_ptr<DictionaryValue>()))); - listeners_->RemoveListenersForProcess(process_.get()); - ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent1Name)); -} - -TEST_F(EventListenerMapUnittest, HasListenerForEvent) { - ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent1Name)); - - listeners_->AddListener(scoped_ptr<EventListener>( - new EventListener(kEvent1Name, kExt1Id, process_.get(), - scoped_ptr<DictionaryValue>()))); - - ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent2Name)); - ASSERT_TRUE(listeners_->HasListenerForEvent(kEvent1Name)); - listeners_->RemoveListenersForProcess(process_.get()); - ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent1Name)); -} - -TEST_F(EventListenerMapUnittest, HasListenerForExtension) { - ASSERT_FALSE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name)); - - // Non-lazy listener. - listeners_->AddListener(scoped_ptr<EventListener>( - new EventListener(kEvent1Name, kExt1Id, process_.get(), - scoped_ptr<DictionaryValue>()))); - // Lazy listener. - listeners_->AddListener(scoped_ptr<EventListener>( - new EventListener(kEvent1Name, kExt1Id, NULL, - scoped_ptr<DictionaryValue>()))); - - ASSERT_FALSE(listeners_->HasListenerForExtension(kExt1Id, kEvent2Name)); - ASSERT_TRUE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name)); - ASSERT_FALSE(listeners_->HasListenerForExtension(kExt2Id, kEvent1Name)); - listeners_->RemoveListenersForProcess(process_.get()); - ASSERT_TRUE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name)); - listeners_->RemoveLazyListenersForExtension(kExt1Id); - ASSERT_FALSE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name)); -} - -TEST_F(EventListenerMapUnittest, AddLazyListenersFromPreferences) { - scoped_ptr<DictionaryValue> filter1(CreateHostSuffixFilter("google.com")); - scoped_ptr<DictionaryValue> filter2(CreateHostSuffixFilter("yahoo.com")); - - DictionaryValue filtered_listeners; - ListValue* filter_list = new ListValue(); - filtered_listeners.Set(kEvent1Name, filter_list); - - filter_list->Append(filter1.release()); - filter_list->Append(filter2.release()); - - listeners_->LoadFilteredLazyListeners(kExt1Id, filtered_listeners); - - scoped_ptr<ExtensionEvent> event(CreateEvent(kEvent1Name, - GURL("http://www.google.com"))); - std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); - ASSERT_EQ(1u, targets.size()); - scoped_ptr<EventListener> listener(new EventListener(kEvent1Name, kExt1Id, - NULL, CreateHostSuffixFilter("google.com"))); - ASSERT_TRUE((*targets.begin())->Equals(listener.get())); -} - -TEST_F(EventListenerMapUnittest, CorruptedExtensionPrefsShouldntCrash) { - scoped_ptr<DictionaryValue> filter1(CreateHostSuffixFilter("google.com")); - - DictionaryValue filtered_listeners; - // kEvent1Name should be associated with a list, not a dictionary. - filtered_listeners.Set(kEvent1Name, filter1.release()); - - listeners_->LoadFilteredLazyListeners(kExt1Id, filtered_listeners); - - scoped_ptr<ExtensionEvent> event(CreateEvent(kEvent1Name, - GURL("http://www.google.com"))); - std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); - ASSERT_EQ(0u, targets.size()); -} - -} // namespace diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc index 3d814ce..021c1ee 100644 --- a/chrome/browser/extensions/extension_browser_event_router.cc +++ b/chrome/browser/extensions/extension_browser_event_router.cc @@ -453,7 +453,7 @@ void ExtensionBrowserEventRouter::DispatchEvent(Profile* profile, return; profile->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, json_args, profile, GURL(), extensions::EventFilteringInfo()); + event_name, json_args, profile, GURL()); } void ExtensionBrowserEventRouter::DispatchEventToExtension( diff --git a/chrome/browser/extensions/extension_devtools_bridge.cc b/chrome/browser/extensions/extension_devtools_bridge.cc index ff331b7..bdd4f91 100644 --- a/chrome/browser/extensions/extension_devtools_bridge.cc +++ b/chrome/browser/extensions/extension_devtools_bridge.cc @@ -107,8 +107,7 @@ void ExtensionDevToolsBridge::InspectedContentsClosing() { // event in extensions. std::string json("[{}]"); profile_->GetExtensionEventRouter()->DispatchEventToRenderers( - on_tab_close_event_name_, json, profile_, GURL(), - extensions::EventFilteringInfo()); + on_tab_close_event_name_, json, profile_, GURL()); // This may result in this object being destroyed. extension_devtools_manager_->BridgeClosingForTab(tab_id_); @@ -120,8 +119,7 @@ void ExtensionDevToolsBridge::DispatchOnInspectorFrontend( std::string json = base::StringPrintf("[%s]", data.c_str()); profile_->GetExtensionEventRouter()->DispatchEventToRenderers( - on_page_event_name_, json, profile_, GURL(), - extensions::EventFilteringInfo()); + on_page_event_name_, json, profile_, GURL()); } void ExtensionDevToolsBridge::ContentsReplaced(WebContents* new_contents) { diff --git a/chrome/browser/extensions/extension_event_router.cc b/chrome/browser/extensions/extension_event_router.cc index ae763ec..166d378 100644 --- a/chrome/browser/extensions/extension_event_router.cc +++ b/chrome/browser/extensions/extension_event_router.cc @@ -65,46 +65,88 @@ struct ExtensionEventRouter::ListenerProcess { } }; +struct ExtensionEventRouter::ExtensionEvent { + std::string event_name; + scoped_ptr<Value> event_args; + GURL event_url; + Profile* restrict_to_profile; + scoped_ptr<Value> cross_incognito_args; + UserGestureState user_gesture; + + ExtensionEvent(const std::string& event_name, + const Value& event_args, + const GURL& event_url, + Profile* restrict_to_profile, + const Value& cross_incognito_args, + UserGestureState user_gesture) + : event_name(event_name), + event_args(event_args.DeepCopy()), + event_url(event_url), + restrict_to_profile(restrict_to_profile), + cross_incognito_args(cross_incognito_args.DeepCopy()), + user_gesture(user_gesture) {} + + ExtensionEvent(const std::string& event_name, + const Value& event_args, + const GURL& event_url, + Profile* restrict_to_profile, + UserGestureState user_gesture) + : event_name(event_name), + event_args(event_args.DeepCopy()), + event_url(event_url), + restrict_to_profile(restrict_to_profile), + cross_incognito_args(NULL), + user_gesture(user_gesture) {} + + // TODO(gdk): This variant should be retired once the callers are switched to + // providing Values instead of just strings. + ExtensionEvent(const std::string& event_name, + const std::string& event_args, + const GURL& event_url, + Profile* restrict_to_profile, + const std::string& cross_incognito_args, + UserGestureState user_gesture) + : event_name(event_name), + event_args(Value::CreateStringValue(event_args)), + event_url(event_url), + restrict_to_profile(restrict_to_profile), + cross_incognito_args(Value::CreateStringValue(cross_incognito_args)), + user_gesture(user_gesture) {} +}; + // static -void ExtensionEventRouter::DispatchEvent( - IPC::Sender* ipc_sender, - const std::string& extension_id, - const std::string& event_name, - const Value& event_args, - const GURL& event_url, - UserGestureState user_gesture, - const extensions::EventFilteringInfo& info) { +void ExtensionEventRouter::DispatchEvent(IPC::Sender* ipc_sender, + const std::string& extension_id, + const std::string& event_name, + const Value& event_args, + const GURL& event_url, + UserGestureState user_gesture) { // TODO(gdk): Reduce number of DeepCopy() calls throughout the event dispatch // chain, starting by replacing the event_args with a Value*. ListValue args; args.Set(0, Value::CreateStringValue(event_name)); args.Set(1, event_args.DeepCopy()); - args.Set(2, info.AsValue().release()); - ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL, extension_id, kDispatchEvent, args, event_url, user_gesture == USER_GESTURE_ENABLED)); } // static -void ExtensionEventRouter::DispatchEvent( - IPC::Sender* ipc_sender, - const std::string& extension_id, - const std::string& event_name, - const std::string& event_args, - const GURL& event_url, - UserGestureState user_gesture, - const extensions::EventFilteringInfo& info) { +void ExtensionEventRouter::DispatchEvent(IPC::Sender* ipc_sender, + const std::string& extension_id, + const std::string& event_name, + const std::string& event_args, + const GURL& event_url, + UserGestureState user_gesture) { scoped_ptr<Value> event_args_value(Value::CreateStringValue(event_args)); DispatchEvent(ipc_sender, extension_id, event_name, *event_args_value.get(), - event_url, user_gesture, info); + event_url, user_gesture); } ExtensionEventRouter::ExtensionEventRouter(Profile* profile) : profile_(profile), extension_devtools_manager_( - ExtensionSystem::Get(profile)->devtools_manager()), - listeners_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { + ExtensionSystem::Get(profile)->devtools_manager()) { registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, content::NotificationService::AllSources()); registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, @@ -123,46 +165,37 @@ void ExtensionEventRouter::AddEventListener( const std::string& event_name, content::RenderProcessHost* process, const std::string& extension_id) { - listeners_.AddListener(scoped_ptr<EventListener>(new EventListener( - event_name, extension_id, process, scoped_ptr<DictionaryValue>()))); -} - -void ExtensionEventRouter::RemoveEventListener( - const std::string& event_name, - content::RenderProcessHost* process, - const std::string& extension_id) { - EventListener listener(event_name, extension_id, process, - scoped_ptr<DictionaryValue>()); - listeners_.RemoveListener(&listener); -} - -void ExtensionEventRouter::OnListenerAdded(const EventListener* listener) { - // We don't care about lazy events being added. - if (!listener->process) - return; + ListenerProcess listener(process, extension_id); + DCHECK_EQ(listeners_[event_name].count(listener), 0u) << event_name; + listeners_[event_name].insert(listener); if (extension_devtools_manager_.get()) - extension_devtools_manager_->AddEventListener(listener->event_name, - listener->process->GetID()); + extension_devtools_manager_->AddEventListener(event_name, + process->GetID()); // We lazily tell the TaskManager to start updating when listeners to the // processes.onUpdated or processes.onUpdatedWithMemory events arrive. - const std::string& event_name = listener->event_name; if (event_name.compare(extension_processes_api_constants::kOnUpdated) == 0 || event_name.compare( extension_processes_api_constants::kOnUpdatedWithMemory) == 0) ExtensionProcessesEventRouter::GetInstance()->ListenerAdded(); } -void ExtensionEventRouter::OnListenerRemoved(const EventListener* listener) { - // We don't care about lazy events being removed. - if (!listener->process) - return; +void ExtensionEventRouter::RemoveEventListener( + const std::string& event_name, + content::RenderProcessHost* process, + const std::string& extension_id) { + ListenerProcess listener(process, extension_id); + DCHECK_EQ(listeners_[event_name].count(listener), 1u) << + " PID=" << process->GetID() << " extension=" << extension_id << + " event=" << event_name; + listeners_[event_name].erase(listener); + // Note: extension_id may point to data in the now-deleted listeners_ object. + // Do not use. - const std::string& event_name = listener->event_name; if (extension_devtools_manager_.get()) - extension_devtools_manager_->RemoveEventListener( - event_name, listener->process->GetID()); + extension_devtools_manager_->RemoveEventListener(event_name, + process->GetID()); // If a processes.onUpdated or processes.onUpdatedWithMemory event listener // is removed (or a process with one exits), then we let the extension API @@ -176,16 +209,14 @@ void ExtensionEventRouter::OnListenerRemoved(const EventListener* listener) { BrowserThread::IO, FROM_HERE, base::Bind( &NotifyEventListenerRemovedOnIOThread, - profile_, listener->extension_id, listener->event_name)); + profile_, listener.extension_id, event_name)); } void ExtensionEventRouter::AddLazyEventListener( const std::string& event_name, const std::string& extension_id) { - scoped_ptr<EventListener> listener(new EventListener( - event_name, extension_id, NULL, scoped_ptr<DictionaryValue>())); - bool is_new = listeners_.AddListener(listener.Pass()); - + ListenerProcess lazy_listener(NULL, extension_id); + bool is_new = lazy_listeners_[event_name].insert(lazy_listener).second; if (is_new) { ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); std::set<std::string> events = prefs->GetRegisteredEvents(extension_id); @@ -198,10 +229,8 @@ void ExtensionEventRouter::AddLazyEventListener( void ExtensionEventRouter::RemoveLazyEventListener( const std::string& event_name, const std::string& extension_id) { - EventListener listener(event_name, extension_id, NULL, - scoped_ptr<DictionaryValue>()); - bool did_exist = listeners_.RemoveListener(&listener); - + ListenerProcess lazy_listener(NULL, extension_id); + bool did_exist = lazy_listeners_[event_name].erase(lazy_listener) > 0; if (did_exist) { ExtensionPrefs* prefs = profile_->GetExtensionService()->extension_prefs(); std::set<std::string> events = prefs->GetRegisteredEvents(extension_id); @@ -211,59 +240,15 @@ void ExtensionEventRouter::RemoveLazyEventListener( } } -void ExtensionEventRouter::AddFilteredEventListener( - const std::string& event_name, - content::RenderProcessHost* process, - const std::string& extension_id, - const base::DictionaryValue& filter, - bool add_lazy_listener) { - listeners_.AddListener(scoped_ptr<EventListener>(new EventListener( - event_name, extension_id, process, - scoped_ptr<DictionaryValue>(filter.DeepCopy())))); - - if (add_lazy_listener) { - bool added = listeners_.AddListener(scoped_ptr<EventListener>( - new EventListener(event_name, extension_id, NULL, - scoped_ptr<DictionaryValue>(filter.DeepCopy())))); - - if (added) { - ExtensionPrefs* prefs = - profile_->GetExtensionService()->extension_prefs(); - prefs->AddFilterToEvent(event_name, extension_id, &filter); - } - } -} - -void ExtensionEventRouter::RemoveFilteredEventListener( - const std::string& event_name, - content::RenderProcessHost* process, - const std::string& extension_id, - const base::DictionaryValue& filter, - bool remove_lazy_listener) { - EventListener listener(event_name, extension_id, process, - scoped_ptr<DictionaryValue>(filter.DeepCopy())); - - listeners_.RemoveListener(&listener); - - if (remove_lazy_listener) { - listener.process = NULL; - bool removed = listeners_.RemoveListener(&listener); - - if (removed) { - ExtensionPrefs* prefs = - profile_->GetExtensionService()->extension_prefs(); - prefs->RemoveFilterFromEvent(event_name, extension_id, &filter); - } - } -} - bool ExtensionEventRouter::HasEventListener(const std::string& event_name) { - return listeners_.HasListenerForEvent(event_name); + return (HasEventListenerImpl(listeners_, "", event_name) || + HasEventListenerImpl(lazy_listeners_, "", event_name)); } bool ExtensionEventRouter::ExtensionHasEventListener( const std::string& extension_id, const std::string& event_name) { - return listeners_.HasListenerForExtension(extension_id, event_name); + return (HasEventListenerImpl(listeners_, extension_id, event_name) || + HasEventListenerImpl(lazy_listeners_, extension_id, event_name)); } bool ExtensionEventRouter::HasEventListenerImpl( @@ -290,25 +275,13 @@ void ExtensionEventRouter::DispatchEventToRenderers( const std::string& event_name, const std::string& event_args, Profile* restrict_to_profile, - const GURL& event_url, - extensions::EventFilteringInfo info) { - DCHECK(!event_args.empty()); - StringValue event_args_value(event_args); + const GURL& event_url) { linked_ptr<ExtensionEvent> event( - new ExtensionEvent(event_name, event_args_value, event_url, - restrict_to_profile, USER_GESTURE_UNKNOWN, info)); + new ExtensionEvent(event_name, event_args, event_url, + restrict_to_profile, "", USER_GESTURE_UNKNOWN)); DispatchEventImpl("", event); } -void ExtensionEventRouter::DispatchEventToRenderers( - const std::string& event_name, - const std::string& event_args, - Profile* restrict_to_profile, - const GURL& event_url) { - DispatchEventToRenderers(event_name, event_args, restrict_to_profile, - event_url, extensions::EventFilteringInfo()); -} - void ExtensionEventRouter::DispatchEventToExtension( const std::string& extension_id, const std::string& event_name, @@ -318,8 +291,7 @@ void ExtensionEventRouter::DispatchEventToExtension( DCHECK(!extension_id.empty()); linked_ptr<ExtensionEvent> event( new ExtensionEvent(event_name, event_args, event_url, - restrict_to_profile, USER_GESTURE_UNKNOWN, - EventFilteringInfo())); + restrict_to_profile, USER_GESTURE_UNKNOWN)); DispatchEventImpl(extension_id, event); } @@ -329,8 +301,8 @@ void ExtensionEventRouter::DispatchEventToExtension( const std::string& event_args, Profile* restrict_to_profile, const GURL& event_url) { - StringValue event_args_value(event_args); - DispatchEventToExtension(extension_id, event_name, event_args_value, + scoped_ptr<Value> event_args_value(Value::CreateStringValue(event_args)); + DispatchEventToExtension(extension_id, event_name, *event_args_value.get(), restrict_to_profile, event_url); } @@ -342,11 +314,9 @@ void ExtensionEventRouter::DispatchEventToExtension( const GURL& event_url, UserGestureState user_gesture) { DCHECK(!extension_id.empty()); - StringValue event_args_value(event_args); linked_ptr<ExtensionEvent> event( - new ExtensionEvent(event_name, event_args_value, event_url, - restrict_to_profile, user_gesture, - EventFilteringInfo())); + new ExtensionEvent(event_name, event_args, event_url, + restrict_to_profile, "", user_gesture)); DispatchEventImpl(extension_id, event); } @@ -359,57 +329,39 @@ void ExtensionEventRouter::DispatchEventsToRenderersAcrossIncognito( linked_ptr<ExtensionEvent> event( new ExtensionEvent(event_name, event_args, event_url, restrict_to_profile, cross_incognito_args, - USER_GESTURE_UNKNOWN, EventFilteringInfo())); + USER_GESTURE_UNKNOWN)); DispatchEventImpl("", event); } void ExtensionEventRouter::DispatchEventImpl( - const std::string& restrict_to_extension_id, + const std::string& extension_id, const linked_ptr<ExtensionEvent>& event) { // We don't expect to get events from a completely different profile. DCHECK(!event->restrict_to_profile || profile_->IsSameProfile(event->restrict_to_profile)); - std::set<const EventListener*> listeners( - listeners_.GetEventListeners(*event)); - for (std::set<const EventListener*>::iterator it = listeners.begin(); - it != listeners.end(); it++) { - const EventListener* listener = *it; - if (listener->process) { - if (restrict_to_extension_id.empty() || - restrict_to_extension_id == listener->extension_id) - DispatchEventToProcess(listener->extension_id, listener->process, - event); - } else { - DispatchLazyEvent(listener->extension_id, event); - } - } -} + LoadLazyBackgroundPagesForEvent(extension_id, event); -void ExtensionEventRouter::DispatchLazyEvent( - const std::string& extension_id, - const linked_ptr<ExtensionEvent>& event) { - ExtensionService* service = profile_->GetExtensionService(); - // Check both the original and the incognito profile to see if we - // should load a lazy bg page to handle the event. The latter case - // occurs in the case of split-mode extensions. - const Extension* extension = service->extensions()->GetByID(extension_id); - if (extension) { - MaybeLoadLazyBackgroundPageToDispatchEvent(profile_, extension, event); - if (profile_->HasOffTheRecordProfile() && - extension->incognito_split_mode()) { - MaybeLoadLazyBackgroundPageToDispatchEvent( - profile_->GetOffTheRecordProfile(), extension, event); - } + ListenerMap::iterator it = listeners_.find(event->event_name); + if (it == listeners_.end()) + return; + + std::set<ListenerProcess>& listeners = it->second; + for (std::set<ListenerProcess>::iterator listener = listeners.begin(); + listener != listeners.end(); ++listener) { + if (!extension_id.empty() && extension_id != listener->extension_id) + continue; + + DispatchEventToListener(*listener, event); } } -void ExtensionEventRouter::DispatchEventToProcess( - const std::string& extension_id, - content::RenderProcessHost* process, +void ExtensionEventRouter::DispatchEventToListener( + const ListenerProcess& listener, const linked_ptr<ExtensionEvent>& event) { ExtensionService* service = profile_->GetExtensionService(); - const Extension* extension = service->extensions()->GetByID(extension_id); + const Extension* extension = service->extensions()->GetByID( + listener.extension_id); // The extension could have been removed, but we do not unregister it until // the extension process is unloaded. @@ -417,13 +369,13 @@ void ExtensionEventRouter::DispatchEventToProcess( return; Profile* listener_profile = Profile::FromBrowserContext( - process->GetBrowserContext()); + listener.process->GetBrowserContext()); extensions::ProcessMap* process_map = listener_profile->GetExtensionService()->process_map(); // If the event is privileged, only send to extension processes. Otherwise, // it's OK to send to normal renderers (e.g., for content scripts). if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) && - !process_map->Contains(extension->id(), process->GetID())) { + !process_map->Contains(extension->id(), listener.process->GetID())) { return; } @@ -433,10 +385,9 @@ void ExtensionEventRouter::DispatchEventToProcess( return; } - DispatchEvent(process, extension_id, + DispatchEvent(listener.process, listener.extension_id, event->event_name, *event_args, - event->event_url, event->user_gesture, - event->info); + event->event_url, event->user_gesture); IncrementInFlightEvents(listener_profile, extension); } @@ -463,7 +414,38 @@ bool ExtensionEventRouter::CanDispatchEventToProfile( return true; } -void ExtensionEventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent( +void ExtensionEventRouter::LoadLazyBackgroundPagesForEvent( + const std::string& extension_id, + const linked_ptr<ExtensionEvent>& event) { + ExtensionService* service = profile_->GetExtensionService(); + + ListenerMap::iterator it = lazy_listeners_.find(event->event_name); + if (it == lazy_listeners_.end()) + return; + + std::set<ListenerProcess>& listeners = it->second; + for (std::set<ListenerProcess>::iterator listener = listeners.begin(); + listener != listeners.end(); ++listener) { + if (!extension_id.empty() && extension_id != listener->extension_id) + continue; + + // Check both the original and the incognito profile to see if we + // should load a lazy bg page to handle the event. The latter case + // occurs in the case of split-mode extensions. + const Extension* extension = service->extensions()->GetByID( + listener->extension_id); + if (extension) { + MaybeLoadLazyBackgroundPage(profile_, extension, event); + if (profile_->HasOffTheRecordProfile() && + extension->incognito_split_mode()) { + MaybeLoadLazyBackgroundPage( + profile_->GetOffTheRecordProfile(), extension, event); + } + } + } +} + +void ExtensionEventRouter::MaybeLoadLazyBackgroundPage( Profile* profile, const Extension* extension, const linked_ptr<ExtensionEvent>& event) { @@ -509,15 +491,14 @@ void ExtensionEventRouter::OnEventAck( } void ExtensionEventRouter::DispatchPendingEvent( - const linked_ptr<ExtensionEvent>& event, - ExtensionHost* host) { + const linked_ptr<ExtensionEvent>& event, ExtensionHost* host) { if (!host) return; - if (listeners_.HasProcessListener(host->render_process_host(), - host->extension()->id())) - DispatchEventToProcess(host->extension()->id(), - host->render_process_host(), event); + ListenerProcess listener(host->render_process_host(), + host->extension()->id()); + if (listeners_[event->event_name].count(listener) > 0u) + DispatchEventToListener(listener, event); } void ExtensionEventRouter::Observe( @@ -530,30 +511,45 @@ void ExtensionEventRouter::Observe( content::RenderProcessHost* renderer = content::Source<content::RenderProcessHost>(source).ptr(); // Remove all event listeners associated with this renderer. - listeners_.RemoveListenersForProcess(renderer); + for (ListenerMap::iterator it = listeners_.begin(); + it != listeners_.end(); ) { + ListenerMap::iterator current_it = it++; + for (std::set<ListenerProcess>::iterator jt = + current_it->second.begin(); + jt != current_it->second.end(); ) { + std::set<ListenerProcess>::iterator current_jt = jt++; + if (current_jt->process == renderer) { + RemoveEventListener(current_it->first, + current_jt->process, + current_jt->extension_id); + } + } + } break; } case chrome::NOTIFICATION_EXTENSION_LOADED: { // Add all registered lazy listeners to our cache. const Extension* extension = content::Details<const Extension>(details).ptr(); - ExtensionPrefs* prefs = - profile_->GetExtensionService()->extension_prefs(); std::set<std::string> registered_events = - prefs->GetRegisteredEvents(extension->id()); - listeners_.LoadUnfilteredLazyListeners(extension->id(), - registered_events); - const DictionaryValue* filtered_events = - prefs->GetFilteredEvents(extension->id()); - if (filtered_events) - listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); + profile_->GetExtensionService()->extension_prefs()-> + GetRegisteredEvents(extension->id()); + ListenerProcess lazy_listener(NULL, extension->id()); + for (std::set<std::string>::iterator it = registered_events.begin(); + it != registered_events.end(); ++it) { + lazy_listeners_[*it].insert(lazy_listener); + } break; } case chrome::NOTIFICATION_EXTENSION_UNLOADED: { // Remove all registered lazy listeners from our cache. extensions::UnloadedExtensionInfo* unloaded = content::Details<extensions::UnloadedExtensionInfo>(details).ptr(); - listeners_.RemoveLazyListenersForExtension(unloaded->extension->id()); + ListenerProcess lazy_listener(NULL, unloaded->extension->id()); + for (ListenerMap::iterator it = lazy_listeners_.begin(); + it != lazy_listeners_.end(); ++it) { + it->second.erase(lazy_listener); + } break; } case chrome::NOTIFICATION_EXTENSION_INSTALLED: { @@ -570,56 +566,3 @@ void ExtensionEventRouter::Observe( return; } } - -ExtensionEvent::ExtensionEvent( - const std::string& event_name, - const Value& event_args, - const GURL& event_url, - Profile* restrict_to_profile, - const Value& cross_incognito_args, - ExtensionEventRouter::UserGestureState user_gesture, - const extensions::EventFilteringInfo& info) - : event_name(event_name), - event_args(event_args.DeepCopy()), - event_url(event_url), - restrict_to_profile(restrict_to_profile), - cross_incognito_args(cross_incognito_args.DeepCopy()), - user_gesture(user_gesture), - info(info) { -} - -ExtensionEvent::ExtensionEvent( - const std::string& event_name, - const std::string& event_args, - const GURL& event_url, - Profile* restrict_to_profile, - const std::string& cross_incognito_args, - ExtensionEventRouter::UserGestureState user_gesture, - const extensions::EventFilteringInfo& info) - : event_name(event_name), - event_args(Value::CreateStringValue(event_args)), - event_url(event_url), - restrict_to_profile(restrict_to_profile), - cross_incognito_args(Value::CreateStringValue(cross_incognito_args)), - user_gesture(user_gesture), - info(info) { -} - -ExtensionEvent::ExtensionEvent( - const std::string& event_name, - const Value& event_args, - const GURL& event_url, - Profile* restrict_to_profile, - ExtensionEventRouter::UserGestureState user_gesture, - const extensions::EventFilteringInfo& info) - : event_name(event_name), - event_args(event_args.DeepCopy()), - event_url(event_url), - restrict_to_profile(restrict_to_profile), - cross_incognito_args(NULL), - user_gesture(user_gesture), - info(info) { -} - -ExtensionEvent::~ExtensionEvent() { -} diff --git a/chrome/browser/extensions/extension_event_router.h b/chrome/browser/extensions/extension_event_router.h index 4afc4a2..4bcfc0e 100644 --- a/chrome/browser/extensions/extension_event_router.h +++ b/chrome/browser/extensions/extension_event_router.h @@ -14,8 +14,6 @@ #include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "base/values.h" -#include "chrome/browser/extensions/event_listener_map.h" -#include "chrome/common/extensions/event_filtering_info.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "ipc/ipc_sender.h" @@ -33,14 +31,7 @@ namespace extensions { class Extension; } -struct ExtensionEvent; - -using extensions::EventFilteringInfo; -using extensions::EventListener; -using extensions::EventListenerMap; - -class ExtensionEventRouter : public content::NotificationObserver, - public extensions::EventListenerMap::Delegate { +class ExtensionEventRouter : public content::NotificationObserver { public: // These constants convey the state of our knowledge of whether we're in // a user-caused gesture as part of DispatchEvent. @@ -57,8 +48,7 @@ class ExtensionEventRouter : public content::NotificationObserver, const std::string& event_name, const base::Value& event_args, const GURL& event_url, - UserGestureState user_gesture, - const extensions::EventFilteringInfo& info); + UserGestureState user_gesture); // This invocation is deprecated. All future consumers of this API should be // sending Values as event arguments, using the above version. @@ -67,8 +57,7 @@ class ExtensionEventRouter : public content::NotificationObserver, const std::string& event_name, const std::string& event_args, const GURL& event_url, - UserGestureState user_gesture, - const extensions::EventFilteringInfo& info); + UserGestureState user_gesture); explicit ExtensionEventRouter(Profile* profile); virtual ~ExtensionEventRouter(); @@ -93,21 +82,6 @@ class ExtensionEventRouter : public content::NotificationObserver, void RemoveLazyEventListener(const std::string& event_name, const std::string& extension_id); - // If |add_lazy_listener| is true also add the lazy version of this listener. - void AddFilteredEventListener(const std::string& event_name, - content::RenderProcessHost* process, - const std::string& extension_id, - const base::DictionaryValue& filter, - bool add_lazy_listener); - - // If |remove_lazy_listener| is true also remove the lazy version of this - // listener. - void RemoveFilteredEventListener(const std::string& event_name, - content::RenderProcessHost* process, - const std::string& extension_id, - const base::DictionaryValue& filter, - bool remove_lazy_listener); - // Returns true if there is at least one listener for the given event. bool HasEventListener(const std::string& event_name); @@ -125,14 +99,6 @@ class ExtensionEventRouter : public content::NotificationObserver, const std::string& event_name, const std::string& event_args, Profile* restrict_to_profile, - const GURL& event_url, - extensions::EventFilteringInfo info); - - // As above, but defaults |info| to EventFilteringInfo(). - void DispatchEventToRenderers( - const std::string& event_name, - const std::string& event_args, - Profile* restrict_to_profile, const GURL& event_url); // Same as above, except only send the event to the given extension. @@ -180,6 +146,9 @@ class ExtensionEventRouter : public content::NotificationObserver, void OnEventAck(Profile* profile, const std::string& extension_id); private: + // The details of an event to be dispatched. + struct ExtensionEvent; + // The extension and process that contains the event listener for a given // event. struct ListenerProcess; @@ -199,21 +168,16 @@ class ExtensionEventRouter : public content::NotificationObserver, const std::string& extension_id, const std::string& event_name); - // Shared by DispatchEvent*. If |restrict_to_extension_id| is empty, the - // event is broadcast. + // Shared by DispatchEvent*. If |extension_id| is empty, the event is + // broadcast. If |process| is non-NULL, the event is only dispatched to that + // particular process. // An event that just came off the pending list may not be delayed again. - void DispatchEventImpl(const std::string& restrict_to_extension_id, - const linked_ptr<ExtensionEvent>& event); - - // Ensures that all lazy background pages that are interested in the given - // event are loaded, and queues the event if the page is not ready yet. - void DispatchLazyEvent(const std::string& extension_id, + void DispatchEventImpl(const std::string& extension_id, const linked_ptr<ExtensionEvent>& event); - // Dispatches the event to the specified extension running in |process|. - void DispatchEventToProcess(const std::string& extension_id, - content::RenderProcessHost* process, - const linked_ptr<ExtensionEvent>& event); + // Dispatches the event to a single listener process. + void DispatchEventToListener(const ListenerProcess& listener, + const linked_ptr<ExtensionEvent>& event); // Returns false when the event is scoped to a profile and the listening // extension does not have access to events from that profile. Also fills @@ -225,9 +189,17 @@ class ExtensionEventRouter : public content::NotificationObserver, const linked_ptr<ExtensionEvent>& event, const base::Value** event_args); + // Ensures that all lazy background pages that are interested in the given + // event are loaded, and queues the event if the page is not ready yet. + // If |extension_id| is non-empty, we load only that extension's page + // (assuming it is interested in the event). + void LoadLazyBackgroundPagesForEvent( + const std::string& extension_id, + const linked_ptr<ExtensionEvent>& event); + // Possibly loads given extension's background page in preparation to // dispatch an event. - void MaybeLoadLazyBackgroundPageToDispatchEvent( + void MaybeLoadLazyBackgroundPage( Profile* profile, const extensions::Extension* extension, const linked_ptr<ExtensionEvent>& event); @@ -240,57 +212,21 @@ class ExtensionEventRouter : public content::NotificationObserver, void DispatchPendingEvent(const linked_ptr<ExtensionEvent>& event, ExtensionHost* host); - // Implementation of extensions::EventListenerMap::Delegate. - virtual void OnListenerAdded(const EventListener* listener) OVERRIDE; - virtual void OnListenerRemoved(const EventListener* listener) OVERRIDE; - Profile* profile_; content::NotificationRegistrar registrar_; scoped_refptr<ExtensionDevToolsManager> extension_devtools_manager_; - EventListenerMap listeners_; + // The list of active extension processes that are listening to events. + ListenerMap listeners_; - DISALLOW_COPY_AND_ASSIGN(ExtensionEventRouter); -}; + // The list of all the lazy (non-persistent) background pages that are + // listening to events. This is just a cache of the real list, which is + // stored on disk in the extension prefs. + ListenerMap lazy_listeners_; -struct ExtensionEvent { - std::string event_name; - scoped_ptr<Value> event_args; - GURL event_url; - Profile* restrict_to_profile; - scoped_ptr<Value> cross_incognito_args; - ExtensionEventRouter::UserGestureState user_gesture; - extensions::EventFilteringInfo info; - - ExtensionEvent(const std::string& event_name, - const Value& event_args, - const GURL& event_url, - Profile* restrict_to_profile, - const Value& cross_incognito_args, - ExtensionEventRouter::UserGestureState user_gesture, - const extensions::EventFilteringInfo& info); - - // TODO(gdk): This variant should be retired once the callers are switched to - // providing Values instead of just strings. - ExtensionEvent(const std::string& event_name, - const std::string& event_args, - const GURL& event_url, - Profile* restrict_to_profile, - const std::string& cross_incognito_args, - ExtensionEventRouter::UserGestureState user_gesture, - const extensions::EventFilteringInfo& info); - - ExtensionEvent(const std::string& event_name, - const Value& event_args, - const GURL& event_url, - Profile* restrict_to_profile, - ExtensionEventRouter::UserGestureState user_gesture, - const extensions::EventFilteringInfo& info); - - ~ExtensionEvent(); + DISALLOW_COPY_AND_ASSIGN(ExtensionEventRouter); }; - #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_ diff --git a/chrome/browser/extensions/extension_event_router_forwarder.cc b/chrome/browser/extensions/extension_event_router_forwarder.cc index 5231324..f654d12 100644 --- a/chrome/browser/extensions/extension_event_router_forwarder.cc +++ b/chrome/browser/extensions/extension_event_router_forwarder.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -114,8 +114,7 @@ void ExtensionEventRouterForwarder::CallExtensionEventRouter( if (extension_id.empty()) { profile->GetExtensionEventRouter()-> DispatchEventToRenderers( - event_name, event_args, restrict_to_profile, event_url, - extensions::EventFilteringInfo()); + event_name, event_args, restrict_to_profile, event_url); } else { profile->GetExtensionEventRouter()-> DispatchEventToExtension( diff --git a/chrome/browser/extensions/extension_idle_api.cc b/chrome/browser/extensions/extension_idle_api.cc index 87ce764..8df6ac8 100644 --- a/chrome/browser/extensions/extension_idle_api.cc +++ b/chrome/browser/extensions/extension_idle_api.cc @@ -145,7 +145,7 @@ void ExtensionIdleEventRouter::OnIdleStateChange(Profile* profile, base::JSONWriter::Write(&args, &json_args); profile->GetExtensionEventRouter()->DispatchEventToRenderers( - keys::kOnStateChanged, json_args, profile, GURL(), EventFilteringInfo()); + keys::kOnStateChanged, json_args, profile, GURL()); } bool ExtensionIdleQueryStateFunction::RunImpl() { diff --git a/chrome/browser/extensions/extension_managed_mode_api.cc b/chrome/browser/extensions/extension_managed_mode_api.cc index 11e9f6f..efa05f8 100644 --- a/chrome/browser/extensions/extension_managed_mode_api.cc +++ b/chrome/browser/extensions/extension_managed_mode_api.cc @@ -66,9 +66,8 @@ void ExtensionManagedModeEventRouter::Observe( std::string json_args; base::JSONWriter::Write(&args, &json_args); ExtensionEventRouter* event_router = profile_->GetExtensionEventRouter(); - event_router->DispatchEventToRenderers(kChangeEventName, json_args, NULL, - GURL(), - extensions::EventFilteringInfo()); + event_router->DispatchEventToRenderers(kChangeEventName, json_args, + NULL, GURL()); } GetManagedModeFunction::~GetManagedModeFunction() { } diff --git a/chrome/browser/extensions/extension_management_api.cc b/chrome/browser/extensions/extension_management_api.cc index 6dfe438..3c5a998 100644 --- a/chrome/browser/extensions/extension_management_api.cc +++ b/chrome/browser/extensions/extension_management_api.cc @@ -589,5 +589,5 @@ void ExtensionManagementEventRouter::Observe( base::JSONWriter::Write(&args, &args_json); profile->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, args_json, NULL, GURL(), extensions::EventFilteringInfo()); + event_name, args_json, NULL, GURL()); } diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc index a61882d..afb94ca 100644 --- a/chrome/browser/extensions/extension_messages_apitest.cc +++ b/chrome/browser/extensions/extension_messages_apitest.cc @@ -31,23 +31,19 @@ class MessageSender : public content::NotificationObserver { event_router->DispatchEventToRenderers("test.onMessage", "[{\"lastMessage\":false,\"data\":\"no restriction\"}]", content::Source<Profile>(source).ptr(), - GURL(), - EventFilteringInfo()); + GURL()); event_router->DispatchEventToRenderers("test.onMessage", "[{\"lastMessage\":false,\"data\":\"http://a.com/\"}]", content::Source<Profile>(source).ptr(), - GURL("http://a.com/"), - EventFilteringInfo()); + GURL("http://a.com/")); event_router->DispatchEventToRenderers("test.onMessage", "[{\"lastMessage\":false,\"data\":\"http://b.com/\"}]", content::Source<Profile>(source).ptr(), - GURL("http://b.com/"), - EventFilteringInfo()); + GURL("http://b.com/")); event_router->DispatchEventToRenderers("test.onMessage", "[{\"lastMessage\":true,\"data\":\"last message\"}]", content::Source<Profile>(source).ptr(), - GURL(), - EventFilteringInfo()); + GURL()); } content::NotificationRegistrar registrar_; diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc index 7d210b9..19e01db 100644 --- a/chrome/browser/extensions/extension_prefs.cc +++ b/chrome/browser/extensions/extension_prefs.cc @@ -179,10 +179,6 @@ const char kPrefIncognitoContentSettings[] = "incognito_content_settings"; // background page. const char kRegisteredEvents[] = "events"; -// A dictionary of event names to lists of filters that this extension has -// registered from its lazy background page. -const char kFilteredEvents[] = "filtered_events"; - // Persisted value for omnibox.setDefaultSuggestion. const char kOmniboxDefaultSuggestion[] = "omnibox_default_suggestion"; @@ -990,59 +986,6 @@ std::set<std::string> ExtensionPrefs::GetRegisteredEvents( return events; } -void ExtensionPrefs::AddFilterToEvent(const std::string& event_name, - const std::string& extension_id, - const DictionaryValue* filter) { - ScopedExtensionPrefUpdate update(prefs_, extension_id); - DictionaryValue* extension_dict = update.Get(); - DictionaryValue* filtered_events = NULL; - if (!extension_dict->GetDictionary(kFilteredEvents, &filtered_events)) { - filtered_events = new DictionaryValue; - extension_dict->Set(kFilteredEvents, filtered_events); - } - ListValue* filter_list = NULL; - if (!filtered_events->GetList(event_name, &filter_list)) { - filter_list = new ListValue; - filtered_events->Set(event_name, filter_list); - } - - filter_list->Append(filter->DeepCopy()); -} - -void ExtensionPrefs::RemoveFilterFromEvent(const std::string& event_name, - const std::string& extension_id, - const DictionaryValue* filter) { - ScopedExtensionPrefUpdate update(prefs_, extension_id); - DictionaryValue* extension_dict = update.Get(); - DictionaryValue* filtered_events = NULL; - - if (!extension_dict->GetDictionary(kFilteredEvents, &filtered_events)) - return; - ListValue* filter_list = NULL; - if (!filtered_events->GetList(event_name, &filter_list)) - return; - - for (size_t i = 0; i < filter_list->GetSize(); i++) { - DictionaryValue* filter; - CHECK(filter_list->GetDictionary(i, &filter)); - if (filter->Equals(filter)) { - filter_list->Remove(i, NULL); - break; - } - } -} - -const DictionaryValue* ExtensionPrefs::GetFilteredEvents( - const std::string& extension_id) const { - const DictionaryValue* extension = GetExtensionPref(extension_id); - if (!extension) - return NULL; - DictionaryValue* result = NULL; - if (!extension->GetDictionary(kFilteredEvents, &result)) - return NULL; - return result; -} - void ExtensionPrefs::SetRegisteredEvents( const std::string& extension_id, const std::set<std::string>& events) { ListValue* value = new ListValue(); diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h index e142fe1..c5735c4 100644 --- a/chrome/browser/extensions/extension_prefs.h +++ b/chrome/browser/extensions/extension_prefs.h @@ -279,21 +279,6 @@ class ExtensionPrefs : public extensions::ContentSettingsStore::Observer, void SetRegisteredEvents(const std::string& extension_id, const std::set<std::string>& events); - // Adds a filter to an event. - void AddFilterToEvent(const std::string& event_name, - const std::string& extension_id, - const DictionaryValue* filter); - - // Removes a filter from an event. - void RemoveFilterFromEvent(const std::string& event_name, - const std::string& extension_id, - const DictionaryValue* filter); - - // Returns the dictionary of event filters that the given extension has - // registered. - const DictionaryValue* GetFilteredEvents( - const std::string& extension_id) const; - // Controls the omnibox default suggestion as set by the extension. extensions::ExtensionOmniboxSuggestion GetOmniboxDefaultSuggestion( const std::string& extension_id); diff --git a/chrome/browser/extensions/extension_processes_api.cc b/chrome/browser/extensions/extension_processes_api.cc index c853495..4607c50 100644 --- a/chrome/browser/extensions/extension_processes_api.cc +++ b/chrome/browser/extensions/extension_processes_api.cc @@ -489,7 +489,7 @@ void ExtensionProcessesEventRouter::DispatchEvent( const std::string& json_args) { if (profile && profile->GetExtensionEventRouter()) { profile->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, json_args, NULL, GURL(), EventFilteringInfo()); + event_name, json_args, NULL, GURL()); } } diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc index 23a067c..5a54454 100644 --- a/chrome/browser/extensions/lazy_background_page_apitest.cc +++ b/chrome/browser/extensions/lazy_background_page_apitest.cc @@ -167,22 +167,6 @@ IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, BroadcastEvent) { GetLocationBarForTesting()->PageActionVisibleCount()); } -IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, Filters) { - const Extension* extension = LoadExtensionAndWait("filters"); - ASSERT_TRUE(extension); - - // Lazy Background Page doesn't exist yet. - ExtensionProcessManager* pm = - browser()->profile()->GetExtensionProcessManager(); - EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id_)); - - // Open a tab to a URL that will fire a webNavigation event. - LazyBackgroundObserver page_complete; - ui_test_utils::NavigateToURL( - browser(), test_server()->GetURL("files/extensions/test_file.html")); - page_complete.Wait(); -} - // Tests that the lazy background page receives the onInstalled event and shuts // down. IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnInstalled) { diff --git a/chrome/browser/extensions/system/system_api.cc b/chrome/browser/extensions/system/system_api.cc index 042eb35..b80538f 100644 --- a/chrome/browser/extensions/system/system_api.cc +++ b/chrome/browser/extensions/system/system_api.cc @@ -60,7 +60,7 @@ void DispatchEvent(const std::string& event_name, const ListValue& args) { std::string json_args; base::JSONWriter::Write(&args, &json_args); extension_event_router->DispatchEventToRenderers( - event_name, json_args, NULL, GURL(), extensions::EventFilteringInfo()); + event_name, json_args, NULL, GURL()); } } // namespace diff --git a/chrome/browser/history/history_extension_api.cc b/chrome/browser/history/history_extension_api.cc index a55d095..b020762 100644 --- a/chrome/browser/history/history_extension_api.cc +++ b/chrome/browser/history/history_extension_api.cc @@ -163,8 +163,7 @@ void HistoryExtensionEventRouter::DispatchEvent(Profile* profile, const std::string& json_args) { if (profile && profile->GetExtensionEventRouter()) { profile->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, json_args, profile, GURL(), - extensions::EventFilteringInfo()); + event_name, json_args, profile, GURL()); } } diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc index cb1855b..b32c441 100644 --- a/chrome/browser/renderer_host/chrome_render_message_filter.cc +++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc @@ -95,10 +95,6 @@ bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message, OnExtensionAddLazyListener) IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener, OnExtensionRemoveLazyListener) - IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener, - OnExtensionAddFilteredListener) - IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener, - OnExtensionRemoveFilteredListener) IPC_MESSAGE_HANDLER(ExtensionHostMsg_CloseChannel, OnExtensionCloseChannel) IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestForIOThread, OnExtensionRequestForIOThread) @@ -151,8 +147,6 @@ void ChromeRenderMessageFilter::OverrideThreadForMessage( case ExtensionHostMsg_RemoveListener::ID: case ExtensionHostMsg_AddLazyListener::ID: case ExtensionHostMsg_RemoveLazyListener::ID: - case ExtensionHostMsg_AddFilteredListener::ID: - case ExtensionHostMsg_RemoveFilteredListener::ID: case ExtensionHostMsg_CloseChannel::ID: case ExtensionHostMsg_ShouldUnloadAck::ID: case ExtensionHostMsg_UnloadAck::ID: @@ -388,34 +382,6 @@ void ChromeRenderMessageFilter::OnExtensionRemoveLazyListener( event_name, extension_id); } -void ChromeRenderMessageFilter::OnExtensionAddFilteredListener( - const std::string& extension_id, - const std::string& event_name, - const base::DictionaryValue& filter, - bool lazy) { - content::RenderProcessHost* process = - content::RenderProcessHost::FromID(render_process_id_); - if (!process || !profile_->GetExtensionEventRouter()) - return; - - profile_->GetExtensionEventRouter()->AddFilteredEventListener( - event_name, process, extension_id, filter, lazy); -} - -void ChromeRenderMessageFilter::OnExtensionRemoveFilteredListener( - const std::string& extension_id, - const std::string& event_name, - const base::DictionaryValue& filter, - bool lazy) { - content::RenderProcessHost* process = - content::RenderProcessHost::FromID(render_process_id_); - if (!process || !profile_->GetExtensionEventRouter()) - return; - - profile_->GetExtensionEventRouter()->RemoveFilteredEventListener( - event_name, process, extension_id, filter, lazy); -} - void ChromeRenderMessageFilter::OnExtensionCloseChannel(int port_id, bool connection_error) { if (!content::RenderProcessHost::FromID(render_process_id_)) diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.h b/chrome/browser/renderer_host/chrome_render_message_filter.h index 6adc895..45efb40 100644 --- a/chrome/browser/renderer_host/chrome_render_message_filter.h +++ b/chrome/browser/renderer_host/chrome_render_message_filter.h @@ -117,14 +117,6 @@ class ChromeRenderMessageFilter : public content::BrowserMessageFilter { const std::string& event_name); void OnExtensionRemoveLazyListener(const std::string& extension_id, const std::string& event_name); - void OnExtensionAddFilteredListener(const std::string& extension_id, - const std::string& event_name, - const base::DictionaryValue& filter, - bool lazy); - void OnExtensionRemoveFilteredListener(const std::string& extension_id, - const std::string& event_name, - const base::DictionaryValue& filter, - bool lazy); void OnExtensionCloseChannel(int port_id, bool connection_error); void OnExtensionRequestForIOThread( int routing_id, diff --git a/chrome/browser/ui/cocoa/menu_controller_unittest.mm b/chrome/browser/ui/cocoa/menu_controller_unittest.mm index 5bfd3c6..04f0ed8 100644 --- a/chrome/browser/ui/cocoa/menu_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/menu_controller_unittest.mm @@ -16,8 +16,6 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image/image_skia.h" -namespace { - class MenuControllerTest : public CocoaTest { }; @@ -332,5 +330,3 @@ TEST_F(MenuControllerTest, OpenClose) { // Expect that the delegate got notified properly. EXPECT_TRUE(delegate.did_close_); } - -} // namespace diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 9f54b92..db23bc6 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -261,8 +261,6 @@ 'browser/extensions/default_apps.h', 'browser/extensions/default_apps_trial.cc', 'browser/extensions/default_apps_trial.h', - 'browser/extensions/event_listener_map.cc', - 'browser/extensions/event_listener_map.h', 'browser/extensions/extension_activity_log.cc', 'browser/extensions/extension_activity_log.h', 'browser/extensions/extension_browser_event_router.cc', diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 19cf9d7..4ccee53 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -192,8 +192,6 @@ 'common/extensions/url_pattern_set.h', 'common/extensions/user_script.cc', 'common/extensions/user_script.h', - 'common/extensions/value_counter.cc', - 'common/extensions/value_counter.h', 'common/extensions/api/extension_api.cc', 'common/extensions/api/extension_api.h', 'common/external_ipc_fuzzer.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index fc9b162..59ccc51 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1224,7 +1224,6 @@ 'browser/extensions/component_loader_unittest.cc', 'browser/extensions/convert_user_script_unittest.cc', 'browser/extensions/convert_web_app_unittest.cc', - 'browser/extensions/event_listener_map_unittest.cc', 'browser/extensions/extension_creator_filter_unittest.cc', 'browser/extensions/extension_event_router_forwarder_unittest.cc', 'browser/extensions/extension_function_test_utils.cc', @@ -1934,7 +1933,6 @@ 'common/extensions/url_pattern_set_unittest.cc', 'common/extensions/url_pattern_unittest.cc', 'common/extensions/user_script_unittest.cc', - 'common/extensions/value_counter_unittest.cc', 'common/extensions/api/extension_api_unittest.cc', 'common/important_file_writer_unittest.cc', 'common/json_pref_store_unittest.cc', diff --git a/chrome/common/extensions/api/web_navigation.json b/chrome/common/extensions/api/web_navigation.json index 5534297..cbfc720 100644 --- a/chrome/common/extensions/api/web_navigation.json +++ b/chrome/common/extensions/api/web_navigation.json @@ -91,11 +91,6 @@ "name": "onBeforeNavigate", "type": "function", "description": "Fired when a navigation is about to occur.", - "options": { - "supportsFilters": true, - "supportsListeners": true, - "supportsRules": false - }, "parameters": [ { "type": "object", @@ -113,11 +108,6 @@ "name": "onCommitted", "type": "function", "description": "Fired when a navigation is committed. The document (and the resources it refers to, such as images and subframes) might still be downloading, but at least part of the document has been received from the server and the browser has decided to switch to the new document.", - "options": { - "supportsFilters": true, - "supportsListeners": true, - "supportsRules": false - }, "parameters": [ { "type": "object", @@ -137,11 +127,6 @@ "name": "onDOMContentLoaded", "type": "function", "description": "Fired when the page's DOM is fully constructed, but the referenced resources may not finish loading.", - "options": { - "supportsFilters": true, - "supportsListeners": true, - "supportsRules": false - }, "parameters": [ { "type": "object", @@ -159,11 +144,6 @@ "name": "onCompleted", "type": "function", "description": "Fired when a document, including the resources it refers to, is completely loaded and initialized.", - "options": { - "supportsFilters": true, - "supportsListeners": true, - "supportsRules": false - }, "parameters": [ { "type": "object", @@ -181,11 +161,6 @@ "name": "onErrorOccurred", "type": "function", "description": "Fired when an error occurs and the navigation is aborted. This can happen if either a network error occurred, or the user aborted the navigation.", - "options": { - "supportsFilters": true, - "supportsListeners": true, - "supportsRules": false - }, "parameters": [ { "type": "object", @@ -204,11 +179,6 @@ "name": "onCreatedNavigationTarget", "type": "function", "description": "Fired when a new window, or a new tab in an existing window, is created to host a navigation.", - "options": { - "supportsFilters": true, - "supportsListeners": true, - "supportsRules": false - }, "parameters": [ { "type": "object", @@ -227,11 +197,6 @@ "name": "onReferenceFragmentUpdated", "type": "function", "description": "Fired when the reference fragment of a frame was updated. All future events for that frame will use the updated URL.", - "options": { - "supportsFilters": true, - "supportsListeners": true, - "supportsRules": false - }, "parameters": [ { "type": "object", diff --git a/chrome/common/extensions/event_filtering_info.cc b/chrome/common/extensions/event_filtering_info.cc index 1e30283..1b61399 100644 --- a/chrome/common/extensions/event_filtering_info.cc +++ b/chrome/common/extensions/event_filtering_info.cc @@ -31,18 +31,4 @@ std::string EventFilteringInfo::AsJSONString() const { return result; } -scoped_ptr<base::Value> EventFilteringInfo::AsValue() const { - if (IsEmpty()) - return scoped_ptr<base::Value>(base::Value::CreateNullValue()); - - scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); - if (has_url_) - result->SetString("url", url_.spec()); - return result.PassAs<base::Value>(); -} - -bool EventFilteringInfo::IsEmpty() const { - return !has_url_; -} - } // namespace extensions diff --git a/chrome/common/extensions/event_filtering_info.h b/chrome/common/extensions/event_filtering_info.h index b137c56..89d4d32 100644 --- a/chrome/common/extensions/event_filtering_info.h +++ b/chrome/common/extensions/event_filtering_info.h @@ -6,13 +6,7 @@ #define CHROME_COMMON_EXTENSIONS_EVENT_FILTERING_INFO_H_ #pragma once -#include "base/memory/scoped_ptr.h" #include "googleurl/src/gurl.h" -#include "v8/include/v8.h" - -namespace base { -class Value; -} namespace extensions { @@ -34,8 +28,6 @@ class EventFilteringInfo { const GURL& url() const { return url_; } std::string AsJSONString() const; - scoped_ptr<base::Value> AsValue() const; - bool IsEmpty() const; private: bool has_url_; diff --git a/chrome/common/extensions/extension_messages.h b/chrome/common/extensions/extension_messages.h index 8499d09..18b9be7 100644 --- a/chrome/common/extensions/extension_messages.h +++ b/chrome/common/extensions/extension_messages.h @@ -367,22 +367,6 @@ IPC_MESSAGE_CONTROL2(ExtensionHostMsg_RemoveLazyListener, std::string /* extension_id */, std::string /* name */) -// Notify the browser that the given extension added a listener to instances of -// the named event that satisfy the filter. -IPC_MESSAGE_CONTROL4(ExtensionHostMsg_AddFilteredListener, - std::string /* extension_id */, - std::string /* name */, - DictionaryValue /* filter */, - bool /* lazy */) - -// Notify the browser that the given extension is no longer interested in -// instances of the named event that satisfy the filter. -IPC_MESSAGE_CONTROL4(ExtensionHostMsg_RemoveFilteredListener, - std::string /* extension_id */, - std::string /* name */, - DictionaryValue /* filter */, - bool /* lazy */) - // Notify the browser that an event has finished being dispatched. IPC_MESSAGE_ROUTED0(ExtensionHostMsg_EventAck) diff --git a/chrome/common/extensions/value_counter.cc b/chrome/common/extensions/value_counter.cc deleted file mode 100644 index 156e3ad..0000000 --- a/chrome/common/extensions/value_counter.cc +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/common/extensions/value_counter.h" - -#include "base/values.h" - -#include <algorithm> - -namespace extensions { - -ValueCounter::ValueCounter() { -} - -ValueCounter::~ValueCounter() { -} - -ValueCounter::Entry::Entry(const base::Value& value) - : value_(value.DeepCopy()), - count_(1) { -} - -ValueCounter::Entry::~Entry() { -} - -int ValueCounter::Entry::Increment() { - return ++count_; -} - -int ValueCounter::Entry::Decrement() { - return --count_; -} - -int ValueCounter::Add(const base::Value& value) { - return AddImpl(value, true); -} - -int ValueCounter::Remove(const base::Value& value) { - for (EntryList::iterator it = entries_.begin(); it != entries_.end(); it++) { - (*it)->value()->GetType(); - if ((*it)->value()->Equals(&value)) { - int remaining = (*it)->Decrement(); - if (remaining == 0) { - std::swap(*it, entries_.back()); - entries_.pop_back(); - } - return remaining; - } - } - return 0; -} - -int ValueCounter::AddIfMissing(const base::Value& value) { - return AddImpl(value, false); -} - -int ValueCounter::AddImpl(const base::Value& value, bool increment) { - for (EntryList::iterator it = entries_.begin(); it != entries_.end(); it++) { - if ((*it)->value()->Equals(&value)) - return increment ? (*it)->Increment() : (*it)->count(); - } - entries_.push_back(linked_ptr<Entry>(new Entry(value))); - return 1; -} - -} // namespace extensions diff --git a/chrome/common/extensions/value_counter.h b/chrome/common/extensions/value_counter.h deleted file mode 100644 index 52c719c..0000000 --- a/chrome/common/extensions/value_counter.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_EXTENSIONS_VALUE_COUNTER_H_ -#define CHROME_COMMON_EXTENSIONS_VALUE_COUNTER_H_ -#pragma once - -#include "base/memory/linked_ptr.h" - -#include <vector> - -namespace base { -class Value; -} - -namespace extensions { - -// Keeps a running count of Values, like map<Value, int>. Adding / removing -// values increments / decrements the count associated with a given Value. -// -// Add() and Remove() are linear in the number of Values in the ValueCounter, -// because there is no operator<() defined on Value, so we must iterate to find -// whether a Value is equal to an existing one. -class ValueCounter { - public: - ValueCounter(); - ~ValueCounter(); - - // Adds |value| to the set and returns how many equal values are in the set - // after. Does not take ownership of |value|. In the case where a Value equal - // to |value| doesn't already exist in this map, this function makes a - // DeepCopy() of |value|. - int Add(const base::Value& value); - - // Removes |value| from the set and returns how many equal values are in - // the set after. - int Remove(const base::Value& value); - - // Same as Add() but only performs the add if the value isn't present. - int AddIfMissing(const base::Value& value); - - private: - class Entry { - public: - explicit Entry(const base::Value& value); - ~Entry(); - - int Increment(); - int Decrement(); - - const base::Value* value() const { return value_.get(); } - int count() const { return count_; } - - private: - linked_ptr<base::Value> value_; - int count_; - - DISALLOW_COPY_AND_ASSIGN(Entry); - }; - typedef std::vector<linked_ptr<Entry> > EntryList; - - int AddImpl(const base::Value& value, bool increment); - - EntryList entries_; - - DISALLOW_COPY_AND_ASSIGN(ValueCounter); -}; - -} // namespace extensions - -#endif // CHROME_COMMON_EXTENSIONS_VALUE_COUNTER_H_ diff --git a/chrome/common/extensions/value_counter_unittest.cc b/chrome/common/extensions/value_counter_unittest.cc deleted file mode 100644 index 6ad7454..0000000 --- a/chrome/common/extensions/value_counter_unittest.cc +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/memory/scoped_ptr.h" -#include "base/values.h" -#include "chrome/common/extensions/value_counter.h" -#include "testing/gtest/include/gtest/gtest.h" - -class ValueCounterUnittest : public testing::Test { -}; - -TEST_F(ValueCounterUnittest, TestAddingSameValue) { - extensions::ValueCounter vc; - base::ListValue value; - ASSERT_EQ(1, vc.Add(value)); - ASSERT_EQ(2, vc.Add(value)); -} - -TEST_F(ValueCounterUnittest, TestAddingDifferentValue) { - extensions::ValueCounter vc; - base::ListValue value1; - base::DictionaryValue value2; - ASSERT_EQ(1, vc.Add(value1)); - ASSERT_EQ(1, vc.Add(value2)); -} - -TEST_F(ValueCounterUnittest, TestRemovingValue) { - extensions::ValueCounter vc; - base::ListValue value; - ASSERT_EQ(1, vc.Add(value)); - ASSERT_EQ(2, vc.Add(value)); - ASSERT_EQ(1, vc.Remove(value)); - ASSERT_EQ(0, vc.Remove(value)); -} - -TEST_F(ValueCounterUnittest, TestAddIfMissing) { - extensions::ValueCounter vc; - base::ListValue value; - ASSERT_EQ(1, vc.AddIfMissing(value)); - ASSERT_EQ(1, vc.AddIfMissing(value)); -} diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc index 06d9dbc..94a0203 100644 --- a/chrome/renderer/extensions/event_bindings.cc +++ b/chrome/renderer/extensions/event_bindings.cc @@ -6,15 +6,11 @@ #include <vector> -#include "base/bind.h" #include "base/basictypes.h" #include "base/lazy_instance.h" -#include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "chrome/common/extensions/extension_messages.h" #include "chrome/common/extensions/extension_set.h" -#include "chrome/common/extensions/event_filter.h" -#include "chrome/common/extensions/value_counter.h" #include "chrome/common/url_constants.h" #include "chrome/common/view_type.h" #include "chrome/renderer/extensions/chrome_v8_context.h" @@ -25,7 +21,6 @@ #include "chrome/renderer/extensions/extension_helper.h" #include "chrome/renderer/extensions/user_script_slave.h" #include "content/public/renderer/render_thread.h" -#include "content/public/renderer/v8_value_converter.h" #include "googleurl/src/gurl.h" #include "grit/renderer_resources.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" @@ -53,57 +48,33 @@ typedef std::map<std::string, int> EventListenerCounts; base::LazyInstance<std::map<std::string, EventListenerCounts> > g_listener_counts = LAZY_INSTANCE_INITIALIZER; -// A map of event names to a (filter -> count) map. The map is used to keep -// track of which filters are in effect for which events. -// We notify the browser about filtered event listeners when we transition -// between 0 and 1. -typedef std::map<std::string, linked_ptr<extensions::ValueCounter> > - FilteredEventListenerCounts; - -// A map of extension IDs to filtered listener counts for that extension. -base::LazyInstance<std::map<std::string, FilteredEventListenerCounts> > - g_filtered_listener_counts = LAZY_INSTANCE_INITIALIZER; - // TODO(koz): Merge this into EventBindings. class ExtensionImpl : public ChromeV8Extension { public: - ExtensionImpl(ExtensionDispatcher* dispatcher, - extensions::EventFilter* event_filter) - : ChromeV8Extension(dispatcher), - event_filter_(event_filter) { - RouteFunction("AttachEvent", - base::Bind(&ExtensionImpl::AttachEvent, - base::Unretained(this))); - RouteFunction("DetachEvent", - base::Bind(&ExtensionImpl::DetachEvent, - base::Unretained(this))); - RouteFunction("AttachFilteredEvent", - base::Bind(&ExtensionImpl::AttachFilteredEvent, - base::Unretained(this))); - RouteFunction("DetachFilteredEvent", - base::Bind(&ExtensionImpl::DetachFilteredEvent, - base::Unretained(this))); - RouteFunction("MatchAgainstEventFilter", - base::Bind(&ExtensionImpl::MatchAgainstEventFilter, - base::Unretained(this))); + explicit ExtensionImpl(ExtensionDispatcher* dispatcher) + : ChromeV8Extension(dispatcher) { + RouteStaticFunction("AttachEvent", &AttachEvent); + RouteStaticFunction("DetachEvent", &DetachEvent); } ~ExtensionImpl() {} // Attach an event name to an object. - v8::Handle<v8::Value> AttachEvent(const v8::Arguments& args) { + static v8::Handle<v8::Value> AttachEvent(const v8::Arguments& args) { DCHECK(args.Length() == 1); // TODO(erikkay) should enforce that event name is a string in the bindings DCHECK(args[0]->IsString() || args[0]->IsUndefined()); if (args[0]->IsString()) { - std::string event_name = *v8::String::AsciiValue(args[0]->ToString()); + ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); const ChromeV8ContextSet& context_set = - extension_dispatcher()->v8_context_set(); + self->extension_dispatcher()->v8_context_set(); ChromeV8Context* context = context_set.GetCurrent(); CHECK(context); + std::string event_name(*v8::String::AsciiValue(args[0])); - if (!extension_dispatcher()->CheckCurrentContextAccessToExtensionAPI( + ExtensionDispatcher* extension_dispatcher = self->extension_dispatcher(); + if (!extension_dispatcher->CheckCurrentContextAccessToExtensionAPI( event_name)) return v8::Undefined(); @@ -118,25 +89,24 @@ class ExtensionImpl : public ChromeV8Extension { // This is called the first time the page has added a listener. Since // the background page is the only lazy page, we know this is the first // time this listener has been registered. - if (IsLazyBackgroundPage(context->extension())) { + if (self->IsLazyBackgroundPage(context->extension())) { content::RenderThread::Get()->Send( new ExtensionHostMsg_AddLazyListener(extension_id, event_name)); } } + return v8::Undefined(); } - v8::Handle<v8::Value> DetachEvent(const v8::Arguments& args) { + static v8::Handle<v8::Value> DetachEvent(const v8::Arguments& args) { DCHECK(args.Length() == 2); // TODO(erikkay) should enforce that event name is a string in the bindings DCHECK(args[0]->IsString() || args[0]->IsUndefined()); if (args[0]->IsString() && args[1]->IsBoolean()) { - std::string event_name = *v8::String::AsciiValue(args[0]->ToString()); - bool is_manual = args[1]->BooleanValue(); - + ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args); const ChromeV8ContextSet& context_set = - extension_dispatcher()->v8_context_set(); + self->extension_dispatcher()->v8_context_set(); ChromeV8Context* context = context_set.GetCurrent(); if (!context) return v8::Undefined(); @@ -144,6 +114,8 @@ class ExtensionImpl : public ChromeV8Extension { std::string extension_id = context->GetExtensionID(); EventListenerCounts& listener_counts = g_listener_counts.Get()[extension_id]; + std::string event_name(*v8::String::AsciiValue(args[0])); + bool is_manual = args[1]->BooleanValue(); if (--listener_counts[event_name] == 0) { content::RenderThread::Get()->Send( @@ -154,164 +126,17 @@ class ExtensionImpl : public ChromeV8Extension { // removed. If the context is the background page, and it removes the // last listener manually, then we assume that it is no longer interested // in being awakened for this event. - if (is_manual && IsLazyBackgroundPage(context->extension())) { + if (is_manual && self->IsLazyBackgroundPage(context->extension())) { content::RenderThread::Get()->Send( new ExtensionHostMsg_RemoveLazyListener(extension_id, event_name)); } } - return v8::Undefined(); - } - - // MatcherID AttachFilteredEvent(string event_name, object filter) - // event_name - Name of the event to attach. - // filter - Which instances of the named event are we interested in. - // returns the id assigned to the listener, which will be returned from calls - // to MatchAgainstEventFilter where this listener matches. - v8::Handle<v8::Value> AttachFilteredEvent(const v8::Arguments& args) { - DCHECK_EQ(2, args.Length()); - DCHECK(args[0]->IsString()); - DCHECK(args[1]->IsObject()); - - const ChromeV8ContextSet& context_set = - extension_dispatcher()->v8_context_set(); - ChromeV8Context* context = context_set.GetCurrent(); - DCHECK(context); - if (!context) - return v8::Integer::New(-1); - - std::string event_name = *v8::String::AsciiValue(args[0]); - // This method throws an exception if it returns false. - if (!extension_dispatcher()->CheckCurrentContextAccessToExtensionAPI( - event_name)) - return v8::Undefined(); - - std::string extension_id = context->GetExtensionID(); - if (extension_id.empty()) - return v8::Integer::New(-1); - - scoped_ptr<base::DictionaryValue> filter; - scoped_ptr<content::V8ValueConverter> converter( - content::V8ValueConverter::create()); - - base::DictionaryValue* filter_dict = NULL; - base::Value* filter_value = converter->FromV8Value(args[1]->ToObject(), - v8::Context::GetCurrent()); - if (!filter_value->GetAsDictionary(&filter_dict)) { - delete filter_value; - return v8::Integer::New(-1); - } - - filter.reset(filter_dict); - int id = event_filter_->AddEventMatcher(event_name, ParseEventMatcher( - filter.get())); - - // Only send IPCs the first time a filter gets added. - if (AddFilter(event_name, extension_id, filter.get())) { - bool lazy = IsLazyBackgroundPage(context->extension()); - content::RenderThread::Get()->Send( - new ExtensionHostMsg_AddFilteredListener(extension_id, event_name, - *filter, lazy)); - } - - return v8::Integer::New(id); - } - - // Add a filter to |event_name| in |extension_id|, returning true if it - // was the first filter for that event in that extension. - bool AddFilter(const std::string& event_name, - const std::string& extension_id, - base::DictionaryValue* filter) { - FilteredEventListenerCounts& counts = - g_filtered_listener_counts.Get()[extension_id]; - FilteredEventListenerCounts::iterator it = counts.find(event_name); - if (it == counts.end()) - counts[event_name].reset(new extensions::ValueCounter); - - int result = counts[event_name]->Add(*filter); - return 1 == result; - } - - // Remove a filter from |event_name| in |extension_id|, returning true if it - // was the last filter for that event in that extension. - bool RemoveFilter(const std::string& event_name, - const std::string& extension_id, - base::DictionaryValue* filter) { - FilteredEventListenerCounts& counts = - g_filtered_listener_counts.Get()[extension_id]; - FilteredEventListenerCounts::iterator it = counts.find(event_name); - if (it == counts.end()) - return false; - return 0 == it->second->Remove(*filter); - } - - // void DetachFilteredEvent(int id, bool manual) - // id - Id of the event to detach. - // manual - false if this is part of the extension unload process where all - // listeners are automatically detached. - v8::Handle<v8::Value> DetachFilteredEvent(const v8::Arguments& args) { - DCHECK_EQ(2, args.Length()); - DCHECK(args[0]->IsInt32()); - DCHECK(args[1]->IsBoolean()); - bool is_manual = args[1]->BooleanValue(); - const ChromeV8ContextSet& context_set = - extension_dispatcher()->v8_context_set(); - ChromeV8Context* context = context_set.GetCurrent(); - if (!context) - return v8::Undefined(); - - std::string extension_id = context->GetExtensionID(); - if (extension_id.empty()) - return v8::Undefined(); - - int matcher_id = args[0]->Int32Value(); - extensions::EventMatcher* event_matcher = - event_filter_->GetEventMatcher(matcher_id); - - const std::string& event_name = event_filter_->GetEventName(matcher_id); - - // Only send IPCs the last time a filter gets removed. - if (RemoveFilter(event_name, extension_id, event_matcher->value())) { - bool lazy = is_manual && IsLazyBackgroundPage(context->extension()); - content::RenderThread::Get()->Send( - new ExtensionHostMsg_RemoveFilteredListener(extension_id, event_name, - *event_matcher->value(), - lazy)); - } - - event_filter_->RemoveEventMatcher(matcher_id); return v8::Undefined(); } - v8::Handle<v8::Value> MatchAgainstEventFilter(const v8::Arguments& args) { - typedef std::set<extensions::EventFilter::MatcherID> MatcherIDs; - - std::string event_name = *v8::String::AsciiValue(args[0]->ToString()); - extensions::EventFilteringInfo info = ParseFromObject(args[1]->ToObject()); - MatcherIDs matched_event_filters = event_filter_->MatchEvent( - event_name, info); - v8::Handle<v8::Array> array(v8::Array::New(matched_event_filters.size())); - int i = 0; - for (MatcherIDs::iterator it = matched_event_filters.begin(); - it != matched_event_filters.end(); ++it) { - array->Set(v8::Integer::New(i++), v8::Integer::New(*it)); - } - return array; - } - - extensions::EventFilteringInfo ParseFromObject( - v8::Handle<v8::Object> object) { - extensions::EventFilteringInfo info; - v8::Handle<v8::String> url(v8::String::New("url")); - if (object->Has(url)) { - v8::Handle<v8::Value> url_value(object->Get(url)); - info.SetURL(GURL(*v8::String::AsciiValue(url_value))); - } - return info; - } - private: - extensions::EventFilter* event_filter_; + bool IsLazyBackgroundPage(const Extension* extension) { content::RenderView* render_view = GetCurrentRenderView(); if (!render_view) @@ -321,18 +146,10 @@ class ExtensionImpl : public ChromeV8Extension { return (extension && extension->has_lazy_background_page() && helper->view_type() == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); } - - scoped_ptr<extensions::EventMatcher> ParseEventMatcher( - base::DictionaryValue* filter_dict) { - return scoped_ptr<extensions::EventMatcher>(new extensions::EventMatcher( - scoped_ptr<base::DictionaryValue>(filter_dict->DeepCopy()))); - } }; } // namespace -// static -ChromeV8Extension* EventBindings::Get(ExtensionDispatcher* dispatcher, - extensions::EventFilter* event_filter) { - return new ExtensionImpl(dispatcher, event_filter); +ChromeV8Extension* EventBindings::Get(ExtensionDispatcher* dispatcher) { + return new ExtensionImpl(dispatcher); } diff --git a/chrome/renderer/extensions/event_bindings.h b/chrome/renderer/extensions/event_bindings.h index 17b32d5..baa2004 100644 --- a/chrome/renderer/extensions/event_bindings.h +++ b/chrome/renderer/extensions/event_bindings.h @@ -9,10 +9,6 @@ class ChromeV8Extension; class ExtensionDispatcher; -namespace extensions { -class EventFilter; -} - namespace v8 { class Extension; } @@ -20,8 +16,7 @@ class Extension; // This class deals with the javascript bindings related to Event objects. class EventBindings { public: - static ChromeV8Extension* Get(ExtensionDispatcher* dispatcher, - extensions::EventFilter* event_filter); + static ChromeV8Extension* Get(ExtensionDispatcher* dispatcher); }; #endif // CHROME_RENDERER_EXTENSIONS_EVENT_BINDINGS_H_ diff --git a/chrome/renderer/extensions/event_unittest.cc b/chrome/renderer/extensions/event_unittest.cc index 4b0619f..947d3e8 100644 --- a/chrome/renderer/extensions/event_unittest.cc +++ b/chrome/renderer/extensions/event_unittest.cc @@ -22,41 +22,13 @@ class EventUnittest : public ModuleSystemTest { OverrideNativeHandler("event_bindings", "var assert = requireNative('assert');" "var attachedListeners = exports.attachedListeners = {};" - "var attachedFilteredListeners = " - " exports.attachedFilteredListeners = {};" - "var nextId = 0;" - "var idToName = {};" - "exports.AttachEvent = function(eventName) {" " assert.AssertFalse(!!attachedListeners[eventName]);" " attachedListeners[eventName] = 1;" "};" - "exports.DetachEvent = function(eventName) {" " assert.AssertTrue(!!attachedListeners[eventName]);" " delete attachedListeners[eventName];" - "};" - - "exports.IsEventAttached = function(eventName) {" - " return !!attachedListeners[eventName];" - "};" - - "exports.AttachFilteredEvent = function(name, filters) {" - " var id = nextId++;" - " idToName[id] = name;" - " attachedFilteredListeners[name] =" - " attachedFilteredListeners[name] || [];" - " attachedFilteredListeners[name][id] = filters;" - " return id;" - "};" - - "exports.DetachFilteredEvent = function(id, manual) {" - " var i = attachedFilteredListeners[idToName[id]].indexOf(id);" - " attachedFilteredListeners[idToName[id]].splice(i, 1);" - "};" - - "exports.HasFilteredListener = function(name) {" - " return attachedFilteredListeners[name].length;" "};"); OverrideNativeHandler("chrome_hidden", "var chromeHidden = {};" @@ -90,39 +62,6 @@ TEST_F(EventUnittest, AddRemoveTwoListeners) { module_system_->Require("test"); } -TEST_F(EventUnittest, OnUnloadDetachesAllListeners) { - ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); - RegisterModule("test", - "var assert = requireNative('assert');" - "var event = require('event');" - "var eventBindings = requireNative('event_bindings');" - "var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();" - "var myEvent = new event.Event('named-event');" - "var cb1 = function() {};" - "var cb2 = function() {};" - "myEvent.addListener(cb1);" - "myEvent.addListener(cb2);" - "chromeHidden.dispatchOnUnload();" - "assert.AssertFalse(!!eventBindings.attachedListeners['named-event']);"); - module_system_->Require("test"); -} - -TEST_F(EventUnittest, OnUnloadDetachesAllListenersEvenDupes) { - ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); - RegisterModule("test", - "var assert = requireNative('assert');" - "var event = require('event');" - "var eventBindings = requireNative('event_bindings');" - "var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();" - "var myEvent = new event.Event('named-event');" - "var cb1 = function() {};" - "myEvent.addListener(cb1);" - "myEvent.addListener(cb1);" - "chromeHidden.dispatchOnUnload();" - "assert.AssertFalse(!!eventBindings.attachedListeners['named-event']);"); - module_system_->Require("test"); -} - TEST_F(EventUnittest, EventsThatSupportRulesMustHaveAName) { ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); RegisterModule("test", @@ -153,97 +92,4 @@ TEST_F(EventUnittest, NamedEventDispatch) { module_system_->Require("test"); } -TEST_F(EventUnittest, AddListenerWithFiltersThrowsErrorByDefault) { - ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); - RegisterModule("test", - "var event = require('event');" - "var assert = requireNative('assert');" - "var e = new event.Event('myevent');" - "var filter = [{" - " url: {hostSuffix: 'google.com'}," - "}];" - "var caught = false;" - "try {" - " e.addListener(function() {}, filter);" - "} catch (e) {" - " caught = true;" - "}" - "assert.AssertTrue(caught);"); - module_system_->Require("test"); -} - -TEST_F(EventUnittest, FilteredEventsAttachment) { - ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); - RegisterModule("test", - "var event = require('event');" - "var assert = requireNative('assert');" - "var bindings = requireNative('event_bindings');" - "var eventOpts = {supportsListeners: true, supportsFilters: true};" - "var e = new event.Event('myevent', undefined, eventOpts);" - "var cb = function() {};" - "var filters = {url: [{hostSuffix: 'google.com'}]};" - "e.addListener(cb, filters);" - "assert.AssertTrue(bindings.HasFilteredListener('myevent'));" - "e.removeListener(cb);" - "assert.AssertFalse(bindings.HasFilteredListener('myevent'));"); - module_system_->Require("test"); -} - -TEST_F(EventUnittest, DetachFilteredEvent) { - ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); - RegisterModule("test", - "var event = require('event');" - "var assert = requireNative('assert');" - "var bindings = requireNative('event_bindings');" - "var eventOpts = {supportsListeners: true, supportsFilters: true};" - "var e = new event.Event('myevent', undefined, eventOpts);" - "var cb1 = function() {};" - "var cb2 = function() {};" - "var filters = {url: [{hostSuffix: 'google.com'}]};" - "e.addListener(cb1, filters);" - "e.addListener(cb2, filters);" - "e.detach_();" - "assert.AssertFalse(bindings.HasFilteredListener('myevent'));"); - module_system_->Require("test"); -} - -TEST_F(EventUnittest, AttachAndRemoveSameFilteredEventListener) { - ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); - RegisterModule("test", - "var event = require('event');" - "var assert = requireNative('assert');" - "var bindings = requireNative('event_bindings');" - "var eventOpts = {supportsListeners: true, supportsFilters: true};" - "var e = new event.Event('myevent', undefined, eventOpts);" - "var cb = function() {};" - "var filters = {url: [{hostSuffix: 'google.com'}]};" - "e.addListener(cb, filters);" - "e.addListener(cb, filters);" - "assert.AssertTrue(bindings.HasFilteredListener('myevent'));" - "e.removeListener(cb);" - "assert.AssertTrue(bindings.HasFilteredListener('myevent'));" - "e.removeListener(cb);" - "assert.AssertFalse(bindings.HasFilteredListener('myevent'));"); - module_system_->Require("test"); -} - -TEST_F(EventUnittest, AddingFilterWithUrlFieldNotAListThrowsException) { - ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get()); - RegisterModule("test", - "var event = require('event');" - "var assert = requireNative('assert');" - "var eventOpts = {supportsListeners: true, supportsFilters: true};" - "var e = new event.Event('myevent', undefined, eventOpts);" - "var cb = function() {};" - "var filters = {url: {hostSuffix: 'google.com'}};" - "var caught = false;" - "try {" - " e.addListener(cb, filters);" - "} catch (e) {" - " caught = true;" - "}" - "assert.AssertTrue(caught);"); - module_system_->Require("test"); -} - } // namespace diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc index 56d5c89..61a7c8f 100644 --- a/chrome/renderer/extensions/extension_dispatcher.cc +++ b/chrome/renderer/extensions/extension_dispatcher.cc @@ -237,8 +237,7 @@ ExtensionDispatcher::ExtensionDispatcher() webrequest_adblock_plus_(false), webrequest_other_(false), source_map_(&ResourceBundle::GetSharedInstance()), - chrome_channel_(chrome::VersionInfo::CHANNEL_UNKNOWN), - event_filter_(new extensions::EventFilter) { + chrome_channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) { const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); is_extension_process_ = command_line.HasSwitch(switches::kExtensionProcess) || @@ -495,7 +494,7 @@ bool ExtensionDispatcher::AllowScriptExtension( void ExtensionDispatcher::RegisterNativeHandlers(ModuleSystem* module_system, ChromeV8Context* context) { module_system->RegisterNativeHandler("event_bindings", - scoped_ptr<NativeHandler>(EventBindings::Get(this, event_filter_.get()))); + scoped_ptr<NativeHandler>(EventBindings::Get(this))); module_system->RegisterNativeHandler("miscellaneous_bindings", scoped_ptr<NativeHandler>(MiscellaneousBindings::Get(this))); module_system->RegisterNativeHandler("apiDefinitions", diff --git a/chrome/renderer/extensions/extension_dispatcher.h b/chrome/renderer/extensions/extension_dispatcher.h index 1aee2d6..d19617e 100644 --- a/chrome/renderer/extensions/extension_dispatcher.h +++ b/chrome/renderer/extensions/extension_dispatcher.h @@ -13,7 +13,6 @@ #include "base/shared_memory.h" #include "base/timer.h" #include "content/public/renderer/render_process_observer.h" -#include "chrome/common/extensions/event_filter.h" #include "chrome/common/extensions/extension_set.h" #include "chrome/common/extensions/features/feature.h" #include "chrome/renderer/extensions/chrome_v8_context.h" @@ -29,10 +28,6 @@ class URLPattern; class UserScriptSlave; struct ExtensionMsg_Loaded_Params; -namespace extensions { -class FilteredEventRouter; -} - namespace WebKit { class WebFrame; } @@ -263,10 +258,6 @@ class ExtensionDispatcher : public content::RenderProcessObserver { // TODO(aa): Remove when we can restrict non-permission APIs to dev-only. int chrome_channel_; - // Routes events to the appropriate listener taking into consideration event - // filters. - scoped_ptr<extensions::EventFilter> event_filter_; - DISALLOW_COPY_AND_ASSIGN(ExtensionDispatcher); }; diff --git a/chrome/renderer/resources/extensions/event.js b/chrome/renderer/resources/extensions/event.js index 4b784ad..a6d6363 100644 --- a/chrome/renderer/resources/extensions/event.js +++ b/chrome/renderer/resources/extensions/event.js @@ -5,9 +5,6 @@ var eventBindingsNatives = requireNative('event_bindings'); var AttachEvent = eventBindingsNatives.AttachEvent; var DetachEvent = eventBindingsNatives.DetachEvent; - var AttachFilteredEvent = eventBindingsNatives.AttachFilteredEvent; - var DetachFilteredEvent = eventBindingsNatives.DetachFilteredEvent; - var MatchAgainstEventFilter = eventBindingsNatives.MatchAgainstEventFilter; var sendRequest = require('sendRequest').sendRequest; var utils = require('utils'); var validate = require('schemaUtils').validate; @@ -78,85 +75,6 @@ }; })(); - // A map of event names to the event object that is registered to that name. - var attachedNamedEvents = {}; - - // An array of all attached event objects, used for detaching on unload. - var allAttachedEvents = []; - - // A map of functions that massage event arguments before they are dispatched. - // Key is event name, value is function. - var eventArgumentMassagers = {}; - - // Handles adding/removing/dispatching listeners for unfiltered events. - var UnfilteredAttachmentStrategy = function(event) { - this.event_ = event; - }; - - UnfilteredAttachmentStrategy.prototype.onAddedListener = - function(listener) { - // Only attach / detach on the first / last listener removed. - if (this.event_.listeners_.length == 0) - AttachEvent(this.event_.eventName_); - }; - - UnfilteredAttachmentStrategy.prototype.onRemovedListener = - function(listener) { - if (this.event_.listeners_.length == 0) - this.detach(true); - }; - - UnfilteredAttachmentStrategy.prototype.detach = function(manual) { - DetachEvent(this.event_.eventName_, manual); - }; - - UnfilteredAttachmentStrategy.prototype.getListenersByIDs = function(ids) { - return this.event_.listeners_; - }; - - var FilteredAttachmentStrategy = function(event) { - this.event_ = event; - this.listenerMap_ = {}; - }; - - FilteredAttachmentStrategy.idToEventMap = {}; - - FilteredAttachmentStrategy.prototype.onAddedListener = function(listener) { - var id = AttachFilteredEvent(this.event_.eventName_, - listener.filters || {}); - if (id == -1) - throw new Error("Can't add listener"); - listener.id = id; - this.listenerMap_[id] = listener; - FilteredAttachmentStrategy.idToEventMap[id] = this.event_; - }; - - FilteredAttachmentStrategy.prototype.onRemovedListener = function(listener) { - this.detachListener(listener, true); - }; - - FilteredAttachmentStrategy.prototype.detachListener = - function(listener, manual) { - if (listener.id == undefined) - throw new Error("listener.id undefined - '" + listener + "'"); - var id = listener.id; - delete this.listenerMap_[id]; - delete FilteredAttachmentStrategy.idToEventMap[id]; - DetachFilteredEvent(id, manual); - }; - - FilteredAttachmentStrategy.prototype.detach = function(manual) { - for (var i in this.listenerMap_) - this.detachListener(this.listenerMap_[i], manual); - }; - - FilteredAttachmentStrategy.prototype.getListenersByIDs = function(ids) { - var result = []; - for (var i = 0; i < ids.length; i++) - result.push(this.listenerMap_[ids[i]]); - return result; - }; - // Event object. If opt_eventName is provided, this object represents // the unique instance of that named event, and dispatching an event // with that name will route through this object's listeners. Note that @@ -174,20 +92,11 @@ this.eventName_ = opt_eventName; this.listeners_ = []; this.eventOptions_ = opt_eventOptions || - {supportsFilters: false, - supportsListeners: true, - supportsRules: false, - }; + {"supportsListeners": true, "supportsRules": false}; if (this.eventOptions_.supportsRules && !opt_eventName) throw new Error("Events that support rules require an event name."); - if (this.eventOptions_.supportsFilters) { - this.attachmentStrategy_ = new FilteredAttachmentStrategy(this); - } else { - this.attachmentStrategy_ = new UnfilteredAttachmentStrategy(this); - } - // Validate event arguments (the data that is passed to the callbacks) // if we are in debug. if (opt_argSchemas && @@ -206,6 +115,16 @@ } }; + // A map of event names to the event object that is registered to that name. + var attachedNamedEvents = {}; + + // An array of all attached event objects, used for detaching on unload. + var allAttachedEvents = []; + + // A map of functions that massage event arguments before they are dispatched. + // Key is event name, value is function. + var eventArgumentMassagers = {}; + chromeHidden.Event = {}; chromeHidden.Event.registerArgumentMassager = function(name, fn) { @@ -217,12 +136,7 @@ // Dispatches a named event with the given JSON array, which is deserialized // before dispatch. The JSON array is the list of arguments that will be // sent with the event callback. - chromeHidden.Event.dispatchJSON = function(name, args, filteringInfo) { - var listenerIDs = null; - - if (filteringInfo) { - listenerIDs = MatchAgainstEventFilter(name, filteringInfo); - } + chromeHidden.Event.dispatchJSON = function(name, args) { if (attachedNamedEvents[name]) { if (args) { // TODO(asargent): This is an antiquity. Until all callers of @@ -234,18 +148,8 @@ if (eventArgumentMassagers[name]) eventArgumentMassagers[name](args); } - - var event = attachedNamedEvents[name]; - var result; - // TODO(koz): We have to do this differently for unfiltered events (which - // have listenerIDs = null) because some bindings write over - // event.dispatch (eg: experimental.app.custom_bindings.js) and so expect - // events to go through it. These places need to be fixed so that they - // expect a listenerIDs parameter. - if (listenerIDs) - result = event.dispatch_(args, listenerIDs); - else - result = event.dispatch.apply(event, args); + var result = attachedNamedEvents[name].dispatch.apply( + attachedNamedEvents[name], args); if (result && result.validationErrors) return result.validationErrors; } @@ -266,34 +170,13 @@ }; // Registers a callback to be called when this event is dispatched. - chrome.Event.prototype.addListener = function(cb, filters) { + chrome.Event.prototype.addListener = function(cb) { if (!this.eventOptions_.supportsListeners) throw new Error("This event does not support listeners."); - if (filters) { - if (!this.eventOptions_.supportsFilters) - throw new Error("This event does not support filters."); - if (filters.url && !(filters.url instanceof Array)) - throw new Error("filters.url should be an array"); - } - var listener = {callback: cb, filters: filters}; - this.attach_(listener); - this.listeners_.push(listener); - }; - - chrome.Event.prototype.attach_ = function(listener) { - this.attachmentStrategy_.onAddedListener(listener); if (this.listeners_.length == 0) { - allAttachedEvents[allAttachedEvents.length] = this; - if (!this.eventName_) - return; - - if (attachedNamedEvents[this.eventName_]) { - throw new Error("chrome.Event '" + this.eventName_ + - "' is already attached."); - } - - attachedNamedEvents[this.eventName_] = this; + this.attach_(); } + this.listeners_.push(cb); }; // Unregisters a callback. @@ -305,22 +188,9 @@ return; } - var removedListener = this.listeners_.splice(idx, 1)[0]; - this.attachmentStrategy_.onRemovedListener(removedListener); - + this.listeners_.splice(idx, 1); if (this.listeners_.length == 0) { - var i = allAttachedEvents.indexOf(this); - if (i >= 0) - delete allAttachedEvents[i]; - if (!this.eventName_) - return; - - if (!attachedNamedEvents[this.eventName_]) { - throw new Error("chrome.Event '" + this.eventName_ + - "' is not attached."); - } - - delete attachedNamedEvents[this.eventName_]; + this.detach_(true); } }; @@ -342,7 +212,7 @@ // found. chrome.Event.prototype.findListener_ = function(cb) { for (var i = 0; i < this.listeners_.length; i++) { - if (this.listeners_[i].callback == cb) { + if (this.listeners_[i] == cb) { return i; } } @@ -350,21 +220,21 @@ return -1; }; - chrome.Event.prototype.dispatch_ = function(args, listenerIDs) { + // Dispatches this event object to all listeners, passing all supplied + // arguments to this function each listener. + chrome.Event.prototype.dispatch = function(varargs) { if (!this.eventOptions_.supportsListeners) throw new Error("This event does not support listeners."); + var args = Array.prototype.slice.call(arguments); var validationErrors = this.validateEventArgs_(args); if (validationErrors) { console.error(validationErrors); return {validationErrors: validationErrors}; } - - var listeners = this.attachmentStrategy_.getListenersByIDs(listenerIDs); - var results = []; - for (var i = 0; i < listeners.length; i++) { + for (var i = 0; i < this.listeners_.length; i++) { try { - var result = listeners[i].callback.apply(null, args); + var result = this.listeners_[i].apply(null, args); if (result !== undefined) results.push(result); } catch (e) { @@ -374,17 +244,39 @@ } if (results.length) return {results: results}; - } + }; - // Dispatches this event object to all listeners, passing all supplied - // arguments to this function each listener. - chrome.Event.prototype.dispatch = function(varargs) { - return this.dispatch_(Array.prototype.slice.call(arguments), undefined); + // Attaches this event object to its name. Only one object can have a given + // name. + chrome.Event.prototype.attach_ = function() { + AttachEvent(this.eventName_); + allAttachedEvents[allAttachedEvents.length] = this; + if (!this.eventName_) + return; + + if (attachedNamedEvents[this.eventName_]) { + throw new Error("chrome.Event '" + this.eventName_ + + "' is already attached."); + } + + attachedNamedEvents[this.eventName_] = this; }; // Detaches this event object from its name. - chrome.Event.prototype.detach_ = function() { - this.attachmentStrategy_.detach(false); + chrome.Event.prototype.detach_ = function(manual) { + var i = allAttachedEvents.indexOf(this); + if (i >= 0) + delete allAttachedEvents[i]; + DetachEvent(this.eventName_, manual); + if (!this.eventName_) + return; + + if (!attachedNamedEvents[this.eventName_]) { + throw new Error("chrome.Event '" + this.eventName_ + + "' is not attached."); + } + + delete attachedNamedEvents[this.eventName_]; }; chrome.Event.prototype.destroy_ = function() { @@ -471,7 +363,7 @@ for (var i = 0; i < allAttachedEvents.length; ++i) { var event = allAttachedEvents[i]; if (event) - event.detach_(); + event.detach_(false); } }; diff --git a/chrome/test/data/extensions/api_test/filtered_events/manifest.json b/chrome/test/data/extensions/api_test/filtered_events/manifest.json deleted file mode 100644 index 73918bf..0000000 --- a/chrome/test/data/extensions/api_test/filtered_events/manifest.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "filtered events apitest", - "description": "filtered events extension", - "version": "0.1", - "manifest_version": 2, - "background": { - "scripts": ["background.js"], - "persistent": false - }, - "permissions": [ "webNavigation", "tabs" ] -} diff --git a/chrome/test/data/extensions/api_test/lazy_background_page/filters/background.js b/chrome/test/data/extensions/api_test/lazy_background_page/filters/background.js deleted file mode 100644 index 4835058..0000000 --- a/chrome/test/data/extensions/api_test/lazy_background_page/filters/background.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -console.log("running extension!"); -chrome.webNavigation.onBeforeNavigate.addListener(function(details) { - console.log("Got the event!"); - chrome.test.succeed(); -}); diff --git a/chrome/test/data/extensions/api_test/lazy_background_page/filters/manifest.json b/chrome/test/data/extensions/api_test/lazy_background_page/filters/manifest.json deleted file mode 100644 index c6b541a..0000000 --- a/chrome/test/data/extensions/api_test/lazy_background_page/filters/manifest.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "Lazy BG messaging test", - "description": "Test that message passing starts the background page", - "version": "1", - "manifest_version": 2, - "permissions": ["experimental", "webNavigation"], - "background": { - "scripts": ["background.js"], - "persistent": false - } -} diff --git a/chrome/test/data/extensions/api_test/webnavigation/filtered/a.html b/chrome/test/data/extensions/api_test/webnavigation/filtered/a.html deleted file mode 100644 index 9c8afe8..0000000 --- a/chrome/test/data/extensions/api_test/webnavigation/filtered/a.html +++ /dev/null @@ -1 +0,0 @@ -<body onload="document.location='b.html'"></body> diff --git a/chrome/test/data/extensions/api_test/webnavigation/filtered/b.html b/chrome/test/data/extensions/api_test/webnavigation/filtered/b.html deleted file mode 100644 index 18ecdcb..0000000 --- a/chrome/test/data/extensions/api_test/webnavigation/filtered/b.html +++ /dev/null @@ -1 +0,0 @@ -<html></html> diff --git a/chrome/test/data/extensions/api_test/webnavigation/test_filtered.html b/chrome/test/data/extensions/api_test/webnavigation/test_filtered.html deleted file mode 100644 index dbf62b6..0000000 --- a/chrome/test/data/extensions/api_test/webnavigation/test_filtered.html +++ /dev/null @@ -1,5 +0,0 @@ -<script src="test_filtered.js"></script> -<script src="framework.js"></script> -<script> - runTests(); -</script> diff --git a/chrome/test/data/extensions/api_test/webnavigation/test_filtered.js b/chrome/test/data/extensions/api_test/webnavigation/test_filtered.js deleted file mode 100644 index b262b92..0000000 --- a/chrome/test/data/extensions/api_test/webnavigation/test_filtered.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -function runTests() { - var getURL = chrome.extension.getURL; - chrome.tabs.create({"url": "about:blank"}, function(tab) { - var tabId = tab.id; - chrome.test.runTests([ - function dontGetEventToWrongUrl() { - var a_visited = false; - chrome.webNavigation.onCommitted.addListener(function(details) { - chrome.test.fail(); - }, { url: [{pathSuffix: 'never-navigated.html'}] }); - chrome.webNavigation.onCommitted.addListener(function(details) { - chrome.test.assertTrue(details.url == getURL('filtered/a.html')); - a_visited = true; - }, { url: [{pathSuffix: 'a.html'}] }); - chrome.webNavigation.onCommitted.addListener(function(details) { - chrome.test.assertTrue(details.url == getURL('filtered/b.html')); - chrome.test.assertTrue(a_visited); - chrome.test.succeed(); - }, { url: [{pathSuffix: 'b.html'}] }); - chrome.tabs.update(tabId, { url: getURL('filtered/a.html') }); - } - ]); - }); -} |