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