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