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