153f17a9db278d33517d9888dd77848f554522a38JP Abgrall// Copyright 2014 The Chromium Authors. All rights reserved.
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project// Use of this source code is governed by a BSD-style license that can be
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project// found in the LICENSE file.
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ipc/message_filter_router.h"
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ipc/ipc_message_macros.h"
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ipc/ipc_message_utils.h"
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ipc/message_filter.h"
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectnamespace IPC {
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectnamespace {
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectbool TryFiltersImpl(MessageFilterRouter::MessageFilters& filters,
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    const IPC::Message& message) {
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  for (size_t i = 0; i < filters.size(); ++i) {
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if (filters[i]->OnMessageReceived(message)) {
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      return true;
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  }
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  return false;
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectbool RemoveFilterImpl(MessageFilterRouter::MessageFilters& filters,
262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                      MessageFilter* filter) {
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  MessageFilterRouter::MessageFilters::iterator it =
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      std::remove(filters.begin(), filters.end(), filter);
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  if (it == filters.end())
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return false;
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  filters.erase(it, filters.end());
332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  return true;
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectbool ValidMessageClass(int message_class) {
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  return message_class >= 0 && message_class < LastIPCMsgStart;
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}  // namespace
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source ProjectMessageFilterRouter::MessageFilterRouter() {}
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source ProjectMessageFilterRouter::~MessageFilterRouter() {}
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid MessageFilterRouter::AddFilter(MessageFilter* filter) {
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  // Determine if the filter should be applied to all messages, or only
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  // messages of a certain class.
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  std::vector<uint32> supported_message_classes;
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  if (filter->GetSupportedMessageClasses(&supported_message_classes)) {
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    DCHECK(!supported_message_classes.empty());
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    for (size_t i = 0; i < supported_message_classes.size(); ++i) {
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      const int message_class = supported_message_classes[i];
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      DCHECK(ValidMessageClass(message_class));
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      // Safely ignore repeated subscriptions to a given message class for the
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      // current filter being added.
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      if (!message_class_filters_[message_class].empty() &&
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project          message_class_filters_[message_class].back() == filter) {
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        continue;
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      }
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project      message_class_filters_[message_class].push_back(filter);
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  } else {
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    global_filters_.push_back(filter);
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  }
6553f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid MessageFilterRouter::RemoveFilter(MessageFilter* filter) {
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  if (RemoveFilterImpl(global_filters_, filter))
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return;
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  for (size_t i = 0; i < arraysize(message_class_filters_); ++i)
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    RemoveFilterImpl(message_class_filters_[i], filter);
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectbool MessageFilterRouter::TryFilters(const Message& message) {
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  if (TryFiltersImpl(global_filters_, message))
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return true;
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  const int message_class = IPC_MESSAGE_CLASS(message);
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  if (!ValidMessageClass(message_class))
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return false;
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  return TryFiltersImpl(message_class_filters_[message_class], message);
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid MessageFilterRouter::Clear() {
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  global_filters_.clear();
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project  for (size_t i = 0; i < arraysize(message_class_filters_); ++i)
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    message_class_filters_[i].clear();
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}  // namespace IPC
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project