1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_listener_map.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/public/browser/render_process_host.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ipc/ipc_message.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "url/gurl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using base::DictionaryValue;
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef EventFilter::MatcherID MatcherID;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_ptr<EventListener> EventListener::ForExtension(
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& event_name,
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& extension_id,
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::RenderProcessHost* process,
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<base::DictionaryValue> filter) {
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return make_scoped_ptr(new EventListener(
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      event_name, extension_id, GURL(), process, filter.Pass()));
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_ptr<EventListener> EventListener::ForURL(
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& event_name,
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& listener_url,
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    content::RenderProcessHost* process,
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<base::DictionaryValue> filter) {
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return make_scoped_ptr(
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new EventListener(event_name, "", listener_url, process, filter.Pass()));
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EventListener::~EventListener() {}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventListener::Equals(const EventListener* other) const {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't check matcher_id equality because we want a listener with a
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // filter that hasn't been added to EventFilter to match one that is
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // equivalent but has.
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return event_name_ == other->event_name_ &&
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         extension_id_ == other->extension_id_ &&
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         listener_url_ == other->listener_url_ && process_ == other->process_ &&
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)         ((!!filter_.get()) == (!!other->filter_.get())) &&
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)         (!filter_.get() || filter_->Equals(other->filter_.get()));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<EventListener> EventListener::Copy() const {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> filter_copy;
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (filter_)
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    filter_copy.reset(filter_->DeepCopy());
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return scoped_ptr<EventListener>(new EventListener(
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      event_name_, extension_id_, listener_url_, process_, filter_copy.Pass()));
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool EventListener::IsLazy() const {
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return !process_;
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void EventListener::MakeLazy() {
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  process_ = NULL;
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)content::BrowserContext* EventListener::GetBrowserContext() const {
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return process_ ? process_->GetBrowserContext() : NULL;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)EventListener::EventListener(const std::string& event_name,
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             const std::string& extension_id,
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             const GURL& listener_url,
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             content::RenderProcessHost* process,
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             scoped_ptr<DictionaryValue> filter)
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : event_name_(event_name),
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      extension_id_(extension_id),
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      listener_url_(listener_url),
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      process_(process),
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      filter_(filter.Pass()),
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      matcher_id_(-1) {
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EventListenerMap::EventListenerMap(Delegate* delegate)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : delegate_(delegate) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EventListenerMap::~EventListenerMap() {}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventListenerMap::AddListener(scoped_ptr<EventListener> listener) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasListener(listener.get()))
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (listener->filter()) {
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<EventMatcher> matcher(ParseEventMatcher(listener->filter()));
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    MatcherID id =
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        event_filter_.AddEventMatcher(listener->event_name(), matcher.Pass());
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    listener->set_matcher_id(id);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listeners_by_matcher_id_[id] = listener.get();
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    filtered_events_.insert(listener->event_name());
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  linked_ptr<EventListener> listener_ptr(listener.release());
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  listeners_[listener_ptr->event_name()].push_back(listener_ptr);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->OnListenerAdded(listener_ptr.get());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<EventMatcher> EventListenerMap::ParseEventMatcher(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* filter_dict) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return scoped_ptr<EventMatcher>(new EventMatcher(
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      make_scoped_ptr(filter_dict->DeepCopy()), MSG_ROUTING_NONE));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventListenerMap::RemoveListener(const EventListener* listener) {
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ListenerList& listeners = listeners_[listener->event_name()];
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ListenerList::iterator it = listeners.begin(); it != listeners.end();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it++) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*it)->Equals(listener)) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CleanupListener(it->get());
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Popping from the back should be cheaper than erase(it).
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::swap(*it, listeners.back());
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      listeners.pop_back();
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate_->OnListenerRemoved(listener);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventListenerMap::HasListenerForEvent(const std::string& event_name) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListenerMap::iterator it = listeners_.find(event_name);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return it != listeners_.end() && !it->second.empty();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventListenerMap::HasListenerForExtension(
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& event_name) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListenerMap::iterator it = listeners_.find(event_name);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == listeners_.end())
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ListenerList::iterator it2 = it->second.begin();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it2 != it->second.end(); it2++) {
146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if ((*it2)->extension_id() == extension_id)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventListenerMap::HasListener(const EventListener* listener) {
153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ListenerMap::iterator it = listeners_.find(listener->event_name());
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == listeners_.end())
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ListenerList::iterator it2 = it->second.begin();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it2 != it->second.end(); it2++) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*it2)->Equals(listener)) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventListenerMap::HasProcessListener(content::RenderProcessHost* process,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const std::string& extension_id) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ListenerMap::iterator it = listeners_.begin(); it != listeners_.end();
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it++) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (ListenerList::iterator it2 = it->second.begin();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it2 != it->second.end(); it2++) {
171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if ((*it2)->process() == process &&
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          (*it2)->extension_id() == extension_id)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventListenerMap::RemoveLazyListenersForExtension(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ListenerMap::iterator it = listeners_.begin(); it != listeners_.end();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it++) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (ListenerList::iterator it2 = it->second.begin();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it2 != it->second.end();) {
185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if ((*it2)->IsLazy() && (*it2)->extension_id() == extension_id) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CleanupListener(it2->get());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        it2 = it->second.erase(it2);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        it2++;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventListenerMap::LoadUnfilteredLazyListeners(
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::set<std::string>& event_names) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::set<std::string>::const_iterator it = event_names.begin();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != event_names.end(); ++it) {
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    AddListener(EventListener::ForExtension(
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        *it, extension_id, NULL, scoped_ptr<DictionaryValue>()));
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventListenerMap::LoadFilteredLazyListeners(
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const DictionaryValue& filtered) {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (DictionaryValue::Iterator it(filtered); !it.IsAtEnd(); it.Advance()) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We skip entries if they are malformed.
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::ListValue* filter_list = NULL;
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!it.value().GetAsList(&filter_list))
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < filter_list->GetSize(); i++) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const DictionaryValue* filter = NULL;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!filter_list->GetDictionary(i, &filter))
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      AddListener(EventListener::ForExtension(
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          it.key(), extension_id, NULL, make_scoped_ptr(filter->DeepCopy())));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::set<const EventListener*> EventListenerMap::GetEventListeners(
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Event& event) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<const EventListener*> interested_listeners;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsFilteredEvent(event)) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Look up the interested listeners via the EventFilter.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::set<MatcherID> ids =
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        event_filter_.MatchEvent(event.event_name, event.filter_info,
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            MSG_ROUTING_NONE);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (std::set<MatcherID>::iterator id = ids.begin(); id != ids.end();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         id++) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EventListener* listener = listeners_by_matcher_id_[*id];
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(listener);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      interested_listeners.insert(listener);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ListenerList& listeners = listeners_[event.event_name];
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (ListenerList::const_iterator it = listeners.begin();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != listeners.end(); it++) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      interested_listeners.insert(it->get());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return interested_listeners;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventListenerMap::RemoveListenersForProcess(
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::RenderProcessHost* process) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(process);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ListenerMap::iterator it = listeners_.begin(); it != listeners_.end();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it++) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (ListenerList::iterator it2 = it->second.begin();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it2 != it->second.end();) {
255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if ((*it2)->process() == process) {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        linked_ptr<EventListener> listener(*it2);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CleanupListener(it2->get());
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        it2 = it->second.erase(it2);
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        delegate_->OnListenerRemoved(listener.get());
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        it2++;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EventListenerMap::CleanupListener(EventListener* listener) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the listener doesn't have a filter then we have nothing to clean up.
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (listener->matcher_id() == -1)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  event_filter_.RemoveEventMatcher(listener->matcher_id());
272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  CHECK_EQ(1u, listeners_by_matcher_id_.erase(listener->matcher_id()));
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventListenerMap::IsFilteredEvent(const Event& event) const {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return filtered_events_.count(event.event_name) > 0u;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
280