1 // Copyright 2014 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.
5 #include "ipc/message_filter_router.h"
9 #include "ipc/ipc_message_macros.h"
10 #include "ipc/ipc_message_utils.h"
11 #include "ipc/message_filter.h"
17 bool TryFiltersImpl(MessageFilterRouter::MessageFilters
& filters
,
18 const IPC::Message
& message
) {
19 for (size_t i
= 0; i
< filters
.size(); ++i
) {
20 if (filters
[i
]->OnMessageReceived(message
)) {
27 bool RemoveFilterImpl(MessageFilterRouter::MessageFilters
& filters
,
28 MessageFilter
* filter
) {
29 MessageFilterRouter::MessageFilters::iterator it
=
30 std::remove(filters
.begin(), filters
.end(), filter
);
31 if (it
== filters
.end())
34 filters
.erase(it
, filters
.end());
38 bool ValidMessageClass(int message_class
) {
39 return message_class
>= 0 && message_class
< LastIPCMsgStart
;
44 MessageFilterRouter::MessageFilterRouter() {}
45 MessageFilterRouter::~MessageFilterRouter() {}
47 void MessageFilterRouter::AddFilter(MessageFilter
* filter
) {
48 // Determine if the filter should be applied to all messages, or only
49 // messages of a certain class.
50 std::vector
<uint32_t> supported_message_classes
;
51 if (filter
->GetSupportedMessageClasses(&supported_message_classes
)) {
52 DCHECK(!supported_message_classes
.empty());
53 for (size_t i
= 0; i
< supported_message_classes
.size(); ++i
) {
54 const int message_class
= supported_message_classes
[i
];
55 DCHECK(ValidMessageClass(message_class
));
56 // Safely ignore repeated subscriptions to a given message class for the
57 // current filter being added.
58 if (!message_class_filters_
[message_class
].empty() &&
59 message_class_filters_
[message_class
].back() == filter
) {
62 message_class_filters_
[message_class
].push_back(filter
);
65 global_filters_
.push_back(filter
);
69 void MessageFilterRouter::RemoveFilter(MessageFilter
* filter
) {
70 if (RemoveFilterImpl(global_filters_
, filter
))
73 for (size_t i
= 0; i
< arraysize(message_class_filters_
); ++i
)
74 RemoveFilterImpl(message_class_filters_
[i
], filter
);
77 bool MessageFilterRouter::TryFilters(const Message
& message
) {
78 if (TryFiltersImpl(global_filters_
, message
))
81 const int message_class
= IPC_MESSAGE_CLASS(message
);
82 if (!ValidMessageClass(message_class
))
85 return TryFiltersImpl(message_class_filters_
[message_class
], message
);
88 void MessageFilterRouter::Clear() {
89 global_filters_
.clear();
90 for (size_t i
= 0; i
< arraysize(message_class_filters_
); ++i
)
91 message_class_filters_
[i
].clear();