1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ipc/message_filter_router.h"
10 #include "ipc/ipc_message_macros.h"
11 #include "ipc/ipc_message_start.h"
12 #include "ipc/ipc_message_utils.h"
13 #include "ipc/message_filter.h"
19 bool TryFiltersImpl(MessageFilterRouter::MessageFilters& filters,
20 const IPC::Message& message) {
21 for (size_t i = 0; i < filters.size(); ++i) {
22 if (filters[i]->OnMessageReceived(message)) {
29 bool RemoveFilterImpl(MessageFilterRouter::MessageFilters& filters,
30 MessageFilter* filter) {
31 MessageFilterRouter::MessageFilters::iterator it =
32 std::remove(filters.begin(), filters.end(), filter);
33 if (it == filters.end())
36 filters.erase(it, filters.end());
40 bool ValidMessageClass(int message_class) {
41 return message_class >= 0 && message_class < LastIPCMsgStart;
46 MessageFilterRouter::MessageFilterRouter() = default;
47 MessageFilterRouter::~MessageFilterRouter() = default;
49 void MessageFilterRouter::AddFilter(MessageFilter* filter) {
50 // Determine if the filter should be applied to all messages, or only
51 // messages of a certain class.
52 std::vector<uint32_t> supported_message_classes;
53 if (filter->GetSupportedMessageClasses(&supported_message_classes)) {
54 for (size_t i = 0; i < supported_message_classes.size(); ++i) {
55 const int message_class = supported_message_classes[i];
56 DCHECK(ValidMessageClass(message_class));
57 // Safely ignore repeated subscriptions to a given message class for the
58 // current filter being added.
59 if (!message_class_filters_[message_class].empty() &&
60 message_class_filters_[message_class].back() == filter) {
63 message_class_filters_[message_class].push_back(filter);
66 global_filters_.push_back(filter);
70 void MessageFilterRouter::RemoveFilter(MessageFilter* filter) {
71 if (RemoveFilterImpl(global_filters_, filter))
74 for (size_t i = 0; i < std::size(message_class_filters_); ++i)
75 RemoveFilterImpl(message_class_filters_[i], filter);
78 bool MessageFilterRouter::TryFilters(const Message& message) {
79 if (TryFiltersImpl(global_filters_, message))
82 const int message_class = IPC_MESSAGE_CLASS(message);
83 if (!ValidMessageClass(message_class))
86 return TryFiltersImpl(message_class_filters_[message_class], message);
89 void MessageFilterRouter::Clear() {
90 global_filters_.clear();
91 for (size_t i = 0; i < std::size(message_class_filters_); ++i)
92 message_class_filters_[i].clear();