diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-25 00:07:30 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-25 00:07:30 +0000 |
commit | 7412204291319c7099206d8e4964b981737e2170 (patch) | |
tree | e96de76e7864b31e664b5a902b2e3f4959d86843 /ipc | |
parent | a8f2a3efb04eea886d198c2dcc87bed6cf472dd6 (diff) | |
download | chromium_src-7412204291319c7099206d8e4964b981737e2170.zip chromium_src-7412204291319c7099206d8e4964b981737e2170.tar.gz chromium_src-7412204291319c7099206d8e4964b981737e2170.tar.bz2 |
Move IPC::MessageFilter and router to a separate file
There are no changes in implementation in this CL. This is in preparation
for making IPC::Channel support filters on the Channel's thread.
BUG=364241
TBR=cpu@chromium.org,nduca@chromium.org
cpu: OWNERS for win8
nduca: OWNERS for components/tracing
Review URL: https://codereview.chromium.org/245443005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266057 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/BUILD.gn | 4 | ||||
-rw-r--r-- | ipc/ipc.gypi | 4 | ||||
-rw-r--r-- | ipc/ipc_channel_proxy.cc | 123 | ||||
-rw-r--r-- | ipc/ipc_channel_proxy.h | 53 | ||||
-rw-r--r-- | ipc/ipc_channel_proxy_unittest.cc | 3 | ||||
-rw-r--r-- | ipc/ipc_forwarding_message_filter.cc | 1 | ||||
-rw-r--r-- | ipc/ipc_forwarding_message_filter.h | 7 | ||||
-rw-r--r-- | ipc/ipc_sync_message_filter.cc | 1 | ||||
-rw-r--r-- | ipc/ipc_sync_message_filter.h | 8 | ||||
-rw-r--r-- | ipc/message_filter.cc | 35 | ||||
-rw-r--r-- | ipc/message_filter.h | 67 | ||||
-rw-r--r-- | ipc/message_filter_router.cc | 92 | ||||
-rw-r--r-- | ipc/message_filter_router.h | 42 |
13 files changed, 262 insertions, 178 deletions
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn index 0c91d2f..cccbb58 100644 --- a/ipc/BUILD.gn +++ b/ipc/BUILD.gn @@ -46,6 +46,10 @@ component("ipc") { "ipc_sync_message.h", "ipc_sync_message_filter.cc", "ipc_sync_message_filter.h", + "message_filter.cc", + "message_filter.h", + "message_filter_router.cc", + "message_filter_router.h", "param_traits_log_macros.h", "param_traits_macros.h", "param_traits_read_macros.h", diff --git a/ipc/ipc.gypi b/ipc/ipc.gypi index ba80e42..fd23fb0 100644 --- a/ipc/ipc.gypi +++ b/ipc/ipc.gypi @@ -53,6 +53,10 @@ 'ipc_sync_message.h', 'ipc_sync_message_filter.cc', 'ipc_sync_message_filter.h', + 'message_filter.cc', + 'message_filter.h', + 'message_filter_router.cc', + 'message_filter_router.h', 'param_traits_log_macros.h', 'param_traits_macros.h', 'param_traits_read_macros.h', diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc index d906dbf..7c96c83 100644 --- a/ipc/ipc_channel_proxy.cc +++ b/ipc/ipc_channel_proxy.cc @@ -2,140 +2,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ipc/ipc_channel_proxy.h" + #include "base/bind.h" #include "base/compiler_specific.h" -#include "base/debug/trace_event.h" #include "base/location.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" -#include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_logging.h" #include "ipc/ipc_message_macros.h" -#include "ipc/ipc_message_start.h" -#include "ipc/ipc_message_utils.h" +#include "ipc/message_filter.h" +#include "ipc/message_filter_router.h" namespace IPC { //------------------------------------------------------------------------------ -class ChannelProxy::Context::MessageFilterRouter { - public: - typedef std::vector<MessageFilter*> MessageFilters; - - MessageFilterRouter() {} - ~MessageFilterRouter() {} - - void AddFilter(MessageFilter* filter) { - // Determine if the filter should be applied to all messages, or only - // messages of a certain class. - std::vector<uint32> supported_message_classes; - if (filter->GetSupportedMessageClasses(&supported_message_classes)) { - DCHECK(!supported_message_classes.empty()); - for (size_t i = 0; i < supported_message_classes.size(); ++i) { - const int message_class = supported_message_classes[i]; - DCHECK(ValidMessageClass(message_class)); - // Safely ignore repeated subscriptions to a given message class for the - // current filter being added. - if (!message_class_filters_[message_class].empty() && - message_class_filters_[message_class].back() == filter) { - continue; - } - message_class_filters_[message_class].push_back(filter); - } - } else { - global_filters_.push_back(filter); - } - } - - void RemoveFilter(MessageFilter* filter) { - if (RemoveFilter(global_filters_, filter)) - return; - - for (size_t i = 0; i < arraysize(message_class_filters_); ++i) - RemoveFilter(message_class_filters_[i], filter); - } - - bool TryFilters(const Message& message) { - if (TryFilters(global_filters_, message)) - return true; - - const int message_class = IPC_MESSAGE_CLASS(message); - if (!ValidMessageClass(message_class)) - return false; - - return TryFilters(message_class_filters_[message_class], message); - } - - void Clear() { - global_filters_.clear(); - for (size_t i = 0; i < arraysize(message_class_filters_); ++i) - message_class_filters_[i].clear(); - } - - private: - static bool TryFilters(MessageFilters& filters, const IPC::Message& message) { - for (size_t i = 0; i < filters.size(); ++i) { - if (filters[i]->OnMessageReceived(message)) { - return true; - } - } - return false; - } - - static bool RemoveFilter(MessageFilters& filters, MessageFilter* filter) { - MessageFilters::iterator it = - std::remove(filters.begin(), filters.end(), filter); - if (it == filters.end()) - return false; - - filters.erase(it, filters.end()); - return true; - } - - static bool ValidMessageClass(int message_class) { - return message_class >= 0 && message_class < LastIPCMsgStart; - } - - // List of global and selective filters; a given filter will exist in either - // |message_global_filters_| OR |message_class_filters_|, but not both. - // Note that |message_global_filters_| will be given first offering of any - // given message. It's the filter implementer and installer's - // responsibility to ensure that a filter is either global or selective to - // ensure proper message filtering order. - MessageFilters global_filters_; - MessageFilters message_class_filters_[LastIPCMsgStart]; -}; - -//------------------------------------------------------------------------------ - -ChannelProxy::MessageFilter::MessageFilter() {} - -void ChannelProxy::MessageFilter::OnFilterAdded(Channel* channel) {} - -void ChannelProxy::MessageFilter::OnFilterRemoved() {} - -void ChannelProxy::MessageFilter::OnChannelConnected(int32 peer_pid) {} - -void ChannelProxy::MessageFilter::OnChannelError() {} - -void ChannelProxy::MessageFilter::OnChannelClosing() {} - -bool ChannelProxy::MessageFilter::OnMessageReceived(const Message& message) { - return false; -} - -bool ChannelProxy::MessageFilter::GetSupportedMessageClasses( - std::vector<uint32>* /*supported_message_classes*/) const { - return false; -} - -ChannelProxy::MessageFilter::~MessageFilter() {} - -//------------------------------------------------------------------------------ - ChannelProxy::Context::Context(Listener* listener, base::SingleThreadTaskRunner* ipc_task_runner) : listener_task_runner_(base::ThreadTaskRunnerHandle::Get()), diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h index b0247c4..375a42b 100644 --- a/ipc/ipc_channel_proxy.h +++ b/ipc/ipc_channel_proxy.h @@ -22,6 +22,8 @@ class SingleThreadTaskRunner; namespace IPC { +class MessageFilter; +class MessageFilterRouter; class SendCallbackHelper; //----------------------------------------------------------------------------- @@ -54,54 +56,6 @@ class SendCallbackHelper; // class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { public: - - // A class that receives messages on the thread where the IPC channel is - // running. It can choose to prevent the default action for an IPC message. - class IPC_EXPORT MessageFilter - : public base::RefCountedThreadSafe<MessageFilter> { - public: - MessageFilter(); - - // Called on the background thread to provide the filter with access to the - // channel. Called when the IPC channel is initialized or when AddFilter - // is called if the channel is already initialized. - virtual void OnFilterAdded(Channel* channel); - - // Called on the background thread when the filter has been removed from - // the ChannelProxy and when the Channel is closing. After a filter is - // removed, it will not be called again. - virtual void OnFilterRemoved(); - - // Called to inform the filter that the IPC channel is connected and we - // have received the internal Hello message from the peer. - virtual void OnChannelConnected(int32 peer_pid); - - // Called when there is an error on the channel, typically that the channel - // has been closed. - virtual void OnChannelError(); - - // Called to inform the filter that the IPC channel will be destroyed. - // OnFilterRemoved is called immediately after this. - virtual void OnChannelClosing(); - - // Return true to indicate that the message was handled, or false to let - // the message be handled in the default way. - virtual bool OnMessageReceived(const Message& message); - - // Called to query the Message classes supported by the filter. Return - // false to indicate that all message types should reach the filter, or true - // if the resulting contents of |supported_message_classes| may be used to - // selectively offer messages of a particular class to the filter. - virtual bool GetSupportedMessageClasses( - std::vector<uint32>* supported_message_classes) const; - - protected: - virtual ~MessageFilter(); - - private: - friend class base::RefCountedThreadSafe<MessageFilter>; - }; - // Initializes a channel proxy. The channel_handle and mode parameters are // passed directly to the underlying IPC::Channel. The listener is called on // the thread that creates the ChannelProxy. The filter's OnMessageReceived @@ -128,7 +82,7 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { // background thread processes the command to close the channel. It is ok to // call this method multiple times. Redundant calls are ignored. // - // WARNING: The MessageFilter object held by the ChannelProxy is also + // WARNING: MessageFilter objects held by the ChannelProxy is also // released asynchronously, and it may in fact have its final reference // released on the background thread. The caller should be careful to deal // with / allow for this possibility. @@ -243,7 +197,6 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { // Routes a given message to a proper subset of |filters_|, depending // on which message classes a filter might support. - class MessageFilterRouter; scoped_ptr<MessageFilterRouter> message_filter_router_; // Holds filters between the AddFilter call on the listerner thread and the diff --git a/ipc/ipc_channel_proxy_unittest.cc b/ipc/ipc_channel_proxy_unittest.cc index 282b346..c5e078a 100644 --- a/ipc/ipc_channel_proxy_unittest.cc +++ b/ipc/ipc_channel_proxy_unittest.cc @@ -10,6 +10,7 @@ #include "ipc/ipc_message.h" #include "ipc/ipc_message_macros.h" #include "ipc/ipc_test_base.h" +#include "ipc/message_filter.h" namespace { @@ -81,7 +82,7 @@ class ChannelReflectorListener : public IPC::Listener { IPC::Channel* channel_; }; -class MessageCountFilter : public IPC::ChannelProxy::MessageFilter { +class MessageCountFilter : public IPC::MessageFilter { public: enum FilterEvent { NONE, diff --git a/ipc/ipc_forwarding_message_filter.cc b/ipc/ipc_forwarding_message_filter.cc index 342aeb7..9857bdf 100644 --- a/ipc/ipc_forwarding_message_filter.cc +++ b/ipc/ipc_forwarding_message_filter.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/location.h" +#include "ipc/ipc_message.h" namespace IPC { diff --git a/ipc/ipc_forwarding_message_filter.h b/ipc/ipc_forwarding_message_filter.h index 919a44d..597fc60 100644 --- a/ipc/ipc_forwarding_message_filter.h +++ b/ipc/ipc_forwarding_message_filter.h @@ -12,7 +12,7 @@ #include "base/callback_forward.h" #include "base/synchronization/lock.h" #include "base/task_runner.h" -#include "ipc/ipc_channel_proxy.h" +#include "ipc/message_filter.h" namespace IPC { @@ -23,7 +23,7 @@ namespace IPC { // // The user of this class implements ForwardingMessageFilter::Client, // which will receive the intercepted messages, on the specified target thread. -class IPC_EXPORT ForwardingMessageFilter : public ChannelProxy::MessageFilter { +class IPC_EXPORT ForwardingMessageFilter : public MessageFilter { public: // The handler is invoked on the thread associated with @@ -44,11 +44,10 @@ class IPC_EXPORT ForwardingMessageFilter : public ChannelProxy::MessageFilter { void AddRoute(int routing_id, const Handler& handler); void RemoveRoute(int routing_id); - // ChannelProxy::MessageFilter methods: + // MessageFilter methods: virtual bool OnMessageReceived(const Message& message) OVERRIDE; private: - friend class ChannelProxy::MessageFilter; virtual ~ForwardingMessageFilter(); std::set<int> message_ids_to_filter_; diff --git a/ipc/ipc_sync_message_filter.cc b/ipc/ipc_sync_message_filter.cc index a534c44..3833d2b 100644 --- a/ipc/ipc_sync_message_filter.cc +++ b/ipc/ipc_sync_message_filter.cc @@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/message_loop/message_loop_proxy.h" #include "base/synchronization/waitable_event.h" +#include "ipc/ipc_channel.h" #include "ipc/ipc_sync_message.h" using base::MessageLoopProxy; diff --git a/ipc/ipc_sync_message_filter.h b/ipc/ipc_sync_message_filter.h index dbc2834..4e08a1a 100644 --- a/ipc/ipc_sync_message_filter.h +++ b/ipc/ipc_sync_message_filter.h @@ -10,8 +10,9 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -#include "ipc/ipc_channel_proxy.h" +#include "ipc/ipc_sender.h" #include "ipc/ipc_sync_message.h" +#include "ipc/message_filter.h" namespace base { class MessageLoopProxy; @@ -25,15 +26,14 @@ namespace IPC { // support fancy features that SyncChannel does, such as handling recursion or // receiving messages while waiting for a response. Note that this object can // be used to send simultaneous synchronous messages from different threads. -class IPC_EXPORT SyncMessageFilter : public ChannelProxy::MessageFilter, - public Sender { +class IPC_EXPORT SyncMessageFilter : public MessageFilter, public Sender { public: explicit SyncMessageFilter(base::WaitableEvent* shutdown_event); // MessageSender implementation. virtual bool Send(Message* message) OVERRIDE; - // ChannelProxy::MessageFilter implementation. + // MessageFilter implementation. virtual void OnFilterAdded(Channel* channel) OVERRIDE; virtual void OnChannelError() OVERRIDE; virtual void OnChannelClosing() OVERRIDE; diff --git a/ipc/message_filter.cc b/ipc/message_filter.cc new file mode 100644 index 0000000..7218126 --- /dev/null +++ b/ipc/message_filter.cc @@ -0,0 +1,35 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ipc/message_filter.h" + +#include "base/memory/ref_counted.h" +#include "ipc/ipc_channel.h" + +namespace IPC { + +MessageFilter::MessageFilter() {} + +void MessageFilter::OnFilterAdded(Channel* channel) {} + +void MessageFilter::OnFilterRemoved() {} + +void MessageFilter::OnChannelConnected(int32 peer_pid) {} + +void MessageFilter::OnChannelError() {} + +void MessageFilter::OnChannelClosing() {} + +bool MessageFilter::OnMessageReceived(const Message& message) { + return false; +} + +bool MessageFilter::GetSupportedMessageClasses( + std::vector<uint32>* /*supported_message_classes*/) const { + return false; +} + +MessageFilter::~MessageFilter() {} + +} // namespace IPC diff --git a/ipc/message_filter.h b/ipc/message_filter.h new file mode 100644 index 0000000..0371585 --- /dev/null +++ b/ipc/message_filter.h @@ -0,0 +1,67 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IPC_MESSAGE_FILTER_H_ +#define IPC_MESSAGE_FILTER_H_ + +#include <vector> + +#include "base/memory/ref_counted.h" +#include "ipc/ipc_export.h" + +namespace IPC { + +class Channel; +class Message; + +// A class that receives messages on the thread where the IPC channel is +// running. It can choose to prevent the default action for an IPC message. +class IPC_EXPORT MessageFilter + : public base::RefCountedThreadSafe<MessageFilter> { + public: + MessageFilter(); + + // Called on the background thread to provide the filter with access to the + // channel. Called when the IPC channel is initialized or when AddFilter + // is called if the channel is already initialized. + virtual void OnFilterAdded(Channel* channel); + + // Called on the background thread when the filter has been removed from + // the ChannelProxy and when the Channel is closing. After a filter is + // removed, it will not be called again. + virtual void OnFilterRemoved(); + + // Called to inform the filter that the IPC channel is connected and we + // have received the internal Hello message from the peer. + virtual void OnChannelConnected(int32 peer_pid); + + // Called when there is an error on the channel, typically that the channel + // has been closed. + virtual void OnChannelError(); + + // Called to inform the filter that the IPC channel will be destroyed. + // OnFilterRemoved is called immediately after this. + virtual void OnChannelClosing(); + + // Return true to indicate that the message was handled, or false to let + // the message be handled in the default way. + virtual bool OnMessageReceived(const Message& message); + + // Called to query the Message classes supported by the filter. Return + // false to indicate that all message types should reach the filter, or true + // if the resulting contents of |supported_message_classes| may be used to + // selectively offer messages of a particular class to the filter. + virtual bool GetSupportedMessageClasses( + std::vector<uint32>* supported_message_classes) const; + + protected: + virtual ~MessageFilter(); + + private: + friend class base::RefCountedThreadSafe<MessageFilter>; +}; + +} // namespace IPC + +#endif // IPC_MESSAGE_FILTER_H_ diff --git a/ipc/message_filter_router.cc b/ipc/message_filter_router.cc new file mode 100644 index 0000000..81e4028 --- /dev/null +++ b/ipc/message_filter_router.cc @@ -0,0 +1,92 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ipc/message_filter_router.h" + +#include "ipc/ipc_message_macros.h" +#include "ipc/ipc_message_utils.h" +#include "ipc/message_filter.h" + +namespace IPC { + +namespace { + +bool TryFiltersImpl(MessageFilterRouter::MessageFilters& filters, + const IPC::Message& message) { + for (size_t i = 0; i < filters.size(); ++i) { + if (filters[i]->OnMessageReceived(message)) { + return true; + } + } + return false; +} + +bool RemoveFilterImpl(MessageFilterRouter::MessageFilters& filters, + MessageFilter* filter) { + MessageFilterRouter::MessageFilters::iterator it = + std::remove(filters.begin(), filters.end(), filter); + if (it == filters.end()) + return false; + + filters.erase(it, filters.end()); + return true; +} + +bool ValidMessageClass(int message_class) { + return message_class >= 0 && message_class < LastIPCMsgStart; +} + +} // namespace + +MessageFilterRouter::MessageFilterRouter() {} +MessageFilterRouter::~MessageFilterRouter() {} + +void MessageFilterRouter::AddFilter(MessageFilter* filter) { + // Determine if the filter should be applied to all messages, or only + // messages of a certain class. + std::vector<uint32> supported_message_classes; + if (filter->GetSupportedMessageClasses(&supported_message_classes)) { + DCHECK(!supported_message_classes.empty()); + for (size_t i = 0; i < supported_message_classes.size(); ++i) { + const int message_class = supported_message_classes[i]; + DCHECK(ValidMessageClass(message_class)); + // Safely ignore repeated subscriptions to a given message class for the + // current filter being added. + if (!message_class_filters_[message_class].empty() && + message_class_filters_[message_class].back() == filter) { + continue; + } + message_class_filters_[message_class].push_back(filter); + } + } else { + global_filters_.push_back(filter); + } +} + +void MessageFilterRouter::RemoveFilter(MessageFilter* filter) { + if (RemoveFilterImpl(global_filters_, filter)) + return; + + for (size_t i = 0; i < arraysize(message_class_filters_); ++i) + RemoveFilterImpl(message_class_filters_[i], filter); +} + +bool MessageFilterRouter::TryFilters(const Message& message) { + if (TryFiltersImpl(global_filters_, message)) + return true; + + const int message_class = IPC_MESSAGE_CLASS(message); + if (!ValidMessageClass(message_class)) + return false; + + return TryFiltersImpl(message_class_filters_[message_class], message); +} + +void MessageFilterRouter::Clear() { + global_filters_.clear(); + for (size_t i = 0; i < arraysize(message_class_filters_); ++i) + message_class_filters_[i].clear(); +} + +} // namespace IPC diff --git a/ipc/message_filter_router.h b/ipc/message_filter_router.h new file mode 100644 index 0000000..183b8eb --- /dev/null +++ b/ipc/message_filter_router.h @@ -0,0 +1,42 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IPC_MESSAGE_FILTER_ROUTER_H_ +#define IPC_MESSAGE_FILTER_ROUTER_H_ + +#include <vector> + +#include "ipc/ipc_message_start.h" + +namespace IPC { + +class Message; +class MessageFilter; + +class MessageFilterRouter { + public: + typedef std::vector<MessageFilter*> MessageFilters; + + MessageFilterRouter(); + ~MessageFilterRouter(); + + void AddFilter(MessageFilter* filter); + void RemoveFilter(MessageFilter* filter); + bool TryFilters(const Message& message); + void Clear(); + + private: + // List of global and selective filters; a given filter will exist in either + // |message_global_filters_| OR |message_class_filters_|, but not both. + // Note that |message_global_filters_| will be given first offering of any + // given message. It's the filter implementer and installer's + // responsibility to ensure that a filter is either global or selective to + // ensure proper message filtering order. + MessageFilters global_filters_; + MessageFilters message_class_filters_[LastIPCMsgStart]; +}; + +} // namespace IPC + +#endif // IPC_MESSAGE_FILTER_ROUTER_H_ |