blob: 66573308198860270b2ccb74eea232415b1947b5 [file] [log] [blame]
Istiaque Ahmedb9af5f82017-09-20 18:19:451// 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_EVENT_BOOKKEEPER_H_
6#define EXTENSIONS_RENDERER_EVENT_BOOKKEEPER_H_
7
8#include <map>
9#include <memory>
10#include <set>
11#include <string>
12
13#include "base/macros.h"
14#include "extensions/common/event_filter.h"
15#include "extensions/common/extension_id.h"
16
17namespace base {
18class DictionaryValue;
19}
20
21namespace extensions {
22class EventFilter;
23class ScriptContext;
24class ValueCounter;
25
26// Class to manage thread (main or worker) specific event global data.
27//
28// TODO(lazyboy): This class could use an IPCMessageSender to also notify the
29// browser/ about the changes in the event data it manages. Currently this is
30// done from EventBindings, i.e. EventBindings updates/queries EventBookkeeper
31// and then notifies the browser/.
32// TODO(devlin/lazyboy): This class is only necessary with JS-based bindings.
33// Remove it when Native bindings launch.
34class EventBookkeeper {
35 public:
36 EventBookkeeper();
37 ~EventBookkeeper();
38
39 // Returns the instance of EventBookkeeper that belongs to current thread.
40 static EventBookkeeper* Get();
41
42 // Increments the number of event-listeners for the given |event_name| and
43 // ScriptContext. Returns the count after the increment.
44 int IncrementEventListenerCount(ScriptContext* script_context,
45 const std::string& event_name);
46 // Decrements the number of event-listeners for the given |event_name| and
47 // ScriptContext. Returns the count after the decrement.
48 int DecrementEventListenerCount(ScriptContext* script_context,
49 const std::string& event_name);
50
51 // Returns the EventFilter.
52 EventFilter& event_filter() { return event_filter_; }
53
54 // Adds a filter to |event_name| in |extension_id|, returning true if it
55 // was the first filter for that event in that extension.
56 bool AddFilter(const std::string& event_name,
57 const ExtensionId& extension_id,
58 const base::DictionaryValue& filter);
59 // Removes a filter from |event_name| in |extension_id|, returning true if it
60 // was the last filter for that event in that extension.
61 bool RemoveFilter(const std::string& event_name,
62 const ExtensionId& extension_id,
63 base::DictionaryValue* filter);
64
65 // Returns true if there is an event (managed or unmanaged) with the given
66 // context and event name.
67 bool HasListener(ScriptContext* script_context,
68 const std::string& event_name);
69
70 void AddUnmanagedEvent(ScriptContext* context, const std::string& event_name);
71 void RemoveUnmanagedEvent(ScriptContext* context,
72 const std::string& event_name);
73 void RemoveAllUnmanagedListeners(ScriptContext* context);
74
75 private:
76 using EventName = std::string;
77
78 // A map of event name to the number of contexts listening to that event.
79 using EventListenerCounts = std::map<EventName, int>;
80 // Maps context id -> (map of event name -> listener count).
81 using AllCounts = std::map<std::string, EventListenerCounts>;
82
83 using FilteredEventListenerKey = std::pair<ExtensionId, EventName>;
84 // A map of <extension id, event name> pair to listener counts.
85 using FilteredEventListenerCounts =
86 std::map<FilteredEventListenerKey, std::unique_ptr<ValueCounter>>;
87
88 // A map of context to name of events the context has.
89 using UnmanagedListenerMap = std::map<ScriptContext*, std::set<std::string>>;
90
91 // Used to notify the browser about event listeners when we transition between
92 // 0 and 1.
93 AllCounts listener_counts_;
94
95 // The event filter.
96 EventFilter event_filter_;
97
98 // A map of (extension ID, event name) pairs to the filtered listener counts
99 // for that pair. The map is used to keep track of which filters are in effect
100 // for which events. Used to notify the browser about filtered event
101 // listeners when we transition between 0 and 1.
102 FilteredEventListenerCounts filtered_listener_counts_;
103
104 // A collection of the unmanaged events (i.e., those for which the browser is
105 // not notified of changes) that have listeners, by context.
106 UnmanagedListenerMap unmanaged_listeners_;
107
108 DISALLOW_COPY_AND_ASSIGN(EventBookkeeper);
109};
110
111} // namespace extensions
112
113#endif // EXTENSIONS_RENDERER_EVENT_BOOKKEEPER_H_