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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
content / public / browser / browser_message_filter.h [blame]
// Copyright 2012 The Chromium Authors
// 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 <stddef.h>
#include <stdint.h>
#include <utility>
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/process/process.h"
#include "base/task/sequenced_task_runner.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_thread.h"
#include "ipc/ipc_channel_proxy.h"
#if BUILDFLAG(IS_WIN)
#include "base/synchronization/lock.h"
#endif
namespace IPC {
class MessageFilter;
}
namespace content {
struct BrowserMessageFilterTraits;
// Base class for message filters in the browser process. You can receive and
// send messages on any thread.
//
// BrowserMessageFilters are ref-counted, and a reference to them is held by the
// IPC ChannelProxy for which they have been installed, so do not rely on the
// destructor being called on a specific sequence unless you specify otherwise
// in OnDestruct().
class CONTENT_EXPORT BrowserMessageFilter
: public base::RefCountedThreadSafe<
BrowserMessageFilter, BrowserMessageFilterTraits>,
public IPC::Sender {
public:
explicit BrowserMessageFilter(uint32_t message_class_to_filter);
BrowserMessageFilter(const uint32_t* message_classes_to_filter,
size_t num_message_classes_to_filter);
// These match the corresponding IPC::MessageFilter methods and are always
// called on the IO thread.
virtual void OnFilterAdded(IPC::Channel* channel) {}
virtual void OnFilterRemoved() {}
virtual void OnChannelClosing() {}
virtual void OnChannelError() {}
virtual void OnChannelConnected(int32_t 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).
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 scoped_refptr<base::SequencedTaskRunner> 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) = 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_process_.Pid(); }
void set_peer_process_for_testing(base::Process peer_process) {
peer_process_ = std::move(peer_process);
}
// Called by bad_message.h helpers if a message couldn't be deserialized. This
// kills the renderer. Can be called on any thread. This doesn't log the
// error details to UMA, so use the bad_message.h for your module instead.
virtual void ShutdownForBadMessage();
const std::vector<uint32_t>& message_classes_to_filter() const {
return message_classes_to_filter_;
}
protected:
~BrowserMessageFilter() override;
private:
friend class base::RefCountedThreadSafe<BrowserMessageFilter,
BrowserMessageFilterTraits>;
class Internal;
friend class AgentSchedulingGroupHost;
friend class BrowserChildProcessHostImpl;
friend class BrowserPpapiHost;
friend class RenderProcessHostImpl;
// These are private because the only classes that need access to them are
// made friends above. These are only guaranteed to be valid to call on
// creation. After that this class could outlive the filter.
IPC::MessageFilter* GetFilter();
// This implements IPC::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.
raw_ptr<Internal, AcrossTasksDanglingUntriaged> internal_ = nullptr;
raw_ptr<IPC::Sender> sender_ = nullptr;
base::Process peer_process_;
std::vector<uint32_t> message_classes_to_filter_;
// Callbacks to be called in OnFilterRemoved().
std::vector<base::OnceClosure> filter_removed_callbacks_;
};
struct BrowserMessageFilterTraits {
static void Destruct(const BrowserMessageFilter* filter) {
filter->OnDestruct();
}
};
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_BROWSER_MESSAGE_FILTER_H_