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