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"
7 #include "ipc/ipc_message_macros.h"
8 #include "ipc/ipc_message_utils.h"
9 #include "ipc/message_filter.h"
15 bool TryFiltersImpl(MessageFilterRouter::MessageFilters
& filters
,
16 const IPC::Message
& message
) {
17 for (size_t i
= 0; i
< filters
.size(); ++i
) {
18 if (filters
[i
]->OnMessageReceived(message
)) {
25 bool RemoveFilterImpl(MessageFilterRouter::MessageFilters
& filters
,
26 MessageFilter
* filter
) {
27 MessageFilterRouter::MessageFilters::iterator it
=
28 std::remove(filters
.begin(), filters
.end(), filter
);
29 if (it
== filters
.end())
32 filters
.erase(it
, filters
.end());
36 bool ValidMessageClass(int message_class
) {
37 return message_class
>= 0 && message_class
< LastIPCMsgStart
;
42 MessageFilterRouter::MessageFilterRouter() {}
43 MessageFilterRouter::~MessageFilterRouter() {}
45 void MessageFilterRouter::AddFilter(MessageFilter
* filter
) {
46 // Determine if the filter should be applied to all messages, or only
47 // messages of a certain class.
48 std::vector
<uint32
> supported_message_classes
;
49 if (filter
->GetSupportedMessageClasses(&supported_message_classes
)) {
50 DCHECK(!supported_message_classes
.empty());
51 for (size_t i
= 0; i
< supported_message_classes
.size(); ++i
) {
52 const int message_class
= supported_message_classes
[i
];
53 DCHECK(ValidMessageClass(message_class
));
54 // Safely ignore repeated subscriptions to a given message class for the
55 // current filter being added.
56 if (!message_class_filters_
[message_class
].empty() &&
57 message_class_filters_
[message_class
].back() == filter
) {
60 message_class_filters_
[message_class
].push_back(filter
);
63 global_filters_
.push_back(filter
);
67 void MessageFilterRouter::RemoveFilter(MessageFilter
* filter
) {
68 if (RemoveFilterImpl(global_filters_
, filter
))
71 for (size_t i
= 0; i
< arraysize(message_class_filters_
); ++i
)
72 RemoveFilterImpl(message_class_filters_
[i
], filter
);
75 bool MessageFilterRouter::TryFilters(const Message
& message
) {
76 if (TryFiltersImpl(global_filters_
, message
))
79 const int message_class
= IPC_MESSAGE_CLASS(message
);
80 if (!ValidMessageClass(message_class
))
83 return TryFiltersImpl(message_class_filters_
[message_class
], message
);
86 void MessageFilterRouter::Clear() {
87 global_filters_
.clear();
88 for (size_t i
= 0; i
< arraysize(message_class_filters_
); ++i
)
89 message_class_filters_
[i
].clear();