15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/ref_counted.h"
958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/content_export.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_proxy.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_WIN)
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/synchronization/lock.h"
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TaskRunner;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace IPC {
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass MessageFilter;
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)struct BrowserMessageFilterTraits;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base class for message filters in the browser process.  You can receive and
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// send messages on any thread.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CONTENT_EXPORT BrowserMessageFilter
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : public base::RefCountedThreadSafe<
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          BrowserMessageFilter, BrowserMessageFilterTraits>,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public IPC::Sender {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit BrowserMessageFilter(uint32 message_class_to_filter);
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BrowserMessageFilter(const uint32* message_classes_to_filter,
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       size_t num_message_classes_to_filter);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // These match the corresponding IPC::MessageFilter methods and are always
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // called on the IO thread.
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void OnFilterAdded(IPC::Sender* sender) {}
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnFilterRemoved() {}
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnChannelClosing() {}
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnChannelConnected(int32 peer_pid) {}
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Called when the message filter is about to be deleted.  This gives
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // derived classes the option of controlling which thread they're deleted
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // on etc.
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnDestruct() const;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IPC::Sender implementation.  Can be called on any thread.  Can't send sync
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // messages (since we don't want to block the browser on any other process).
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Send(IPC::Message* message) OVERRIDE;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If you want the given message to be dispatched to your OnMessageReceived on
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a different thread, there are two options, either
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OverrideThreadForMessage or OverrideTaskRunnerForMessage.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If neither is overriden, the message will be dispatched on the IO thread.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If you want the message to be dispatched on a particular well-known
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // browser thread, change |thread| to the id of the target thread
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OverrideThreadForMessage(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const IPC::Message& message,
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      BrowserThread::ID* thread) {}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If you want the message to be dispatched via the SequencedWorkerPool,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return a non-null task runner which will target tasks accordingly.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: To target the UI thread, please use OverrideThreadForMessage
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since that has extra checks to avoid deadlocks.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::TaskRunner* OverrideTaskRunnerForMessage(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const IPC::Message& message);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override this to receive messages.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Your function will normally be called on the IO thread.  However, if your
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OverrideXForMessage modifies the thread used to dispatch the message,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // your function will be called on the requested thread.
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual bool OnMessageReceived(const IPC::Message& message) = 0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Can be called on any thread, after OnChannelConnected is called.
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::ProcessHandle PeerHandle();
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Can be called on any thread, after OnChannelConnected is called.
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::ProcessId peer_pid() const { return peer_pid_; }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void set_peer_pid_for_testing(base::ProcessId peer_pid) {
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    peer_pid_ = peer_pid;
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks that the given message can be dispatched on the UI thread, depending
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on the platform.  If not, returns false and an error ot the sender.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool CheckCanDispatchOnUI(const IPC::Message& message,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   IPC::Sender* sender);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call this if a message couldn't be deserialized.  This kills the renderer.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Can be called on any thread.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BadMessageReceived();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::vector<uint32>& message_classes_to_filter() const {
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return message_classes_to_filter_;
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~BrowserMessageFilter();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  friend class base::RefCountedThreadSafe<BrowserMessageFilter,
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                          BrowserMessageFilterTraits>;
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class Internal;
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  friend class BrowserChildProcessHostImpl;
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  friend class BrowserPpapiHost;
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  friend class RenderProcessHostImpl;
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This is private because the only classes that need access to it are made
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // friends above. This is only guaranteed to be valid on creation, after that
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // this class could outlive the filter.
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  IPC::MessageFilter* GetFilter();
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // This implements IPC::MessageFilter so that we can hide that from child
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // classes. Internal keeps a reference to this class, which is why there's a
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // weak pointer back. This class could outlive Internal based on what the
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // child class does in its OnDestruct method.
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Internal* internal_;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  IPC::Sender* sender_;
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::ProcessId peer_pid_;
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<uint32> message_classes_to_filter_;
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_WIN)
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::Lock peer_handle_lock_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessHandle peer_handle_;
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)struct BrowserMessageFilterTraits {
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static void Destruct(const BrowserMessageFilter* filter) {
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    filter->OnDestruct();
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_
146