diff options
author | koz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-18 05:29:39 +0000 |
---|---|---|
committer | koz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-18 05:29:39 +0000 |
commit | 4df8ef1e1e8a1f94bc8cd3353605e3a7480789fd (patch) | |
tree | 34a2a7ff16711bbf19d0947c73b3184ec81065b9 | |
parent | 28969526c31ebd384fe2341d5b0f8bc96a279efd (diff) | |
download | chromium_src-4df8ef1e1e8a1f94bc8cd3353605e3a7480789fd.zip chromium_src-4df8ef1e1e8a1f94bc8cd3353605e3a7480789fd.tar.gz chromium_src-4df8ef1e1e8a1f94bc8cd3353605e3a7480789fd.tar.bz2 |
Add common code for extensions event filtering.
FilteredEventRouter will be used in the browser and the renderer to match
events to interested parties. In the browser it will be used to send events
only to renderers that are interested in them, and in the renderer it will be
used to send events to the correct JS listeners.
BUG=121479
Review URL: https://chromiumcodereview.appspot.com/10388135
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137829 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/chrome_common.gypi | 6 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 | ||||
-rw-r--r-- | chrome/common/extensions/event_filter.cc | 148 | ||||
-rw-r--r-- | chrome/common/extensions/event_filter.h | 119 | ||||
-rw-r--r-- | chrome/common/extensions/event_filter_unittest.cc | 231 | ||||
-rw-r--r-- | chrome/common/extensions/event_filtering_info.cc | 21 | ||||
-rw-r--r-- | chrome/common/extensions/event_filtering_info.h | 39 | ||||
-rw-r--r-- | chrome/common/extensions/event_matcher.cc | 22 | ||||
-rw-r--r-- | chrome/common/extensions/event_matcher.h | 50 |
9 files changed, 637 insertions, 0 deletions
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index e1a4e12..2d8dfdd 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -110,6 +110,12 @@ 'common/custom_handlers/protocol_handler.h', 'common/extensions/csp_validator.cc', 'common/extensions/csp_validator.h', + 'common/extensions/event_filter.cc', + 'common/extensions/event_filter.h', + 'common/extensions/event_filtering_info.cc', + 'common/extensions/event_filtering_info.h', + 'common/extensions/event_matcher.cc', + 'common/extensions/event_matcher.h', 'common/extensions/extension.cc', 'common/extensions/extension.h', 'common/extensions/extension_action.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 9c00f2a..baf060c 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1810,6 +1810,7 @@ 'common/content_settings_pattern_parser_unittest.cc', 'common/content_settings_pattern_unittest.cc', 'common/extensions/csp_validator_unittest.cc', + 'common/extensions/event_filter_unittest.cc', 'common/extensions/extension_action_unittest.cc', 'common/extensions/extension_commands_unittest.cc', 'common/extensions/extension_constants_unittest.cc', diff --git a/chrome/common/extensions/event_filter.cc b/chrome/common/extensions/event_filter.cc new file mode 100644 index 0000000..e9ccad5 --- /dev/null +++ b/chrome/common/extensions/event_filter.cc @@ -0,0 +1,148 @@ +// 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/event_filter.h" + +#include "chrome/common/extensions/matcher/url_matcher_factory.h" + +namespace extensions { + +EventFilter::EventMatcherEntry::EventMatcherEntry( + scoped_ptr<EventMatcher> event_matcher, + URLMatcher* url_matcher, + const URLMatcherConditionSet::Vector& condition_sets) + : event_matcher_(event_matcher.Pass()), + url_matcher_(url_matcher) { + for (URLMatcherConditionSet::Vector::const_iterator it = + condition_sets.begin(); it != condition_sets.end(); it++) + condition_set_ids_.push_back((*it)->id()); + url_matcher_->AddConditionSets(condition_sets); +} + +EventFilter::EventMatcherEntry::~EventMatcherEntry() { + url_matcher_->RemoveConditionSets(condition_set_ids_); +} + +void EventFilter::EventMatcherEntry::DontRemoveConditionSetsInDestructor() { + condition_set_ids_.clear(); +} + +EventFilter::EventFilter() + : next_id_(0), + next_condition_set_id_(0) { +} + +EventFilter::~EventFilter() { + // Normally when an event matcher entry is removed from event_matchers_ it + // will remove its condition sets from url_matcher_, but as url_matcher_ is + // being destroyed anyway there is no need to do that step here. + for (EventMatcherMultiMap::iterator it = event_matchers_.begin(); + it != event_matchers_.end(); it++) { + for (EventMatcherMap::iterator it2 = it->second.begin(); + it2 != it->second.end(); it2++) { + it2->second->DontRemoveConditionSetsInDestructor(); + } + } +} + +EventFilter::MatcherID +EventFilter::AddEventMatcher(const std::string& event_name, + scoped_ptr<EventMatcher> matcher) { + MatcherID id = next_id_++; + URLMatcherConditionSet::Vector condition_sets; + if (!CreateConditionSets(id, matcher->url_filters(), &condition_sets)) + return -1; + + for (URLMatcherConditionSet::Vector::iterator it = condition_sets.begin(); + it != condition_sets.end(); it++) { + condition_set_id_to_event_matcher_id_.insert( + std::make_pair((*it)->id(), id)); + } + id_to_event_name_[id] = event_name; + event_matchers_[event_name][id] = linked_ptr<EventMatcherEntry>( + new EventMatcherEntry(matcher.Pass(), &url_matcher_, condition_sets)); + return id; +} + +bool EventFilter::CreateConditionSets( + MatcherID id, + base::ListValue* url_filters, + URLMatcherConditionSet::Vector* condition_sets) { + if (!url_filters || url_filters->GetSize() == 0) { + // If there are no url_filters then we want to match all events, so create a + // URLFilter from an empty dictionary. + base::DictionaryValue empty_dict; + return AddDictionaryAsConditionSet(&empty_dict, condition_sets); + } + for (size_t i = 0; i < url_filters->GetSize(); i++) { + base::DictionaryValue* url_filter; + if (!url_filters->GetDictionary(i, &url_filter)) + return false; + if (!AddDictionaryAsConditionSet(url_filter, condition_sets)) + return false; + } + return true; +} + +bool EventFilter::AddDictionaryAsConditionSet( + base::DictionaryValue* url_filter, + URLMatcherConditionSet::Vector* condition_sets) { + std::string error; + URLMatcherConditionSet::ID condition_set_id = next_condition_set_id_++; + condition_sets->push_back(URLMatcherFactory::CreateFromURLFilterDictionary( + url_matcher_.condition_factory(), + url_filter, + condition_set_id, + &error)); + if (!error.empty()) { + LOG(ERROR) << "CreateFromURLFilterDictionary failed: " << error; + url_matcher_.ClearUnusedConditionSets(); + condition_sets->clear(); + return false; + } + return true; +} + +std::string EventFilter::RemoveEventMatcher(MatcherID id) { + std::map<MatcherID, std::string>::iterator it = id_to_event_name_.find(id); + event_matchers_[it->second].erase(id); + std::string event_name = it->second; + id_to_event_name_.erase(it); + return event_name; +} + +std::set<EventFilter::MatcherID> EventFilter::MatchEvent( + const std::string& event_name, const EventFilteringInfo& event_info) { + std::set<MatcherID> matchers; + EventMatcherMultiMap::iterator it = event_matchers_.find(event_name); + if (it == event_matchers_.end()) + return matchers; + + EventMatcherMap& matcher_map = it->second; + GURL url_to_match_against = event_info.has_url() ? event_info.url() : GURL(); + std::set<URLMatcherConditionSet::ID> matching_condition_set_ids = + url_matcher_.MatchURL(url_to_match_against); + for (std::set<URLMatcherConditionSet::ID>::iterator it = + matching_condition_set_ids.begin(); + it != matching_condition_set_ids.end(); it++) { + MatcherID id = condition_set_id_to_event_matcher_id_[*it]; + const EventMatcher& event_matcher = matcher_map[id]->event_matcher(); + if (event_matcher.MatchNonURLCriteria(event_info)) { + CHECK(!event_matcher.url_filters() || event_info.has_url()); + matchers.insert(id); + } + } + + return matchers; +} + +int EventFilter::GetMatcherCountForEvent(const std::string& name) { + EventMatcherMultiMap::const_iterator it = event_matchers_.find(name); + if (it == event_matchers_.end()) + return 0; + + return it->second.size(); +} + +} // namespace extensions diff --git a/chrome/common/extensions/event_filter.h b/chrome/common/extensions/event_filter.h new file mode 100644 index 0000000..26acb44 --- /dev/null +++ b/chrome/common/extensions/event_filter.h @@ -0,0 +1,119 @@ +// 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_EVENT_FILTER_H_ +#define CHROME_COMMON_EXTENSIONS_EVENT_FILTER_H_ +#pragma once + +#include "base/memory/linked_ptr.h" +#include "chrome/common/extensions/event_matcher.h" +#include "chrome/common/extensions/event_filtering_info.h" +#include "chrome/common/extensions/matcher/url_matcher.h" + +#include <map> +#include <set> + +namespace extensions { + +// Matches incoming events against a collection of EventMatchers. Each added +// EventMatcher is given an id which is returned by MatchEvent() when it is +// passed a matching event. +class EventFilter { + public: + typedef int MatcherID; + EventFilter(); + ~EventFilter(); + + // Adds an event matcher that will be used in calls to MatchEvent(). Returns + // the id of the matcher, or -1 if there was an error. + MatcherID AddEventMatcher(const std::string& event_name, + scoped_ptr<EventMatcher> matcher); + // Removes an event matcher, returning the name of the event that it was for. + std::string RemoveEventMatcher(MatcherID id); + + // Match an event named |event_name| with filtering info |event_info| against + // our set of event matchers. Returns a set of ids that correspond to the + // event matchers that matched the event. + // TODO(koz): Add a std::string* parameter for retrieving error messages. + std::set<MatcherID> MatchEvent(const std::string& event_name, + const EventFilteringInfo& event_info); + + int GetMatcherCountForEvent(const std::string& event_name); + + // For testing. + bool IsURLMatcherEmpty() const { + return url_matcher_.IsEmpty(); + } + + private: + class EventMatcherEntry { + public: + // Adds |condition_sets| to |url_matcher| on construction and removes them + // again on destruction. |condition_sets| should be the + // URLMatcherConditionSets that match the URL constraints specified by + // |event_matcher|. + EventMatcherEntry(scoped_ptr<EventMatcher> event_matcher, + URLMatcher* url_matcher, + const URLMatcherConditionSet::Vector& condition_sets); + ~EventMatcherEntry(); + + // Prevents the removal of condition sets when this class is destroyed. We + // call this in EventFilter's destructor so that we don't do the costly + // removal of condition sets when the URLMatcher is going to be destroyed + // and clean them up anyway. + void DontRemoveConditionSetsInDestructor(); + + const EventMatcher& event_matcher() const { + return *event_matcher_; + } + + private: + scoped_ptr<EventMatcher> event_matcher_; + // The id sets in url_matcher_ that this EventMatcher owns. + std::vector<URLMatcherConditionSet::ID> condition_set_ids_; + URLMatcher* url_matcher_; + + DISALLOW_COPY_AND_ASSIGN(EventMatcherEntry); + }; + + // Maps from a matcher id to an event matcher entry. + typedef std::map<MatcherID, linked_ptr<EventMatcherEntry> > EventMatcherMap; + + // Maps from event name to the map of matchers that are registered for it. + typedef std::map<std::string, EventMatcherMap> EventMatcherMultiMap; + + // Adds the list of filters to the URL matcher, having matches for those URLs + // map to |id|. + bool CreateConditionSets(MatcherID id, + base::ListValue* url_filters, + URLMatcherConditionSet::Vector* condition_sets); + + bool AddDictionaryAsConditionSet( + base::DictionaryValue* url_filter, + URLMatcherConditionSet::Vector* condition_sets); + + URLMatcher url_matcher_; + EventMatcherMultiMap event_matchers_; + + // The next id to assign to an EventMatcher. + MatcherID next_id_; + + // The next id to assign to a condition set passed to URLMatcher. + URLMatcherConditionSet::ID next_condition_set_id_; + + // Maps condition set ids, which URLMatcher operates in, to event matcher + // ids, which the interface to this class operates in. As each EventFilter + // can specify many condition sets this is a many to one relationship. + std::map<URLMatcherConditionSet::ID, MatcherID> + condition_set_id_to_event_matcher_id_; + + // Maps from event matcher ids to the name of the event they match on. + std::map<MatcherID, std::string> id_to_event_name_; + + DISALLOW_COPY_AND_ASSIGN(EventFilter); +}; + +} // namespace extensions + +#endif // CHROME_COMMON_EXTENSIONS_EVENT_FILTER_H_ diff --git a/chrome/common/extensions/event_filter_unittest.cc b/chrome/common/extensions/event_filter_unittest.cc new file mode 100644 index 0000000..d1ca5a0 --- /dev/null +++ b/chrome/common/extensions/event_filter_unittest.cc @@ -0,0 +1,231 @@ +// 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/event_filter.h" +#include "chrome/common/extensions/event_filtering_info.h" +#include "chrome/common/extensions/event_matcher.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace extensions { + +class EventFilterUnittest : public testing::Test { + public: + EventFilterUnittest() { + google_event_.SetURL(GURL("http://google.com")); + yahoo_event_.SetURL(GURL("http://yahoo.com")); + random_url_event_.SetURL(GURL("http://www.something-else.com")); + empty_url_event_.SetURL(GURL()); + } + + protected: + scoped_ptr<base::Value> HostSuffixDict(const std::string& host_suffix) { + scoped_ptr<base::DictionaryValue> dict(new DictionaryValue()); + dict->Set("hostSuffix", base::Value::CreateStringValue(host_suffix)); + return scoped_ptr<base::Value>(dict.release()); + } + + scoped_ptr<base::ListValue> ValueAsList(scoped_ptr<base::Value> value) { + scoped_ptr<base::ListValue> result(new base::ListValue()); + result->Append(value.release()); + return result.Pass(); + } + + scoped_ptr<EventMatcher> AllURLs() { + scoped_ptr<EventMatcher> matcher(new EventMatcher()); + // An empty set of URL filters always matches. + matcher->set_url_filters(scoped_ptr<ListValue>(new ListValue())); + return matcher.Pass(); + } + + scoped_ptr<EventMatcher> HostSuffixMatcher(const std::string& host_suffix) { + scoped_ptr<EventMatcher> event_matcher(new EventMatcher()); + event_matcher->set_url_filters(ValueAsList(HostSuffixDict(host_suffix))); + return event_matcher.Pass(); + } + + EventFilter event_filter_; + EventFilteringInfo empty_event_; + EventFilteringInfo google_event_; + EventFilteringInfo yahoo_event_; + EventFilteringInfo random_url_event_; + EventFilteringInfo empty_url_event_; +}; + +TEST_F(EventFilterUnittest, NoMatchersMatchIfEmpty) { + std::set<int> matches = event_filter_.MatchEvent("some-event", + empty_event_); + ASSERT_EQ(0u, matches.size()); +} + +TEST_F(EventFilterUnittest, AddingEventMatcherDoesntCrash) { + event_filter_.AddEventMatcher("event1", AllURLs()); +} + +TEST_F(EventFilterUnittest, + DontMatchAgainstMatchersForDifferentEvents) { + event_filter_.AddEventMatcher("event1", AllURLs()); + std::set<int> matches = event_filter_.MatchEvent("event2", + empty_event_); + ASSERT_EQ(0u, matches.size()); +} + +TEST_F(EventFilterUnittest, DoMatchAgainstMatchersForSameEvent) { + int id = event_filter_.AddEventMatcher("event1", AllURLs()); + std::set<int> matches = event_filter_.MatchEvent("event1", + google_event_); + ASSERT_EQ(1u, matches.size()); + ASSERT_EQ(1u, matches.count(id)); +} + +TEST_F(EventFilterUnittest, DontMatchUnlessMatcherMatches) { + EventFilteringInfo info; + info.SetURL(GURL("http://www.yahoo.com")); + event_filter_.AddEventMatcher("event1", HostSuffixMatcher("google.com")); + std::set<int> matches = event_filter_.MatchEvent("event1", info); + ASSERT_TRUE(matches.empty()); +} + +TEST_F(EventFilterUnittest, RemovingAnEventMatcherStopsItMatching) { + int id = event_filter_.AddEventMatcher("event1", AllURLs()); + event_filter_.RemoveEventMatcher(id); + std::set<int> matches = event_filter_.MatchEvent("event1", + empty_event_); + ASSERT_TRUE(matches.empty()); +} + +TEST_F(EventFilterUnittest, MultipleEventMatches) { + int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); + int id2 = event_filter_.AddEventMatcher("event1", AllURLs()); + std::set<int> matches = event_filter_.MatchEvent("event1", + google_event_); + ASSERT_EQ(2u, matches.size()); + ASSERT_EQ(1u, matches.count(id1)); + ASSERT_EQ(1u, matches.count(id2)); +} + +TEST_F(EventFilterUnittest, TestURLMatching) { + EventFilteringInfo info; + info.SetURL(GURL("http://www.google.com")); + int id = event_filter_.AddEventMatcher("event1", + HostSuffixMatcher("google.com")); + std::set<int> matches = event_filter_.MatchEvent("event1", info); + ASSERT_EQ(1u, matches.size()); + ASSERT_EQ(1u, matches.count(id)); +} + +TEST_F(EventFilterUnittest, TestMultipleURLFiltersMatchOnAny) { + scoped_ptr<base::ListValue> filters(new base::ListValue()); + filters->Append(HostSuffixDict("google.com").release()); + filters->Append(HostSuffixDict("yahoo.com").release()); + + scoped_ptr<EventMatcher> matcher(new EventMatcher()); + matcher->set_url_filters(filters.Pass()); + int id = event_filter_.AddEventMatcher("event1", matcher.Pass()); + + { + std::set<int> matches = event_filter_.MatchEvent("event1", + google_event_); + ASSERT_EQ(1u, matches.size()); + ASSERT_EQ(1u, matches.count(id)); + } + { + std::set<int> matches = event_filter_.MatchEvent("event1", + yahoo_event_); + ASSERT_EQ(1u, matches.size()); + ASSERT_EQ(1u, matches.count(id)); + } + { + std::set<int> matches = event_filter_.MatchEvent("event1", + random_url_event_); + ASSERT_EQ(0u, matches.size()); + } +} + +TEST_F(EventFilterUnittest, TestStillMatchesAfterRemoval) { + int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); + int id2 = event_filter_.AddEventMatcher("event1", AllURLs()); + + event_filter_.RemoveEventMatcher(id1); + { + std::set<int> matches = event_filter_.MatchEvent("event1", + google_event_); + ASSERT_EQ(1u, matches.size()); + ASSERT_EQ(1u, matches.count(id2)); + } +} + +TEST_F(EventFilterUnittest, TestGetMatcherCountForEvent) { + ASSERT_EQ(0, event_filter_.GetMatcherCountForEvent("event1")); + int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); + ASSERT_EQ(1, event_filter_.GetMatcherCountForEvent("event1")); + int id2 = event_filter_.AddEventMatcher("event1", AllURLs()); + ASSERT_EQ(2, event_filter_.GetMatcherCountForEvent("event1")); + event_filter_.RemoveEventMatcher(id1); + ASSERT_EQ(1, event_filter_.GetMatcherCountForEvent("event1")); + event_filter_.RemoveEventMatcher(id2); + ASSERT_EQ(0, event_filter_.GetMatcherCountForEvent("event1")); +} + +TEST_F(EventFilterUnittest, RemoveEventMatcherReturnsEventName) { + int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); + int id2 = event_filter_.AddEventMatcher("event1", AllURLs()); + int id3 = event_filter_.AddEventMatcher("event2", AllURLs()); + + ASSERT_EQ("event1", event_filter_.RemoveEventMatcher(id1)); + ASSERT_EQ("event1", event_filter_.RemoveEventMatcher(id2)); + ASSERT_EQ("event2", event_filter_.RemoveEventMatcher(id3)); +} + +TEST_F(EventFilterUnittest, InvalidURLFilterCantBeAdded) { + scoped_ptr<base::ListValue> filter_list(new base::ListValue()); + filter_list->Append(new base::ListValue()); // Should be a dict. + scoped_ptr<EventMatcher> matcher(new EventMatcher); + matcher->set_url_filters(filter_list.Pass()); + int id1 = event_filter_.AddEventMatcher("event1", matcher.Pass()); + EXPECT_TRUE(event_filter_.IsURLMatcherEmpty()); + ASSERT_EQ(-1, id1); +} + +TEST_F(EventFilterUnittest, EmptyListOfURLFiltersMatchesAllURLs) { + scoped_ptr<base::ListValue> filter_list(new base::ListValue()); + scoped_ptr<EventMatcher> matcher(new EventMatcher); + matcher->set_url_filters(filter_list.Pass()); + int id = event_filter_.AddEventMatcher("event1", matcher.Pass()); + std::set<int> matches = event_filter_.MatchEvent("event1", + google_event_); + ASSERT_EQ(1u, matches.size()); + ASSERT_EQ(1u, matches.count(id)); +} + +TEST_F(EventFilterUnittest, + InternalURLMatcherShouldBeEmptyWhenThereAreNoEventMatchers) { + ASSERT_TRUE(event_filter_.IsURLMatcherEmpty()); + int id = event_filter_.AddEventMatcher("event1", + HostSuffixMatcher("google.com")); + ASSERT_FALSE(event_filter_.IsURLMatcherEmpty()); + event_filter_.RemoveEventMatcher(id); + ASSERT_TRUE(event_filter_.IsURLMatcherEmpty()); +} + +TEST_F(EventFilterUnittest, EmptyURLsShouldBeMatchedByEmptyURLFilters) { + int id = event_filter_.AddEventMatcher("event1", AllURLs()); + std::set<int> matches = event_filter_.MatchEvent("event1", empty_url_event_); + ASSERT_EQ(1u, matches.size()); + ASSERT_EQ(1u, matches.count(id)); +} + +TEST_F(EventFilterUnittest, + EmptyURLsShouldBeMatchedByEmptyURLFiltersWithAnEmptyItem) { + scoped_ptr<EventMatcher> matcher(new EventMatcher()); + matcher->set_url_filters(ValueAsList(scoped_ptr<Value>( + new DictionaryValue()))); + int id = event_filter_.AddEventMatcher("event1", matcher.Pass()); + std::set<int> matches = event_filter_.MatchEvent("event1", empty_url_event_); + ASSERT_EQ(1u, matches.size()); + ASSERT_EQ(1u, matches.count(id)); +} + +} // namespace extensions diff --git a/chrome/common/extensions/event_filtering_info.cc b/chrome/common/extensions/event_filtering_info.cc new file mode 100644 index 0000000..dcf78fc --- /dev/null +++ b/chrome/common/extensions/event_filtering_info.cc @@ -0,0 +1,21 @@ +// 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/event_filtering_info.h" + +namespace extensions { + +EventFilteringInfo::EventFilteringInfo() + : has_url_(false) { +} + +EventFilteringInfo::~EventFilteringInfo() { +} + +void EventFilteringInfo::SetURL(const GURL& url) { + url_ = url; + has_url_ = true; +} + +} // namespace extensions diff --git a/chrome/common/extensions/event_filtering_info.h b/chrome/common/extensions/event_filtering_info.h new file mode 100644 index 0000000..e7077f1 --- /dev/null +++ b/chrome/common/extensions/event_filtering_info.h @@ -0,0 +1,39 @@ +// 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_EVENT_FILTERING_INFO_H_ +#define CHROME_COMMON_EXTENSIONS_EVENT_FILTERING_INFO_H_ +#pragma once + +#include "googleurl/src/gurl.h" + +namespace extensions { + +// Extra information about an event that is used in event filtering. +// +// This is the information that is matched against criteria specified in JS +// extension event listeners. Eg: +// +// chrome.someApi.onSomeEvent.addListener(cb, +// {url: [{hostSuffix: 'google.com'}], +// tabId: 1}); +class EventFilteringInfo { + public: + EventFilteringInfo(); + ~EventFilteringInfo(); + void SetURL(const GURL& url); + + bool has_url() const { return has_url_; } + const GURL& url() const { return url_; } + + private: + bool has_url_; + GURL url_; + + DISALLOW_COPY_AND_ASSIGN(EventFilteringInfo); +}; + +} // namespace extensions + +#endif // CHROME_COMMON_EXTENSIONS_EVENT_FILTERING_INFO_H_ diff --git a/chrome/common/extensions/event_matcher.cc b/chrome/common/extensions/event_matcher.cc new file mode 100644 index 0000000..1f9e474 --- /dev/null +++ b/chrome/common/extensions/event_matcher.cc @@ -0,0 +1,22 @@ +// 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/event_matcher.h" +#include "chrome/common/extensions/event_filtering_info.h" + +namespace extensions { + +EventMatcher::EventMatcher() { +} + +EventMatcher::~EventMatcher() { +} + +bool EventMatcher::MatchNonURLCriteria( + const EventFilteringInfo& event_info) const { + // There is currently no criteria apart from URL criteria. + return true; +} + +} // namespace extensions diff --git a/chrome/common/extensions/event_matcher.h b/chrome/common/extensions/event_matcher.h new file mode 100644 index 0000000..7f91962 --- /dev/null +++ b/chrome/common/extensions/event_matcher.h @@ -0,0 +1,50 @@ +// 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_EVENT_MATCHER_H_ +#define CHROME_COMMON_EXTENSIONS_EVENT_MATCHER_H_ +#pragma once + +#include "base/memory/scoped_ptr.h" +#include "base/values.h" + +namespace extensions { + +class EventFilteringInfo; + +// Matches EventFilteringInfos against a set of criteria. This is intended to +// be used by EventFilter which performs efficient URL matching across +// potentially many EventMatchers itself. This is why this class only exposes +// MatchNonURLCriteria() - URL matching is handled by EventFilter. +class EventMatcher { + public: + EventMatcher(); + ~EventMatcher(); + + // Returns true if |event_info| satisfies this matcher's criteria, not taking + // into consideration any URL criteria. + bool MatchNonURLCriteria(const EventFilteringInfo& event_info) const; + + void set_url_filters(scoped_ptr<base::ListValue> url_filters) { + url_filters_ = url_filters.Pass(); + } + + // Returns NULL if no url_filters have been specified. + base::ListValue* url_filters() const { + return url_filters_.get(); + } + + bool has_url_filters() const { + return url_filters_.get() && !url_filters_->empty(); + } + + private: + scoped_ptr<base::ListValue> url_filters_; + + DISALLOW_COPY_AND_ASSIGN(EventMatcher); +}; + +} // namespace extensions + +#endif // CHROME_COMMON_EXTENSIONS_EVENT_MATCHER_H_ |