summaryrefslogtreecommitdiffstats
path: root/content/public/browser/browser_message_filter.h
blob: ad1f0693790b2abb0177ffe92433b49b9861fada (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright (c) 2012 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 CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_
#define CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_

#include "base/memory/ref_counted.h"
#include "base/process/process.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_thread.h"
#include "ipc/ipc_channel_proxy.h"

#if defined(OS_WIN)
#include "base/synchronization/lock.h"
#endif

namespace base {
class TaskRunner;
}

namespace content {
struct BrowserMessageFilterTraits;

// Base class for message filters in the browser process.  You can receive and
// send messages on any thread.
class CONTENT_EXPORT BrowserMessageFilter
    : public base::RefCountedThreadSafe<
          BrowserMessageFilter, BrowserMessageFilterTraits>,
      public IPC::Sender {
 public:
  BrowserMessageFilter();

  // These match the corresponding IPC::ChannelProxy::MessageFilter methods and
  // are always called on the IO thread.
  virtual void OnFilterAdded(IPC::Channel* channel) {}
  virtual void OnFilterRemoved() {}
  virtual void OnChannelClosing() {}
  virtual void OnChannelConnected(int32 peer_pid) {}

  // Called when the message filter is about to be deleted.  This gives
  // derived classes the option of controlling which thread they're deleted
  // on etc.
  virtual void OnDestruct() const;

  // IPC::Sender implementation.  Can be called on any thread.  Can't send sync
  // messages (since we don't want to block the browser on any other process).
  virtual bool Send(IPC::Message* message) OVERRIDE;

  // If you want the given message to be dispatched to your OnMessageReceived on
  // a different thread, there are two options, either
  // OverrideThreadForMessage or OverrideTaskRunnerForMessage.
  // If neither is overriden, the message will be dispatched on the IO thread.

  // If you want the message to be dispatched on a particular well-known
  // browser thread, change |thread| to the id of the target thread
  virtual void OverrideThreadForMessage(
      const IPC::Message& message,
      BrowserThread::ID* thread) {}

  // If you want the message to be dispatched via the SequencedWorkerPool,
  // return a non-null task runner which will target tasks accordingly.
  // Note: To target the UI thread, please use OverrideThreadForMessage
  // since that has extra checks to avoid deadlocks.
  virtual base::TaskRunner* OverrideTaskRunnerForMessage(
      const IPC::Message& message);

  // Override this to receive messages.
  // Your function will normally be called on the IO thread.  However, if your
  // OverrideXForMessage modifies the thread used to dispatch the message,
  // your function will be called on the requested thread.
  virtual bool OnMessageReceived(const IPC::Message& message,
                                 bool* message_was_ok) = 0;

  // Can be called on any thread, after OnChannelConnected is called.
  base::ProcessHandle PeerHandle();

  // Can be called on any thread, after OnChannelConnected is called.
  base::ProcessId peer_pid() const { return peer_pid_; }

  void set_peer_pid_for_testing(base::ProcessId peer_pid) {
    peer_pid_ = peer_pid;
  }

  // Checks that the given message can be dispatched on the UI thread, depending
  // on the platform.  If not, returns false and an error ot the sender.
  static bool CheckCanDispatchOnUI(const IPC::Message& message,
                                   IPC::Sender* sender);

  // Call this if a message couldn't be deserialized.  This kills the renderer.
  // Can be called on any thread.
  virtual void BadMessageReceived();

 protected:
  virtual ~BrowserMessageFilter();

 private:
  friend class base::RefCountedThreadSafe<BrowserMessageFilter,
                                          BrowserMessageFilterTraits>;

  class Internal;
  friend class BrowserChildProcessHostImpl;
  friend class BrowserPpapiHost;
  friend class RenderProcessHostImpl;

  // This is private because the only classes that need access to it are made
  // friends above. This is only guaranteed to be valid on creation, after that
  // this class could outlive the filter.
  IPC::ChannelProxy::MessageFilter* GetFilter();

  // This implements IPC::ChannelProxy::MessageFilter so that we can hide that
  // from child classes. Internal keeps a reference to this class, which is why
  // there's a weak pointer back. This class could outlive Internal based on
  // what the child class does in its OnDestruct method.
  Internal* internal_;

  IPC::Channel* channel_;
  base::ProcessId peer_pid_;

#if defined(OS_WIN)
  base::Lock peer_handle_lock_;
  base::ProcessHandle peer_handle_;
#endif
};

struct BrowserMessageFilterTraits {
  static void Destruct(const BrowserMessageFilter* filter) {
    filter->OnDestruct();
  }
};

}  // namespace content

#endif  // CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_