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