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 "ipc/ipc_message_macros.h" 8#include "ipc/ipc_message_utils.h" 9#include "ipc/message_filter.h" 10 11namespace IPC { 12 13namespace { 14 15bool 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)) { 19 return true; 20 } 21 } 22 return false; 23} 24 25bool 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()) 30 return false; 31 32 filters.erase(it, filters.end()); 33 return true; 34} 35 36bool ValidMessageClass(int message_class) { 37 return message_class >= 0 && message_class < LastIPCMsgStart; 38} 39 40} // namespace 41 42MessageFilterRouter::MessageFilterRouter() {} 43MessageFilterRouter::~MessageFilterRouter() {} 44 45void 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) { 58 continue; 59 } 60 message_class_filters_[message_class].push_back(filter); 61 } 62 } else { 63 global_filters_.push_back(filter); 64 } 65} 66 67void MessageFilterRouter::RemoveFilter(MessageFilter* filter) { 68 if (RemoveFilterImpl(global_filters_, filter)) 69 return; 70 71 for (size_t i = 0; i < arraysize(message_class_filters_); ++i) 72 RemoveFilterImpl(message_class_filters_[i], filter); 73} 74 75bool MessageFilterRouter::TryFilters(const Message& message) { 76 if (TryFiltersImpl(global_filters_, message)) 77 return true; 78 79 const int message_class = IPC_MESSAGE_CLASS(message); 80 if (!ValidMessageClass(message_class)) 81 return false; 82 83 return TryFiltersImpl(message_class_filters_[message_class], message); 84} 85 86void MessageFilterRouter::Clear() { 87 global_filters_.clear(); 88 for (size_t i = 0; i < arraysize(message_class_filters_); ++i) 89 message_class_filters_[i].clear(); 90} 91 92} // namespace IPC 93