1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "extensions/renderer/bindings/listener_tracker.h"
#include "base/check.h"
#include "extensions/common/mojom/event_dispatcher.mojom.h"
#include "extensions/common/value_counter.h"
namespace extensions {
ListenerTracker::ListenerTracker() = default;
ListenerTracker::~ListenerTracker() = default;
bool ListenerTracker::AddUnfilteredListener(const std::string& context_owner_id,
const std::string& event_name) {
ListenerCountMap& listeners = unfiltered_listeners_[context_owner_id];
return ++listeners[event_name] == 1;
}
bool ListenerTracker::RemoveUnfilteredListener(
const std::string& context_owner_id,
const std::string& event_name) {
ListenerCountMap& listeners = unfiltered_listeners_[context_owner_id];
auto iter = listeners.find(event_name);
CHECK(iter != listeners.end());
if (--(iter->second) == 0) {
listeners.erase(iter);
return true;
}
return false;
}
std::pair<bool, int> ListenerTracker::AddFilteredListener(
const std::string& context_owner_id,
const std::string& event_name,
std::unique_ptr<base::Value::Dict> filter,
int routing_id) {
int filter_id = event_filter_.AddEventMatcher(
event_name,
std::make_unique<EventMatcher>(std::move(filter), routing_id));
if (filter_id == -1)
return std::make_pair(false, -1);
FilteredEventListenerKey key(context_owner_id, event_name);
std::unique_ptr<ValueCounter>& counts = filtered_listeners_[key];
if (!counts)
counts = std::make_unique<ValueCounter>();
const EventMatcher* matcher = event_filter_.GetEventMatcher(filter_id);
bool was_first_of_kind = counts->Add(base::Value(matcher->value()->Clone()));
return std::make_pair(was_first_of_kind, filter_id);
}
std::pair<bool, std::unique_ptr<base::Value::Dict>>
ListenerTracker::RemoveFilteredListener(const std::string& context_owner_id,
const std::string& event_name,
int filter_id) {
EventMatcher* matcher = event_filter_.GetEventMatcher(filter_id);
DCHECK(matcher);
FilteredEventListenerKey key(context_owner_id, event_name);
FilteredListeners::const_iterator counts = filtered_listeners_.find(key);
bool was_last_of_kind = false;
CHECK(counts != filtered_listeners_.end());
base::Value filter_copy = base::Value(matcher->value()->Clone());
if (counts->second->Remove(filter_copy)) {
if (counts->second->is_empty()) {
// Clean up if there are no more filters.
filtered_listeners_.erase(counts);
}
was_last_of_kind = true;
}
event_filter_.RemoveEventMatcher(filter_id);
return std::make_pair(
was_last_of_kind,
std::make_unique<base::Value::Dict>(std::move(filter_copy).TakeDict()));
}
std::set<int> ListenerTracker::GetMatchingFilteredListeners(
const std::string& event_name,
mojom::EventFilteringInfoPtr filter,
int routing_id) {
DCHECK(!filter.is_null());
return event_filter_.MatchEvent(event_name, *filter, routing_id);
}
} // namespace extensions
|