OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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_RENDERER_API_EVENT_LISTENERS_H_ |
| 6 #define EXTENSIONS_RENDERER_API_EVENT_LISTENERS_H_ |
| 7 |
| 8 #include <string> |
| 9 #include <vector> |
| 10 |
| 11 #include "base/callback.h" |
| 12 #include "base/macros.h" |
| 13 #include "extensions/common/value_counter.h" |
| 14 #include "extensions/renderer/api_binding_types.h" |
| 15 #include "v8/include/v8.h" |
| 16 |
| 17 namespace base { |
| 18 class DictionaryValue; |
| 19 } |
| 20 |
| 21 namespace extensions { |
| 22 class EventFilter; |
| 23 class EventFilteringInfo; |
| 24 |
| 25 // A base class to hold listeners for a given event. This allows for adding, |
| 26 // removing, and querying listeners in the list, and calling a callback when |
| 27 // transitioning from 0 -> 1 or 1 -> 0 listeners. |
| 28 class APIEventListeners { |
| 29 public: |
| 30 using ListenersUpdated = |
| 31 base::Callback<void(binding::EventListenersChanged, |
| 32 const base::DictionaryValue* filter, |
| 33 v8::Local<v8::Context> context)>; |
| 34 |
| 35 virtual ~APIEventListeners() = default; |
| 36 |
| 37 // Adds the given |listener| to the list, possibly associating it with the |
| 38 // given |filter|. Returns true if the listener is added. Populates |error| |
| 39 // with any errors encountered. Note that |error| is *not* always populated |
| 40 // if false is returned, since we don't consider trying to re-add a listener |
| 41 // to be an error. |
| 42 virtual bool AddListener(v8::Local<v8::Function> listener, |
| 43 v8::Local<v8::Object> filter, |
| 44 v8::Local<v8::Context> context, |
| 45 std::string* error) = 0; |
| 46 |
| 47 // Removes the given |listener|, if it's present in the list. |
| 48 virtual void RemoveListener(v8::Local<v8::Function> listener, |
| 49 v8::Local<v8::Context> context) = 0; |
| 50 |
| 51 // Returns true if the given |listener| is in the list. |
| 52 virtual bool HasListener(v8::Local<v8::Function> listener) = 0; |
| 53 |
| 54 // Returns the number of listeners in the list. |
| 55 virtual size_t GetNumListeners() = 0; |
| 56 |
| 57 // Returns the listeners that should be notified for the given |filter|. |
| 58 virtual std::vector<v8::Local<v8::Function>> GetListeners( |
| 59 const EventFilteringInfo* filter, |
| 60 v8::Local<v8::Context> context) = 0; |
| 61 |
| 62 // Invalidates the list. |
| 63 virtual void Invalidate(v8::Local<v8::Context> context) = 0; |
| 64 |
| 65 protected: |
| 66 APIEventListeners() {} |
| 67 |
| 68 private: |
| 69 DISALLOW_COPY_AND_ASSIGN(APIEventListeners); |
| 70 }; |
| 71 |
| 72 // A listener list implementation that doesn't support filtering. Each event |
| 73 // dispatched is dispatched to all the associated listeners. |
| 74 class UnfilteredEventListeners final : public APIEventListeners { |
| 75 public: |
| 76 UnfilteredEventListeners(const ListenersUpdated& listeners_updated); |
| 77 ~UnfilteredEventListeners() override; |
| 78 |
| 79 bool AddListener(v8::Local<v8::Function> listener, |
| 80 v8::Local<v8::Object> filter, |
| 81 v8::Local<v8::Context> context, |
| 82 std::string* error) override; |
| 83 void RemoveListener(v8::Local<v8::Function> listener, |
| 84 v8::Local<v8::Context> context) override; |
| 85 bool HasListener(v8::Local<v8::Function> listener) override; |
| 86 size_t GetNumListeners() override; |
| 87 std::vector<v8::Local<v8::Function>> GetListeners( |
| 88 const EventFilteringInfo* filter, |
| 89 v8::Local<v8::Context> context) override; |
| 90 void Invalidate(v8::Local<v8::Context> context) override; |
| 91 |
| 92 private: |
| 93 // The event listeners associated with this event. |
| 94 // TODO(devlin): Having these listeners held as v8::Globals means that we |
| 95 // need to worry about cycles when a listener holds a reference to the event, |
| 96 // e.g. EventEmitter -> Listener -> EventEmitter. Right now, we handle that by |
| 97 // requiring Invalidate() to be called, but that means that events that aren't |
| 98 // Invalidate()'d earlier can leak until context destruction. We could |
| 99 // circumvent this by storing the listeners strongly in a private propery |
| 100 // (thus traceable by v8), and optionally keep a weak cache on this object. |
| 101 std::vector<v8::Global<v8::Function>> listeners_; |
| 102 |
| 103 ListenersUpdated listeners_updated_; |
| 104 |
| 105 DISALLOW_COPY_AND_ASSIGN(UnfilteredEventListeners); |
| 106 }; |
| 107 |
| 108 // A listener list implementation that supports filtering. Events should only |
| 109 // be dispatched to those listeners whose filters match. Additionally, the |
| 110 // updated callback is triggered any time a listener with a new filter is |
| 111 // added, or the last listener with a given filter is removed. |
| 112 class FilteredEventListeners final : public APIEventListeners { |
| 113 public: |
| 114 FilteredEventListeners(const ListenersUpdated& listeners_updated, |
| 115 const std::string& event_name, |
| 116 EventFilter* event_filter); |
| 117 ~FilteredEventListeners() override; |
| 118 |
| 119 bool AddListener(v8::Local<v8::Function> listener, |
| 120 v8::Local<v8::Object> filter, |
| 121 v8::Local<v8::Context> context, |
| 122 std::string* error) override; |
| 123 void RemoveListener(v8::Local<v8::Function> listener, |
| 124 v8::Local<v8::Context> context) override; |
| 125 bool HasListener(v8::Local<v8::Function> listener) override; |
| 126 size_t GetNumListeners() override; |
| 127 std::vector<v8::Local<v8::Function>> GetListeners( |
| 128 const EventFilteringInfo* filter, |
| 129 v8::Local<v8::Context> context) override; |
| 130 void Invalidate(v8::Local<v8::Context> context) override; |
| 131 |
| 132 private: |
| 133 struct ListenerData; |
| 134 |
| 135 void InvalidateListener(const ListenerData& listener, |
| 136 v8::Local<v8::Context> context); |
| 137 |
| 138 // Note: See TODO on UnfilteredEventListeners::listeners_. |
| 139 std::vector<ListenerData> listeners_; |
| 140 |
| 141 ListenersUpdated listeners_updated_; |
| 142 |
| 143 std::string event_name_; |
| 144 |
| 145 // The associated EventFilter; required to outlive this object. |
| 146 EventFilter* event_filter_ = nullptr; |
| 147 |
| 148 ValueCounter value_counter_; |
| 149 |
| 150 DISALLOW_COPY_AND_ASSIGN(FilteredEventListeners); |
| 151 }; |
| 152 |
| 153 } // namespace extensions |
| 154 |
| 155 #endif // EXTENSIONS_RENDERER_API_EVENT_LISTENERS_H_ |
OLD | NEW |