blob: 71aa192bcf8d6d96826b78b6a4445ff7ff4935fc [file] [log] [blame]
// Copyright 2013 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 <map>
#include <set>
#include <string>
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "extensions/common/event_filter.h"
namespace base {
class DictionaryValue;
namespace content {
class RenderProcessHost;
class ListenerRemovalListener;
namespace extensions {
struct Event;
// 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: ''}],
// tabId: 5
// }
EventListener(const std::string& event_name,
const std::string& extension_id,
content::RenderProcessHost* process,
scoped_ptr<base::DictionaryValue> filter);
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<base::DictionaryValue> filter;
EventFilter::MatcherID matcher_id;
// Holds listeners for extension events and can answer questions about which
// listeners are interested in what events.
class EventListenerMap {
typedef std::vector<linked_ptr<EventListener> > ListenerList;
class Delegate {
virtual ~Delegate() {}
virtual void OnListenerAdded(const EventListener* listener) = 0;
virtual void OnListenerRemoved(const EventListener* listener) = 0;
explicit EventListenerMap(Delegate* delegate);
// Add a listener for a particular event. GetEventListeners() will include a
// weak pointer to |listener| in its results if passed a relevant
// extensions::Event.
// 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 Event& event);
const ListenerList& GetEventListenersByName(const std::string& event_name) {
return listeners_[event_name];
// 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 base::DictionaryValue& filtered);
// The key here is an event name.
typedef std::map<std::string, ListenerList> ListenerMap;
void CleanupListener(EventListener* listener);
bool IsFilteredEvent(const Event& event) const;
scoped_ptr<EventMatcher> ParseEventMatcher(
base::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_;
} // namespace extensions