Home | History | Annotate | Download | only in browser
      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.
      4 
      5 #ifndef EXTENSIONS_BROWSER_EVENT_LISTENER_MAP_H_
      6 #define EXTENSIONS_BROWSER_EVENT_LISTENER_MAP_H_
      7 
      8 #include <map>
      9 #include <set>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "base/memory/scoped_ptr.h"
     14 #include "extensions/common/event_filter.h"
     15 
     16 namespace base {
     17 class DictionaryValue;
     18 }
     19 
     20 namespace content {
     21 class BrowserContext;
     22 class RenderProcessHost;
     23 }
     24 
     25 class ListenerRemovalListener;
     26 
     27 namespace extensions {
     28 struct Event;
     29 
     30 // A listener for an extension event. A listener is essentially an endpoint
     31 // that an event can be dispatched to.
     32 //
     33 // This is a lazy listener if |IsLazy| is returns true, and a filtered listener
     34 // if |filter| is defined.
     35 //
     36 // A lazy listener is added to an event to indicate that a lazy background page
     37 // is listening to the event. It is associated with no process, so to dispatch
     38 // an event to a lazy listener one must start a process running the associated
     39 // extension and dispatch the event to that.
     40 //
     41 class EventListener {
     42  public:
     43   // |filter| represents a generic filter structure that EventFilter knows how
     44   // to filter events with. A typical filter instance will look like
     45   //
     46   // {
     47   //   url: [{hostSuffix: 'google.com'}],
     48   //   tabId: 5
     49   // }
     50   EventListener(const std::string& event_name,
     51                 const std::string& extension_id,
     52                 content::RenderProcessHost* process,
     53                 scoped_ptr<base::DictionaryValue> filter);
     54   ~EventListener();
     55 
     56   bool Equals(const EventListener* other) const;
     57 
     58   scoped_ptr<EventListener> Copy() const;
     59 
     60   // Returns true in the case of a lazy background page, and thus no process.
     61   bool IsLazy() const;
     62 
     63   // Modifies this listener to be a lazy listener, clearing process references.
     64   void MakeLazy();
     65 
     66   // Returns the browser context associated with the listener, or NULL if
     67   // IsLazy.
     68   content::BrowserContext* GetBrowserContext() const;
     69 
     70   const std::string event_name() const { return event_name_; }
     71   const std::string extension_id() const { return extension_id_; }
     72   content::RenderProcessHost* process() const { return process_; }
     73   base::DictionaryValue* filter() const { return filter_.get(); }
     74   EventFilter::MatcherID matcher_id() const { return matcher_id_; }
     75   void set_matcher_id(EventFilter::MatcherID id) { matcher_id_ = id; }
     76 
     77  private:
     78   const std::string event_name_;
     79   const std::string extension_id_;
     80   content::RenderProcessHost* process_;
     81   scoped_ptr<base::DictionaryValue> filter_;
     82   EventFilter::MatcherID matcher_id_;  // -1 if unset.
     83 
     84   DISALLOW_COPY_AND_ASSIGN(EventListener);
     85 };
     86 
     87 // Holds listeners for extension events and can answer questions about which
     88 // listeners are interested in what events.
     89 class EventListenerMap {
     90  public:
     91   typedef std::vector<linked_ptr<EventListener> > ListenerList;
     92 
     93   class Delegate {
     94    public:
     95     virtual ~Delegate() {}
     96     virtual void OnListenerAdded(const EventListener* listener) = 0;
     97     virtual void OnListenerRemoved(const EventListener* listener) = 0;
     98   };
     99 
    100   explicit EventListenerMap(Delegate* delegate);
    101   ~EventListenerMap();
    102 
    103   // Add a listener for a particular event. GetEventListeners() will include a
    104   // weak pointer to |listener| in its results if passed a relevant
    105   // extensions::Event.
    106   // Returns true if the listener was added (in the case that it has never been
    107   // seen before).
    108   bool AddListener(scoped_ptr<EventListener> listener);
    109 
    110   // Remove a listener that .Equals() |listener|.
    111   // Returns true if the listener was removed .
    112   bool RemoveListener(const EventListener* listener);
    113 
    114   // Returns the set of listeners that want to be notified of |event|.
    115   std::set<const EventListener*> GetEventListeners(const Event& event);
    116 
    117   const ListenerList& GetEventListenersByName(const std::string& event_name) {
    118     return listeners_[event_name];
    119   }
    120 
    121   // Removes all listeners with process equal to |process|.
    122   void RemoveListenersForProcess(const content::RenderProcessHost* process);
    123 
    124   // Returns true if there are any listeners on the event named |event_name|.
    125   bool HasListenerForEvent(const std::string& event_name);
    126 
    127   // Returns true if there are any listeners on |event_name| from
    128   // |extension_id|.
    129   bool HasListenerForExtension(const std::string& extension_id,
    130                                const std::string& event_name);
    131 
    132   // Returns true if this map contains an EventListener that .Equals()
    133   // |listener|.
    134   bool HasListener(const EventListener* listener);
    135 
    136   // Returns true if there is a listener for |extension_id| in |process|.
    137   bool HasProcessListener(content::RenderProcessHost* process,
    138                           const std::string& extension_id);
    139 
    140   // Removes any lazy listeners that |extension_id| has added.
    141   void RemoveLazyListenersForExtension(const std::string& extension_id);
    142 
    143   // Adds unfiltered lazy listeners as described their serialised descriptions.
    144   // |event_names| the names of the lazy events.
    145   // Note that we can only load lazy listeners in this fashion, because there
    146   // is no way to serialise a RenderProcessHost*.
    147   void LoadUnfilteredLazyListeners(const std::string& extension_id,
    148                                    const std::set<std::string>& event_names);
    149 
    150   // Adds filtered lazy listeners as described their serialised descriptions.
    151   // |filtered| contains a map from event names to filters, each pairing
    152   // defining a lazy filtered listener.
    153   void LoadFilteredLazyListeners(
    154       const std::string& extension_id,
    155       const base::DictionaryValue& filtered);
    156 
    157  private:
    158   // The key here is an event name.
    159   typedef std::map<std::string, ListenerList> ListenerMap;
    160 
    161   void CleanupListener(EventListener* listener);
    162   bool IsFilteredEvent(const Event& event) const;
    163   scoped_ptr<EventMatcher> ParseEventMatcher(
    164       base::DictionaryValue* filter_dict);
    165 
    166   // Listens for removals from this map.
    167   Delegate* delegate_;
    168 
    169   std::set<std::string> filtered_events_;
    170   ListenerMap listeners_;
    171 
    172   std::map<EventFilter::MatcherID, EventListener*> listeners_by_matcher_id_;
    173 
    174   EventFilter event_filter_;
    175 
    176   DISALLOW_COPY_AND_ASSIGN(EventListenerMap);
    177 };
    178 
    179 }  // namespace extensions
    180 
    181 #endif  // EXTENSIONS_BROWSER_EVENT_LISTENER_MAP_H_
    182