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.
5 #include "build/build_config.h"
7 #include "base/pickle.h"
8 #include "base/threading/thread.h"
9 #include "ipc/ipc_message.h"
10 #include "ipc/ipc_test_base.h"
11 #include "ipc/message_filter.h"
13 // Get basic type definitions.
14 #define IPC_MESSAGE_IMPL
15 #include "ipc/ipc_channel_proxy_unittest_messages.h"
17 // Generate constructors.
18 #include "ipc/struct_constructor_macros.h"
19 #include "ipc/ipc_channel_proxy_unittest_messages.h"
21 // Generate destructors.
22 #include "ipc/struct_destructor_macros.h"
23 #include "ipc/ipc_channel_proxy_unittest_messages.h"
25 // Generate param traits write methods.
26 #include "ipc/param_traits_write_macros.h"
28 #include "ipc/ipc_channel_proxy_unittest_messages.h"
31 // Generate param traits read methods.
32 #include "ipc/param_traits_read_macros.h"
34 #include "ipc/ipc_channel_proxy_unittest_messages.h"
37 // Generate param traits log methods.
38 #include "ipc/param_traits_log_macros.h"
40 #include "ipc/ipc_channel_proxy_unittest_messages.h"
46 class QuitListener
: public IPC::Listener
{
48 QuitListener() : bad_message_received_(false) {}
50 bool OnMessageReceived(const IPC::Message
& message
) override
{
51 IPC_BEGIN_MESSAGE_MAP(QuitListener
, message
)
52 IPC_MESSAGE_HANDLER(WorkerMsg_Quit
, OnQuit
)
53 IPC_MESSAGE_HANDLER(TestMsg_BadMessage
, OnBadMessage
)
58 void OnBadMessageReceived(const IPC::Message
& message
) override
{
59 bad_message_received_
= true;
63 base::MessageLoop::current()->QuitWhenIdle();
66 void OnBadMessage(const BadType
& bad_type
) {
67 // Should never be called since IPC wouldn't be deserialized correctly.
71 bool bad_message_received_
;
74 class ChannelReflectorListener
: public IPC::Listener
{
76 ChannelReflectorListener() : channel_(NULL
) {}
78 void Init(IPC::Channel
* channel
) {
83 bool OnMessageReceived(const IPC::Message
& message
) override
{
84 IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener
, message
)
85 IPC_MESSAGE_HANDLER(TestMsg_Bounce
, OnTestBounce
)
86 IPC_MESSAGE_HANDLER(TestMsg_SendBadMessage
, OnSendBadMessage
)
87 IPC_MESSAGE_HANDLER(UtilityMsg_Bounce
, OnUtilityBounce
)
88 IPC_MESSAGE_HANDLER(WorkerMsg_Bounce
, OnBounce
)
89 IPC_MESSAGE_HANDLER(WorkerMsg_Quit
, OnQuit
)
95 channel_
->Send(new TestMsg_Bounce());
98 void OnSendBadMessage() {
99 channel_
->Send(new TestMsg_BadMessage(BadType()));
102 void OnUtilityBounce() {
103 channel_
->Send(new UtilityMsg_Bounce());
107 channel_
->Send(new WorkerMsg_Bounce());
111 channel_
->Send(new WorkerMsg_Quit());
112 base::MessageLoop::current()->QuitWhenIdle();
116 IPC::Channel
* channel_
;
119 class MessageCountFilter
: public IPC::MessageFilter
{
130 : messages_received_(0),
131 supported_message_class_(0),
132 is_global_filter_(true),
133 last_filter_event_(NONE
),
134 message_filtering_enabled_(false) {}
136 MessageCountFilter(uint32_t supported_message_class
)
137 : messages_received_(0),
138 supported_message_class_(supported_message_class
),
139 is_global_filter_(false),
140 last_filter_event_(NONE
),
141 message_filtering_enabled_(false) {}
143 void OnFilterAdded(IPC::Sender
* sender
) override
{
145 EXPECT_EQ(NONE
, last_filter_event_
);
146 last_filter_event_
= FILTER_ADDED
;
149 void OnChannelConnected(int32_t peer_pid
) override
{
150 EXPECT_EQ(FILTER_ADDED
, last_filter_event_
);
151 EXPECT_NE(static_cast<int32_t>(base::kNullProcessId
), peer_pid
);
152 last_filter_event_
= CHANNEL_CONNECTED
;
155 void OnChannelError() override
{
156 EXPECT_EQ(CHANNEL_CONNECTED
, last_filter_event_
);
157 last_filter_event_
= CHANNEL_ERROR
;
160 void OnChannelClosing() override
{
161 // We may or may not have gotten OnChannelError; if not, the last event has
162 // to be OnChannelConnected.
163 if (last_filter_event_
!= CHANNEL_ERROR
)
164 EXPECT_EQ(CHANNEL_CONNECTED
, last_filter_event_
);
165 last_filter_event_
= CHANNEL_CLOSING
;
168 void OnFilterRemoved() override
{
169 // If the channel didn't get a chance to connect, we might see the
170 // OnFilterRemoved event with no other events preceding it. We still want
171 // OnFilterRemoved to be called to allow for deleting the Filter.
172 if (last_filter_event_
!= NONE
)
173 EXPECT_EQ(CHANNEL_CLOSING
, last_filter_event_
);
174 last_filter_event_
= FILTER_REMOVED
;
177 bool OnMessageReceived(const IPC::Message
& message
) override
{
178 // We should always get the OnFilterAdded and OnChannelConnected events
179 // prior to any messages.
180 EXPECT_EQ(CHANNEL_CONNECTED
, last_filter_event_
);
182 if (!is_global_filter_
) {
183 EXPECT_EQ(supported_message_class_
, IPC_MESSAGE_CLASS(message
));
185 ++messages_received_
;
187 if (!message_filtering_enabled_
)
191 IPC_BEGIN_MESSAGE_MAP(MessageCountFilter
, message
)
192 IPC_MESSAGE_HANDLER(TestMsg_BadMessage
, OnBadMessage
)
193 IPC_MESSAGE_UNHANDLED(handled
= false)
194 IPC_END_MESSAGE_MAP()
198 void OnBadMessage(const BadType
& bad_type
) {
199 // Should never be called since IPC wouldn't be deserialized correctly.
203 bool GetSupportedMessageClasses(
204 std::vector
<uint32_t>* supported_message_classes
) const override
{
205 if (is_global_filter_
)
207 supported_message_classes
->push_back(supported_message_class_
);
211 void set_message_filtering_enabled(bool enabled
) {
212 message_filtering_enabled_
= enabled
;
215 size_t messages_received() const { return messages_received_
; }
216 FilterEvent
last_filter_event() const { return last_filter_event_
; }
219 ~MessageCountFilter() override
{}
221 size_t messages_received_
;
222 uint32_t supported_message_class_
;
223 bool is_global_filter_
;
225 FilterEvent last_filter_event_
;
226 bool message_filtering_enabled_
;
229 class IPCChannelProxyTest
: public IPCTestBase
{
231 IPCChannelProxyTest() {}
232 ~IPCChannelProxyTest() override
{}
234 void SetUp() override
{
235 IPCTestBase::SetUp();
237 Init("ChannelProxyClient");
239 thread_
.reset(new base::Thread("ChannelProxyTestServerThread"));
240 base::Thread::Options options
;
241 options
.message_loop_type
= base::MessageLoop::TYPE_IO
;
242 thread_
->StartWithOptions(options
);
244 listener_
.reset(new QuitListener());
245 CreateChannelProxy(listener_
.get(), thread_
->task_runner().get());
247 ASSERT_TRUE(StartClient());
250 void TearDown() override
{
251 DestroyChannelProxy();
254 IPCTestBase::TearDown();
257 void SendQuitMessageAndWaitForIdle() {
258 sender()->Send(new WorkerMsg_Quit
);
259 base::MessageLoop::current()->Run();
260 EXPECT_TRUE(WaitForClientShutdown());
263 bool DidListenerGetBadMessage() {
264 return listener_
->bad_message_received_
;
268 scoped_ptr
<base::Thread
> thread_
;
269 scoped_ptr
<QuitListener
> listener_
;
272 #if defined(OS_ANDROID)
273 #define MAYBE_MessageClassFilters DISABLED_MessageClassFilters
275 #define MAYBE_MessageClassFilters MessageClassFilters
277 TEST_F(IPCChannelProxyTest
, MAYBE_MessageClassFilters
) {
278 // Construct a filter per message class.
279 std::vector
<scoped_refptr
<MessageCountFilter
> > class_filters
;
280 class_filters
.push_back(make_scoped_refptr(
281 new MessageCountFilter(TestMsgStart
)));
282 class_filters
.push_back(make_scoped_refptr(
283 new MessageCountFilter(UtilityMsgStart
)));
284 for (size_t i
= 0; i
< class_filters
.size(); ++i
)
285 channel_proxy()->AddFilter(class_filters
[i
].get());
287 // Send a message for each class; each filter should receive just one message.
288 sender()->Send(new TestMsg_Bounce());
289 sender()->Send(new UtilityMsg_Bounce());
291 // Send some messages not assigned to a specific or valid message class.
292 sender()->Send(new WorkerMsg_Bounce
);
294 // Each filter should have received just the one sent message of the
295 // corresponding class.
296 SendQuitMessageAndWaitForIdle();
297 for (size_t i
= 0; i
< class_filters
.size(); ++i
)
298 EXPECT_EQ(1U, class_filters
[i
]->messages_received());
301 #if defined(OS_ANDROID)
302 #define MAYBE_GlobalAndMessageClassFilters DISABLED_GlobalAndMessageClassFilters
304 #define MAYBE_GlobalAndMessageClassFilters GlobalAndMessageClassFilters
306 TEST_F(IPCChannelProxyTest
, MAYBE_GlobalAndMessageClassFilters
) {
307 // Add a class and global filter.
308 scoped_refptr
<MessageCountFilter
> class_filter(
309 new MessageCountFilter(TestMsgStart
));
310 class_filter
->set_message_filtering_enabled(false);
311 channel_proxy()->AddFilter(class_filter
.get());
313 scoped_refptr
<MessageCountFilter
> global_filter(new MessageCountFilter());
314 global_filter
->set_message_filtering_enabled(false);
315 channel_proxy()->AddFilter(global_filter
.get());
317 // A message of class Test should be seen by both the global filter and
318 // Test-specific filter.
319 sender()->Send(new TestMsg_Bounce
);
321 // A message of a different class should be seen only by the global filter.
322 sender()->Send(new UtilityMsg_Bounce
);
324 // Flush all messages.
325 SendQuitMessageAndWaitForIdle();
327 // The class filter should have received only the class-specific message.
328 EXPECT_EQ(1U, class_filter
->messages_received());
330 // The global filter should have received both messages, as well as the final
332 EXPECT_EQ(3U, global_filter
->messages_received());
335 #if defined(OS_ANDROID)
336 #define MAYBE_FilterRemoval DISABLED_FilterRemoval
338 #define MAYBE_FilterRemoval FilterRemoval
340 TEST_F(IPCChannelProxyTest
, MAYBE_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());
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());
352 // Send some messages; they should not be seen by either filter.
353 sender()->Send(new TestMsg_Bounce
);
354 sender()->Send(new UtilityMsg_Bounce
);
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());
366 // The test that follow trigger DCHECKS in debug build.
367 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
369 TEST_F(IPCChannelProxyTest
, BadMessageOnListenerThread
) {
370 scoped_refptr
<MessageCountFilter
> class_filter(
371 new MessageCountFilter(TestMsgStart
));
372 class_filter
->set_message_filtering_enabled(false);
373 channel_proxy()->AddFilter(class_filter
.get());
375 sender()->Send(new TestMsg_SendBadMessage());
377 SendQuitMessageAndWaitForIdle();
378 EXPECT_TRUE(DidListenerGetBadMessage());
381 TEST_F(IPCChannelProxyTest
, BadMessageOnIPCThread
) {
382 scoped_refptr
<MessageCountFilter
> class_filter(
383 new MessageCountFilter(TestMsgStart
));
384 class_filter
->set_message_filtering_enabled(true);
385 channel_proxy()->AddFilter(class_filter
.get());
387 sender()->Send(new TestMsg_SendBadMessage());
389 SendQuitMessageAndWaitForIdle();
390 EXPECT_TRUE(DidListenerGetBadMessage());
393 class IPCChannelBadMessageTest
: public IPCTestBase
{
395 void SetUp() override
{
396 IPCTestBase::SetUp();
398 Init("ChannelProxyClient");
400 listener_
.reset(new QuitListener());
401 CreateChannel(listener_
.get());
402 ASSERT_TRUE(ConnectChannel());
404 ASSERT_TRUE(StartClient());
407 void TearDown() override
{
409 IPCTestBase::TearDown();
412 void SendQuitMessageAndWaitForIdle() {
413 sender()->Send(new WorkerMsg_Quit
);
414 base::MessageLoop::current()->Run();
415 EXPECT_TRUE(WaitForClientShutdown());
418 bool DidListenerGetBadMessage() {
419 return listener_
->bad_message_received_
;
423 scoped_ptr
<QuitListener
> listener_
;
427 // TODO(jam): for some reason this is flaky on win buildbots.
428 TEST_F(IPCChannelBadMessageTest
, BadMessage
) {
429 sender()->Send(new TestMsg_SendBadMessage());
430 SendQuitMessageAndWaitForIdle();
431 EXPECT_TRUE(DidListenerGetBadMessage());
437 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ChannelProxyClient
) {
438 base::MessageLoopForIO main_message_loop
;
439 ChannelReflectorListener listener
;
440 scoped_ptr
<IPC::Channel
> channel(IPC::Channel::CreateClient(
441 IPCTestBase::GetChannelName("ChannelProxyClient"), &listener
, nullptr));
442 CHECK(channel
->Connect());
443 listener
.Init(channel
.get());
445 base::MessageLoop::current()->Run();