1// Copyright (c) 2012 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#ifndef CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_
6#define CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_
7
8#include "base/memory/ref_counted.h"
9#include "base/process/process.h"
10#include "content/common/content_export.h"
11#include "content/public/browser/browser_thread.h"
12#include "ipc/ipc_channel_proxy.h"
13
14#if defined(OS_WIN)
15#include "base/synchronization/lock.h"
16#endif
17
18namespace base {
19class TaskRunner;
20}
21
22namespace IPC {
23class MessageFilter;
24}
25
26namespace content {
27struct BrowserMessageFilterTraits;
28
29// Base class for message filters in the browser process.  You can receive and
30// send messages on any thread.
31class CONTENT_EXPORT BrowserMessageFilter
32    : public base::RefCountedThreadSafe<
33          BrowserMessageFilter, BrowserMessageFilterTraits>,
34      public IPC::Sender {
35 public:
36  explicit BrowserMessageFilter(uint32 message_class_to_filter);
37  BrowserMessageFilter(const uint32* message_classes_to_filter,
38                       size_t num_message_classes_to_filter);
39
40  // These match the corresponding IPC::MessageFilter methods and are always
41  // called on the IO thread.
42  virtual void OnFilterAdded(IPC::Sender* sender) {}
43  virtual void OnFilterRemoved() {}
44  virtual void OnChannelClosing() {}
45  virtual void OnChannelConnected(int32 peer_pid) {}
46
47  // Called when the message filter is about to be deleted.  This gives
48  // derived classes the option of controlling which thread they're deleted
49  // on etc.
50  virtual void OnDestruct() const;
51
52  // IPC::Sender implementation.  Can be called on any thread.  Can't send sync
53  // messages (since we don't want to block the browser on any other process).
54  virtual bool Send(IPC::Message* message) OVERRIDE;
55
56  // If you want the given message to be dispatched to your OnMessageReceived on
57  // a different thread, there are two options, either
58  // OverrideThreadForMessage or OverrideTaskRunnerForMessage.
59  // If neither is overriden, the message will be dispatched on the IO thread.
60
61  // If you want the message to be dispatched on a particular well-known
62  // browser thread, change |thread| to the id of the target thread
63  virtual void OverrideThreadForMessage(
64      const IPC::Message& message,
65      BrowserThread::ID* thread) {}
66
67  // If you want the message to be dispatched via the SequencedWorkerPool,
68  // return a non-null task runner which will target tasks accordingly.
69  // Note: To target the UI thread, please use OverrideThreadForMessage
70  // since that has extra checks to avoid deadlocks.
71  virtual base::TaskRunner* OverrideTaskRunnerForMessage(
72      const IPC::Message& message);
73
74  // Override this to receive messages.
75  // Your function will normally be called on the IO thread.  However, if your
76  // OverrideXForMessage modifies the thread used to dispatch the message,
77  // your function will be called on the requested thread.
78  virtual bool OnMessageReceived(const IPC::Message& message) = 0;
79
80  // Can be called on any thread, after OnChannelConnected is called.
81  base::ProcessHandle PeerHandle();
82
83  // Can be called on any thread, after OnChannelConnected is called.
84  base::ProcessId peer_pid() const { return peer_pid_; }
85
86  void set_peer_pid_for_testing(base::ProcessId peer_pid) {
87    peer_pid_ = peer_pid;
88  }
89
90  // Checks that the given message can be dispatched on the UI thread, depending
91  // on the platform.  If not, returns false and an error ot the sender.
92  static bool CheckCanDispatchOnUI(const IPC::Message& message,
93                                   IPC::Sender* sender);
94
95  // Call this if a message couldn't be deserialized.  This kills the renderer.
96  // Can be called on any thread.
97  virtual void BadMessageReceived();
98
99  const std::vector<uint32>& message_classes_to_filter() const {
100    return message_classes_to_filter_;
101  }
102
103 protected:
104  virtual ~BrowserMessageFilter();
105
106 private:
107  friend class base::RefCountedThreadSafe<BrowserMessageFilter,
108                                          BrowserMessageFilterTraits>;
109
110  class Internal;
111  friend class BrowserChildProcessHostImpl;
112  friend class BrowserPpapiHost;
113  friend class RenderProcessHostImpl;
114
115  // This is private because the only classes that need access to it are made
116  // friends above. This is only guaranteed to be valid on creation, after that
117  // this class could outlive the filter.
118  IPC::MessageFilter* GetFilter();
119
120  // This implements IPC::MessageFilter so that we can hide that from child
121  // classes. Internal keeps a reference to this class, which is why there's a
122  // weak pointer back. This class could outlive Internal based on what the
123  // child class does in its OnDestruct method.
124  Internal* internal_;
125
126  IPC::Sender* sender_;
127  base::ProcessId peer_pid_;
128
129  std::vector<uint32> message_classes_to_filter_;
130
131#if defined(OS_WIN)
132  base::Lock peer_handle_lock_;
133  base::ProcessHandle peer_handle_;
134#endif
135};
136
137struct BrowserMessageFilterTraits {
138  static void Destruct(const BrowserMessageFilter* filter) {
139    filter->OnDestruct();
140  }
141};
142
143}  // namespace content
144
145#endif  // CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_
146