Upload upstream chromium 73.0.3683.0
[platform/framework/web/chromium-efl.git] / ipc / message_filter_router.cc
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.
4
5 #include "ipc/message_filter_router.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include "base/stl_util.h"
11 #include "ipc/ipc_message_macros.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     DCHECK(!supported_message_classes.empty());
55     for (size_t i = 0; i < supported_message_classes.size(); ++i) {
56       const int message_class = supported_message_classes[i];
57       DCHECK(ValidMessageClass(message_class));
58       // Safely ignore repeated subscriptions to a given message class for the
59       // current filter being added.
60       if (!message_class_filters_[message_class].empty() &&
61           message_class_filters_[message_class].back() == filter) {
62         continue;
63       }
64       message_class_filters_[message_class].push_back(filter);
65     }
66   } else {
67     global_filters_.push_back(filter);
68   }
69 }
70
71 void MessageFilterRouter::RemoveFilter(MessageFilter* filter) {
72   if (RemoveFilterImpl(global_filters_, filter))
73     return;
74
75   for (size_t i = 0; i < base::size(message_class_filters_); ++i)
76     RemoveFilterImpl(message_class_filters_[i], filter);
77 }
78
79 bool MessageFilterRouter::TryFilters(const Message& message) {
80   if (TryFiltersImpl(global_filters_, message))
81     return true;
82
83   const int message_class = IPC_MESSAGE_CLASS(message);
84   if (!ValidMessageClass(message_class))
85     return false;
86
87   return TryFiltersImpl(message_class_filters_[message_class], message);
88 }
89
90 void MessageFilterRouter::Clear() {
91   global_filters_.clear();
92   for (size_t i = 0; i < base::size(message_class_filters_); ++i)
93     message_class_filters_[i].clear();
94 }
95
96 }  // namespace IPC