1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/memory/raw_ptr.h"
6 #include "base/memory/raw_ptr_exclusion.h"
7 #include "build/build_config.h"
8
9 #include <stddef.h>
10 #include <stdint.h>
11
12 #include <memory>
13
14 #include "base/message_loop/message_pump_type.h"
15 #include "base/pickle.h"
16 #include "base/run_loop.h"
17 #include "base/task/single_thread_task_runner.h"
18 #include "base/threading/thread.h"
19 #include "ipc/ipc_message.h"
20 #include "ipc/ipc_test_base.h"
21 #include "ipc/message_filter.h"
22
23 // Get basic type definitions.
24 #define IPC_MESSAGE_IMPL
25 #include "ipc/ipc_channel_proxy_unittest_messages.h"
26
27 // Generate constructors.
28 #include "ipc/struct_constructor_macros.h"
29 #include "ipc/ipc_channel_proxy_unittest_messages.h"
30
31 // Generate param traits write methods.
32 #include "ipc/param_traits_write_macros.h"
33 namespace IPC {
34 #include "ipc/ipc_channel_proxy_unittest_messages.h"
35 } // namespace IPC
36
37 // Generate param traits read methods.
38 #include "ipc/param_traits_read_macros.h"
39 namespace IPC {
40 #include "ipc/ipc_channel_proxy_unittest_messages.h"
41 } // namespace IPC
42
43 // Generate param traits log methods.
44 #include "ipc/param_traits_log_macros.h"
45 namespace IPC {
46 #include "ipc/ipc_channel_proxy_unittest_messages.h"
47 } // namespace IPC
48
49
50 namespace {
51
CreateRunLoopAndRun(base::RunLoop ** run_loop_ptr)52 void CreateRunLoopAndRun(base::RunLoop** run_loop_ptr) {
53 base::RunLoop run_loop;
54 *run_loop_ptr = &run_loop;
55 run_loop.Run();
56 *run_loop_ptr = nullptr;
57 }
58
59 class QuitListener : public IPC::Listener {
60 public:
61 QuitListener() = default;
62
OnMessageReceived(const IPC::Message & message)63 bool OnMessageReceived(const IPC::Message& message) override {
64 IPC_BEGIN_MESSAGE_MAP(QuitListener, message)
65 IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
66 IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
67 IPC_END_MESSAGE_MAP()
68 return true;
69 }
70
OnBadMessageReceived(const IPC::Message & message)71 void OnBadMessageReceived(const IPC::Message& message) override {
72 bad_message_received_ = true;
73 }
74
OnChannelError()75 void OnChannelError() override { CHECK(quit_message_received_); }
76
OnQuit()77 void OnQuit() {
78 quit_message_received_ = true;
79 run_loop_->QuitWhenIdle();
80 }
81
OnBadMessage(const BadType & bad_type)82 void OnBadMessage(const BadType& bad_type) {
83 // Should never be called since IPC wouldn't be deserialized correctly.
84 CHECK(false);
85 }
86
87 bool bad_message_received_ = false;
88 bool quit_message_received_ = false;
89 // This field is not a raw_ptr<> because it was filtered by the rewriter for:
90 // #constexpr-ctor-field-initializer, #addr-of
91 RAW_PTR_EXCLUSION base::RunLoop* run_loop_ = nullptr;
92 };
93
94 class ChannelReflectorListener : public IPC::Listener {
95 public:
96 ChannelReflectorListener() = default;
97
Init(IPC::Channel * channel)98 void Init(IPC::Channel* channel) {
99 DCHECK(!channel_);
100 channel_ = channel;
101 }
102
OnMessageReceived(const IPC::Message & message)103 bool OnMessageReceived(const IPC::Message& message) override {
104 IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
105 IPC_MESSAGE_HANDLER(TestMsg_Bounce, OnTestBounce)
106 IPC_MESSAGE_HANDLER(TestMsg_SendBadMessage, OnSendBadMessage)
107 IPC_MESSAGE_HANDLER(AutomationMsg_Bounce, OnAutomationBounce)
108 IPC_MESSAGE_HANDLER(WorkerMsg_Bounce, OnBounce)
109 IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
110 IPC_END_MESSAGE_MAP()
111 return true;
112 }
113
OnTestBounce()114 void OnTestBounce() {
115 channel_->Send(new TestMsg_Bounce());
116 }
117
OnSendBadMessage()118 void OnSendBadMessage() {
119 channel_->Send(new TestMsg_BadMessage(BadType()));
120 }
121
OnAutomationBounce()122 void OnAutomationBounce() { channel_->Send(new AutomationMsg_Bounce()); }
123
OnBounce()124 void OnBounce() {
125 channel_->Send(new WorkerMsg_Bounce());
126 }
127
OnQuit()128 void OnQuit() {
129 channel_->Send(new WorkerMsg_Quit());
130 run_loop_->QuitWhenIdle();
131 }
132
133 // This field is not a raw_ptr<> because it was filtered by the rewriter for:
134 // #constexpr-ctor-field-initializer, #addr-of
135 RAW_PTR_EXCLUSION base::RunLoop* run_loop_ = nullptr;
136
137 private:
138 raw_ptr<IPC::Channel> channel_ = nullptr;
139 };
140
141 class MessageCountFilter : public IPC::MessageFilter {
142 public:
143 enum FilterEvent {
144 NONE,
145 FILTER_ADDED,
146 CHANNEL_CONNECTED,
147 CHANNEL_ERROR,
148 CHANNEL_CLOSING,
149 FILTER_REMOVED
150 };
151
152 MessageCountFilter() = default;
MessageCountFilter(uint32_t supported_message_class)153 MessageCountFilter(uint32_t supported_message_class)
154 : supported_message_class_(supported_message_class),
155 is_global_filter_(false) {}
156
OnFilterAdded(IPC::Channel * channel)157 void OnFilterAdded(IPC::Channel* channel) override {
158 EXPECT_TRUE(channel);
159 EXPECT_EQ(NONE, last_filter_event_);
160 last_filter_event_ = FILTER_ADDED;
161 }
162
OnChannelConnected(int32_t peer_pid)163 void OnChannelConnected(int32_t peer_pid) override {
164 EXPECT_EQ(FILTER_ADDED, last_filter_event_);
165 EXPECT_NE(static_cast<int32_t>(base::kNullProcessId), peer_pid);
166 last_filter_event_ = CHANNEL_CONNECTED;
167 }
168
OnChannelError()169 void OnChannelError() override {
170 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
171 last_filter_event_ = CHANNEL_ERROR;
172 }
173
OnChannelClosing()174 void OnChannelClosing() override {
175 // We may or may not have gotten OnChannelError; if not, the last event has
176 // to be OnChannelConnected.
177 EXPECT_NE(FILTER_REMOVED, last_filter_event_);
178 if (last_filter_event_ != CHANNEL_ERROR)
179 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
180 last_filter_event_ = CHANNEL_CLOSING;
181 }
182
OnFilterRemoved()183 void OnFilterRemoved() override {
184 // A filter may be removed at any time, even before the channel is connected
185 // (and thus before OnFilterAdded is ever able to dispatch.) The only time
186 // we won't see OnFilterRemoved is immediately after OnFilterAdded, because
187 // OnChannelConnected is always the next event to fire after that.
188 EXPECT_NE(FILTER_ADDED, last_filter_event_);
189 last_filter_event_ = FILTER_REMOVED;
190 }
191
OnMessageReceived(const IPC::Message & message)192 bool OnMessageReceived(const IPC::Message& message) override {
193 // We should always get the OnFilterAdded and OnChannelConnected events
194 // prior to any messages.
195 EXPECT_EQ(CHANNEL_CONNECTED, last_filter_event_);
196
197 if (!is_global_filter_) {
198 EXPECT_EQ(supported_message_class_, IPC_MESSAGE_CLASS(message));
199 }
200 ++messages_received_;
201
202 if (!message_filtering_enabled_)
203 return false;
204
205 bool handled = true;
206 IPC_BEGIN_MESSAGE_MAP(MessageCountFilter, message)
207 IPC_MESSAGE_HANDLER(TestMsg_BadMessage, OnBadMessage)
208 IPC_MESSAGE_UNHANDLED(handled = false)
209 IPC_END_MESSAGE_MAP()
210 return handled;
211 }
212
OnBadMessage(const BadType & bad_type)213 void OnBadMessage(const BadType& bad_type) {
214 // Should never be called since IPC wouldn't be deserialized correctly.
215 CHECK(false);
216 }
217
GetSupportedMessageClasses(std::vector<uint32_t> * supported_message_classes) const218 bool GetSupportedMessageClasses(
219 std::vector<uint32_t>* supported_message_classes) const override {
220 if (is_global_filter_)
221 return false;
222 supported_message_classes->push_back(supported_message_class_);
223 return true;
224 }
225
set_message_filtering_enabled(bool enabled)226 void set_message_filtering_enabled(bool enabled) {
227 message_filtering_enabled_ = enabled;
228 }
229
messages_received() const230 size_t messages_received() const { return messages_received_; }
last_filter_event() const231 FilterEvent last_filter_event() const { return last_filter_event_; }
232
233 private:
234 ~MessageCountFilter() override = default;
235
236 size_t messages_received_ = 0;
237 uint32_t supported_message_class_ = 0;
238 bool is_global_filter_ = true;
239
240 FilterEvent last_filter_event_ = NONE;
241 bool message_filtering_enabled_ = false;
242 };
243
244 class IPCChannelProxyTest : public IPCChannelMojoTestBase {
245 public:
246 IPCChannelProxyTest() = default;
247 ~IPCChannelProxyTest() override = default;
248
SetUp()249 void SetUp() override {
250 IPCChannelMojoTestBase::SetUp();
251
252 Init("ChannelProxyClient");
253
254 thread_ = std::make_unique<base::Thread>("ChannelProxyTestServerThread");
255 base::Thread::Options options;
256 options.message_pump_type = base::MessagePumpType::IO;
257 thread_->StartWithOptions(std::move(options));
258
259 listener_ = std::make_unique<QuitListener>();
260 channel_proxy_ = IPC::ChannelProxy::Create(
261 TakeHandle().release(), IPC::Channel::MODE_SERVER, listener_.get(),
262 thread_->task_runner(),
263 base::SingleThreadTaskRunner::GetCurrentDefault());
264 }
265
TearDown()266 void TearDown() override {
267 channel_proxy_.reset();
268 thread_.reset();
269 listener_.reset();
270 IPCChannelMojoTestBase::TearDown();
271 }
272
SendQuitMessageAndWaitForIdle()273 void SendQuitMessageAndWaitForIdle() {
274 sender()->Send(new WorkerMsg_Quit);
275 CreateRunLoopAndRun(&listener_->run_loop_);
276 EXPECT_TRUE(WaitForClientShutdown());
277 }
278
DidListenerGetBadMessage()279 bool DidListenerGetBadMessage() {
280 return listener_->bad_message_received_;
281 }
282
channel_proxy()283 IPC::ChannelProxy* channel_proxy() { return channel_proxy_.get(); }
sender()284 IPC::Sender* sender() { return channel_proxy_.get(); }
285
286 private:
287 std::unique_ptr<base::Thread> thread_;
288 std::unique_ptr<QuitListener> listener_;
289 std::unique_ptr<IPC::ChannelProxy> channel_proxy_;
290 };
291
TEST_F(IPCChannelProxyTest,MessageClassFilters)292 TEST_F(IPCChannelProxyTest, MessageClassFilters) {
293 // Construct a filter per message class.
294 std::vector<scoped_refptr<MessageCountFilter>> class_filters;
295 class_filters.push_back(
296 base::MakeRefCounted<MessageCountFilter>(TestMsgStart));
297 class_filters.push_back(
298 base::MakeRefCounted<MessageCountFilter>(AutomationMsgStart));
299 for (size_t i = 0; i < class_filters.size(); ++i)
300 channel_proxy()->AddFilter(class_filters[i].get());
301
302 // Send a message for each class; each filter should receive just one message.
303 sender()->Send(new TestMsg_Bounce);
304 sender()->Send(new AutomationMsg_Bounce);
305
306 // Send some messages not assigned to a specific or valid message class.
307 sender()->Send(new WorkerMsg_Bounce);
308
309 // Each filter should have received just the one sent message of the
310 // corresponding class.
311 SendQuitMessageAndWaitForIdle();
312 for (size_t i = 0; i < class_filters.size(); ++i)
313 EXPECT_EQ(1U, class_filters[i]->messages_received());
314 }
315
TEST_F(IPCChannelProxyTest,GlobalAndMessageClassFilters)316 TEST_F(IPCChannelProxyTest, GlobalAndMessageClassFilters) {
317 // Add a class and global filter.
318 scoped_refptr<MessageCountFilter> class_filter(
319 new MessageCountFilter(TestMsgStart));
320 class_filter->set_message_filtering_enabled(false);
321 channel_proxy()->AddFilter(class_filter.get());
322
323 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
324 global_filter->set_message_filtering_enabled(false);
325 channel_proxy()->AddFilter(global_filter.get());
326
327 // A message of class Test should be seen by both the global filter and
328 // Test-specific filter.
329 sender()->Send(new TestMsg_Bounce);
330
331 // A message of a different class should be seen only by the global filter.
332 sender()->Send(new AutomationMsg_Bounce);
333
334 // Flush all messages.
335 SendQuitMessageAndWaitForIdle();
336
337 // The class filter should have received only the class-specific message.
338 EXPECT_EQ(1U, class_filter->messages_received());
339
340 // The global filter should have received both messages, as well as the final
341 // QUIT message.
342 EXPECT_EQ(3U, global_filter->messages_received());
343 }
344
TEST_F(IPCChannelProxyTest,FilterRemoval)345 TEST_F(IPCChannelProxyTest, FilterRemoval) {
346 // Add a class and global filter.
347 scoped_refptr<MessageCountFilter> class_filter(
348 new MessageCountFilter(TestMsgStart));
349 scoped_refptr<MessageCountFilter> global_filter(new MessageCountFilter());
350
351 // Add and remove both types of filters.
352 channel_proxy()->AddFilter(class_filter.get());
353 channel_proxy()->AddFilter(global_filter.get());
354 channel_proxy()->RemoveFilter(global_filter.get());
355 channel_proxy()->RemoveFilter(class_filter.get());
356
357 // Send some messages; they should not be seen by either filter.
358 sender()->Send(new TestMsg_Bounce);
359 sender()->Send(new AutomationMsg_Bounce);
360
361 // Ensure that the filters were removed and did not receive any messages.
362 SendQuitMessageAndWaitForIdle();
363 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
364 global_filter->last_filter_event());
365 EXPECT_EQ(MessageCountFilter::FILTER_REMOVED,
366 class_filter->last_filter_event());
367 EXPECT_EQ(0U, class_filter->messages_received());
368 EXPECT_EQ(0U, global_filter->messages_received());
369 }
370
TEST_F(IPCChannelProxyTest,BadMessageOnListenerThread)371 TEST_F(IPCChannelProxyTest, BadMessageOnListenerThread) {
372 scoped_refptr<MessageCountFilter> class_filter(
373 new MessageCountFilter(TestMsgStart));
374 class_filter->set_message_filtering_enabled(false);
375 channel_proxy()->AddFilter(class_filter.get());
376
377 sender()->Send(new TestMsg_SendBadMessage());
378
379 SendQuitMessageAndWaitForIdle();
380 EXPECT_TRUE(DidListenerGetBadMessage());
381 }
382
TEST_F(IPCChannelProxyTest,BadMessageOnIPCThread)383 TEST_F(IPCChannelProxyTest, BadMessageOnIPCThread) {
384 scoped_refptr<MessageCountFilter> class_filter(
385 new MessageCountFilter(TestMsgStart));
386 class_filter->set_message_filtering_enabled(true);
387 channel_proxy()->AddFilter(class_filter.get());
388
389 sender()->Send(new TestMsg_SendBadMessage());
390
391 SendQuitMessageAndWaitForIdle();
392 EXPECT_TRUE(DidListenerGetBadMessage());
393 }
394
395 class IPCChannelBadMessageTest : public IPCChannelMojoTestBase {
396 public:
SetUp()397 void SetUp() override {
398 IPCChannelMojoTestBase::SetUp();
399
400 Init("ChannelProxyClient");
401
402 listener_ = std::make_unique<QuitListener>();
403 CreateChannel(listener_.get());
404 ASSERT_TRUE(ConnectChannel());
405 }
406
TearDown()407 void TearDown() override {
408 IPCChannelMojoTestBase::TearDown();
409 listener_.reset();
410 }
411
SendQuitMessageAndWaitForIdle()412 void SendQuitMessageAndWaitForIdle() {
413 sender()->Send(new WorkerMsg_Quit);
414 CreateRunLoopAndRun(&listener_->run_loop_);
415 EXPECT_TRUE(WaitForClientShutdown());
416 }
417
DidListenerGetBadMessage()418 bool DidListenerGetBadMessage() {
419 return listener_->bad_message_received_;
420 }
421
422 private:
423 std::unique_ptr<QuitListener> listener_;
424 };
425
TEST_F(IPCChannelBadMessageTest,BadMessage)426 TEST_F(IPCChannelBadMessageTest, BadMessage) {
427 sender()->Send(new TestMsg_SendBadMessage());
428 SendQuitMessageAndWaitForIdle();
429 EXPECT_TRUE(DidListenerGetBadMessage());
430 }
431
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ChannelProxyClient)432 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ChannelProxyClient) {
433 ChannelReflectorListener listener;
434 Connect(&listener);
435 listener.Init(channel());
436
437 CreateRunLoopAndRun(&listener.run_loop_);
438
439 Close();
440 }
441
442 } // namespace
443