Fix import error in mac_platform_backend.py
[chromium-blink-merge.git] / extensions / browser / event_listener_map.cc
blob1c9fba4a64669d14ceaa7d5a1939afee8d7af5f9
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/browser/event_listener_map.h"
7 #include "base/values.h"
8 #include "extensions/browser/event_router.h"
9 #include "ipc/ipc_message.h"
11 using base::DictionaryValue;
13 namespace extensions {
15 typedef EventFilter::MatcherID MatcherID;
17 EventListener::EventListener(const std::string& event_name,
18 const std::string& extension_id,
19 content::RenderProcessHost* process,
20 scoped_ptr<DictionaryValue> filter)
21 : event_name(event_name),
22 extension_id(extension_id),
23 process(process),
24 filter(filter.Pass()),
25 matcher_id(-1) {}
27 EventListener::~EventListener() {}
29 bool EventListener::Equals(const EventListener* other) const {
30 // We don't check matcher_id equality because we want a listener with a
31 // filter that hasn't been added to EventFilter to match one that is
32 // equivalent but has.
33 return event_name == other->event_name &&
34 extension_id == other->extension_id &&
35 process == other->process &&
36 ((!!filter.get()) == (!!other->filter.get())) &&
37 (!filter.get() || filter->Equals(other->filter.get()));
40 scoped_ptr<EventListener> EventListener::Copy() const {
41 scoped_ptr<DictionaryValue> filter_copy;
42 if (filter)
43 filter_copy.reset(filter->DeepCopy());
44 return scoped_ptr<EventListener>(new EventListener(event_name, extension_id,
45 process,
46 filter_copy.Pass()));
49 EventListenerMap::EventListenerMap(Delegate* delegate)
50 : delegate_(delegate) {
53 EventListenerMap::~EventListenerMap() {}
55 bool EventListenerMap::AddListener(scoped_ptr<EventListener> listener) {
56 if (HasListener(listener.get()))
57 return false;
58 if (listener->filter) {
59 scoped_ptr<EventMatcher> matcher(ParseEventMatcher(listener->filter.get()));
60 MatcherID id = event_filter_.AddEventMatcher(listener->event_name,
61 matcher.Pass());
62 listener->matcher_id = id;
63 listeners_by_matcher_id_[id] = listener.get();
64 filtered_events_.insert(listener->event_name);
66 linked_ptr<EventListener> listener_ptr(listener.release());
67 listeners_[listener_ptr->event_name].push_back(listener_ptr);
69 delegate_->OnListenerAdded(listener_ptr.get());
71 return true;
74 scoped_ptr<EventMatcher> EventListenerMap::ParseEventMatcher(
75 DictionaryValue* filter_dict) {
76 return scoped_ptr<EventMatcher>(new EventMatcher(
77 scoped_ptr<DictionaryValue>(filter_dict->DeepCopy()), MSG_ROUTING_NONE));
80 bool EventListenerMap::RemoveListener(const EventListener* listener) {
81 ListenerList& listeners = listeners_[listener->event_name];
82 for (ListenerList::iterator it = listeners.begin(); it != listeners.end();
83 it++) {
84 if ((*it)->Equals(listener)) {
85 CleanupListener(it->get());
86 // Popping from the back should be cheaper than erase(it).
87 std::swap(*it, listeners.back());
88 listeners.pop_back();
89 delegate_->OnListenerRemoved(listener);
90 return true;
93 return false;
96 bool EventListenerMap::HasListenerForEvent(const std::string& event_name) {
97 ListenerMap::iterator it = listeners_.find(event_name);
98 return it != listeners_.end() && !it->second.empty();
101 bool EventListenerMap::HasListenerForExtension(
102 const std::string& extension_id,
103 const std::string& event_name) {
104 ListenerMap::iterator it = listeners_.find(event_name);
105 if (it == listeners_.end())
106 return false;
108 for (ListenerList::iterator it2 = it->second.begin();
109 it2 != it->second.end(); it2++) {
110 if ((*it2)->extension_id == extension_id)
111 return true;
113 return false;
116 bool EventListenerMap::HasListener(const EventListener* listener) {
117 ListenerMap::iterator it = listeners_.find(listener->event_name);
118 if (it == listeners_.end())
119 return false;
120 for (ListenerList::iterator it2 = it->second.begin();
121 it2 != it->second.end(); it2++) {
122 if ((*it2)->Equals(listener)) {
123 return true;
126 return false;
129 bool EventListenerMap::HasProcessListener(content::RenderProcessHost* process,
130 const std::string& extension_id) {
131 for (ListenerMap::iterator it = listeners_.begin(); it != listeners_.end();
132 it++) {
133 for (ListenerList::iterator it2 = it->second.begin();
134 it2 != it->second.end(); it2++) {
135 if ((*it2)->process == process && (*it2)->extension_id == extension_id)
136 return true;
139 return false;
142 void EventListenerMap::RemoveLazyListenersForExtension(
143 const std::string& extension_id) {
144 for (ListenerMap::iterator it = listeners_.begin(); it != listeners_.end();
145 it++) {
146 for (ListenerList::iterator it2 = it->second.begin();
147 it2 != it->second.end();) {
148 if (!(*it2)->process && (*it2)->extension_id == extension_id) {
149 CleanupListener(it2->get());
150 it2 = it->second.erase(it2);
151 } else {
152 it2++;
158 void EventListenerMap::LoadUnfilteredLazyListeners(
159 const std::string& extension_id,
160 const std::set<std::string>& event_names) {
161 for (std::set<std::string>::const_iterator it = event_names.begin();
162 it != event_names.end(); ++it) {
163 AddListener(scoped_ptr<EventListener>(new EventListener(
164 *it, extension_id, NULL, scoped_ptr<DictionaryValue>())));
168 void EventListenerMap::LoadFilteredLazyListeners(
169 const std::string& extension_id,
170 const DictionaryValue& filtered) {
171 for (DictionaryValue::Iterator it(filtered); !it.IsAtEnd(); it.Advance()) {
172 // We skip entries if they are malformed.
173 const base::ListValue* filter_list = NULL;
174 if (!it.value().GetAsList(&filter_list))
175 continue;
176 for (size_t i = 0; i < filter_list->GetSize(); i++) {
177 const DictionaryValue* filter = NULL;
178 if (!filter_list->GetDictionary(i, &filter))
179 continue;
180 AddListener(scoped_ptr<EventListener>(new EventListener(
181 it.key(), extension_id, NULL,
182 scoped_ptr<DictionaryValue>(filter->DeepCopy()))));
187 std::set<const EventListener*> EventListenerMap::GetEventListeners(
188 const Event& event) {
189 std::set<const EventListener*> interested_listeners;
190 if (IsFilteredEvent(event)) {
191 // Look up the interested listeners via the EventFilter.
192 std::set<MatcherID> ids =
193 event_filter_.MatchEvent(event.event_name, event.filter_info,
194 MSG_ROUTING_NONE);
195 for (std::set<MatcherID>::iterator id = ids.begin(); id != ids.end();
196 id++) {
197 EventListener* listener = listeners_by_matcher_id_[*id];
198 CHECK(listener);
199 interested_listeners.insert(listener);
201 } else {
202 ListenerList& listeners = listeners_[event.event_name];
203 for (ListenerList::const_iterator it = listeners.begin();
204 it != listeners.end(); it++) {
205 interested_listeners.insert(it->get());
209 return interested_listeners;
212 void EventListenerMap::RemoveListenersForProcess(
213 const content::RenderProcessHost* process) {
214 CHECK(process);
215 for (ListenerMap::iterator it = listeners_.begin(); it != listeners_.end();
216 it++) {
217 for (ListenerList::iterator it2 = it->second.begin();
218 it2 != it->second.end();) {
219 if ((*it2)->process == process) {
220 linked_ptr<EventListener> listener(*it2);
221 CleanupListener(it2->get());
222 it2 = it->second.erase(it2);
223 delegate_->OnListenerRemoved(listener.get());
224 } else {
225 it2++;
231 void EventListenerMap::CleanupListener(EventListener* listener) {
232 // If the listener doesn't have a filter then we have nothing to clean up.
233 if (listener->matcher_id == -1)
234 return;
235 event_filter_.RemoveEventMatcher(listener->matcher_id);
236 CHECK_EQ(1u, listeners_by_matcher_id_.erase(listener->matcher_id));
239 bool EventListenerMap::IsFilteredEvent(const Event& event) const {
240 return filtered_events_.count(event.event_name) > 0u;
243 } // namespace extensions