Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / ipc / message_filter_router.cc
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.
4
5 #include "ipc/message_filter_router.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
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"
14
15 namespace IPC {
16
17 namespace {
18
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)) {
23       return true;
24     }
25   }
26   return false;
27 }
28
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())
34     return false;
35
36   filters.erase(it, filters.end());
37   return true;
38 }
39
40 bool ValidMessageClass(int message_class) {
41   return message_class >= 0 && message_class < LastIPCMsgStart;
42 }
43
44 }  // namespace
45
46 MessageFilterRouter::MessageFilterRouter() = default;
47 MessageFilterRouter::~MessageFilterRouter() = default;
48
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) {
61         continue;
62       }
63       message_class_filters_[message_class].push_back(filter);
64     }
65   } else {
66     global_filters_.push_back(filter);
67   }
68 }
69
70 void MessageFilterRouter::RemoveFilter(MessageFilter* filter) {
71   if (RemoveFilterImpl(global_filters_, filter))
72     return;
73
74   for (size_t i = 0; i < std::size(message_class_filters_); ++i)
75     RemoveFilterImpl(message_class_filters_[i], filter);
76 }
77
78 bool MessageFilterRouter::TryFilters(const Message& message) {
79   if (TryFiltersImpl(global_filters_, message))
80     return true;
81
82   const int message_class = IPC_MESSAGE_CLASS(message);
83   if (!ValidMessageClass(message_class))
84     return false;
85
86   return TryFiltersImpl(message_class_filters_[message_class], message);
87 }
88
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();
93 }
94
95 }  // namespace IPC