xref: /aosp_15_r20/external/libchrome/ipc/ipc_channel_mojo_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_channel_mojo.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include <memory>
11*635a8641SAndroid Build Coastguard Worker #include <utility>
12*635a8641SAndroid Build Coastguard Worker 
13*635a8641SAndroid Build Coastguard Worker #include "base/base_paths.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/callback_helpers.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/containers/queue.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/files/file.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/files/scoped_temp_dir.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/location.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
21*635a8641SAndroid Build Coastguard Worker #include "base/memory/platform_shared_memory_region.h"
22*635a8641SAndroid Build Coastguard Worker #include "base/memory/shared_memory.h"
23*635a8641SAndroid Build Coastguard Worker #include "base/memory/shared_memory_mapping.h"
24*635a8641SAndroid Build Coastguard Worker #include "base/message_loop/message_loop.h"
25*635a8641SAndroid Build Coastguard Worker #include "base/optional.h"
26*635a8641SAndroid Build Coastguard Worker #include "base/path_service.h"
27*635a8641SAndroid Build Coastguard Worker #include "base/pickle.h"
28*635a8641SAndroid Build Coastguard Worker #include "base/run_loop.h"
29*635a8641SAndroid Build Coastguard Worker #include "base/single_thread_task_runner.h"
30*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
31*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
32*635a8641SAndroid Build Coastguard Worker #include "base/test/bind_test_util.h"
33*635a8641SAndroid Build Coastguard Worker #include "base/test/test_io_thread.h"
34*635a8641SAndroid Build Coastguard Worker #include "base/test/test_shared_memory_util.h"
35*635a8641SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
36*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread.h"
37*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_task_runner_handle.h"
38*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
39*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message.h"
40*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message_utils.h"
41*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_handle_attachment.h"
42*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_message_helper.h"
43*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_param_traits.h"
44*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_sync_channel.h"
45*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_sync_message.h"
46*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_test.mojom.h"
47*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_test_base.h"
48*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_test_channel_listener.h"
49*635a8641SAndroid Build Coastguard Worker #include "mojo/core/embedder/embedder.h"
50*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/lib/validation_errors.h"
51*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/wait.h"
52*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
53*635a8641SAndroid Build Coastguard Worker 
54*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
55*635a8641SAndroid Build Coastguard Worker #include "base/file_descriptor_posix.h"
56*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_platform_file_attachment_posix.h"
57*635a8641SAndroid Build Coastguard Worker #endif
58*635a8641SAndroid Build Coastguard Worker 
59*635a8641SAndroid Build Coastguard Worker namespace {
60*635a8641SAndroid Build Coastguard Worker 
SendString(IPC::Sender * sender,const std::string & str)61*635a8641SAndroid Build Coastguard Worker void SendString(IPC::Sender* sender, const std::string& str) {
62*635a8641SAndroid Build Coastguard Worker   IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
63*635a8641SAndroid Build Coastguard Worker   message->WriteString(str);
64*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(sender->Send(message));
65*635a8641SAndroid Build Coastguard Worker }
66*635a8641SAndroid Build Coastguard Worker 
SendValue(IPC::Sender * sender,int32_t value)67*635a8641SAndroid Build Coastguard Worker void SendValue(IPC::Sender* sender, int32_t value) {
68*635a8641SAndroid Build Coastguard Worker   IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
69*635a8641SAndroid Build Coastguard Worker   message->WriteInt(value);
70*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(sender->Send(message));
71*635a8641SAndroid Build Coastguard Worker }
72*635a8641SAndroid Build Coastguard Worker 
73*635a8641SAndroid Build Coastguard Worker class ListenerThatExpectsOK : public IPC::Listener {
74*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatExpectsOK(base::OnceClosure quit_closure)75*635a8641SAndroid Build Coastguard Worker   explicit ListenerThatExpectsOK(base::OnceClosure quit_closure)
76*635a8641SAndroid Build Coastguard Worker       : received_ok_(false), quit_closure_(std::move(quit_closure)) {}
77*635a8641SAndroid Build Coastguard Worker 
78*635a8641SAndroid Build Coastguard Worker   ~ListenerThatExpectsOK() override = default;
79*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)80*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
81*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
82*635a8641SAndroid Build Coastguard Worker     std::string should_be_ok;
83*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(iter.ReadString(&should_be_ok));
84*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(should_be_ok, "OK");
85*635a8641SAndroid Build Coastguard Worker     received_ok_ = true;
86*635a8641SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
87*635a8641SAndroid Build Coastguard Worker     return true;
88*635a8641SAndroid Build Coastguard Worker   }
89*635a8641SAndroid Build Coastguard Worker 
OnChannelError()90*635a8641SAndroid Build Coastguard Worker   void OnChannelError() override {
91*635a8641SAndroid Build Coastguard Worker     // The connection should be healthy while the listener is waiting
92*635a8641SAndroid Build Coastguard Worker     // message.  An error can occur after that because the peer
93*635a8641SAndroid Build Coastguard Worker     // process dies.
94*635a8641SAndroid Build Coastguard Worker     CHECK(received_ok_);
95*635a8641SAndroid Build Coastguard Worker   }
96*635a8641SAndroid Build Coastguard Worker 
SendOK(IPC::Sender * sender)97*635a8641SAndroid Build Coastguard Worker   static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
98*635a8641SAndroid Build Coastguard Worker 
99*635a8641SAndroid Build Coastguard Worker  private:
100*635a8641SAndroid Build Coastguard Worker   bool received_ok_;
101*635a8641SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
102*635a8641SAndroid Build Coastguard Worker };
103*635a8641SAndroid Build Coastguard Worker 
104*635a8641SAndroid Build Coastguard Worker class TestListenerBase : public IPC::Listener {
105*635a8641SAndroid Build Coastguard Worker  public:
TestListenerBase(base::OnceClosure quit_closure)106*635a8641SAndroid Build Coastguard Worker   explicit TestListenerBase(base::OnceClosure quit_closure)
107*635a8641SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)) {}
108*635a8641SAndroid Build Coastguard Worker 
109*635a8641SAndroid Build Coastguard Worker   ~TestListenerBase() override = default;
OnChannelError()110*635a8641SAndroid Build Coastguard Worker   void OnChannelError() override { RunQuitClosure(); }
111*635a8641SAndroid Build Coastguard Worker 
set_sender(IPC::Sender * sender)112*635a8641SAndroid Build Coastguard Worker   void set_sender(IPC::Sender* sender) { sender_ = sender; }
sender() const113*635a8641SAndroid Build Coastguard Worker   IPC::Sender* sender() const { return sender_; }
RunQuitClosure()114*635a8641SAndroid Build Coastguard Worker   void RunQuitClosure() {
115*635a8641SAndroid Build Coastguard Worker     if (quit_closure_)
116*635a8641SAndroid Build Coastguard Worker       std::move(quit_closure_).Run();
117*635a8641SAndroid Build Coastguard Worker   }
118*635a8641SAndroid Build Coastguard Worker 
119*635a8641SAndroid Build Coastguard Worker  private:
120*635a8641SAndroid Build Coastguard Worker   IPC::Sender* sender_ = nullptr;
121*635a8641SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
122*635a8641SAndroid Build Coastguard Worker };
123*635a8641SAndroid Build Coastguard Worker 
124*635a8641SAndroid Build Coastguard Worker using IPCChannelMojoTest = IPCChannelMojoTestBase;
125*635a8641SAndroid Build Coastguard Worker 
126*635a8641SAndroid Build Coastguard Worker class TestChannelListenerWithExtraExpectations
127*635a8641SAndroid Build Coastguard Worker     : public IPC::TestChannelListener {
128*635a8641SAndroid Build Coastguard Worker  public:
TestChannelListenerWithExtraExpectations()129*635a8641SAndroid Build Coastguard Worker   TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
130*635a8641SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)131*635a8641SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
132*635a8641SAndroid Build Coastguard Worker     IPC::TestChannelListener::OnChannelConnected(peer_pid);
133*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(base::kNullProcessId != peer_pid);
134*635a8641SAndroid Build Coastguard Worker     is_connected_called_ = true;
135*635a8641SAndroid Build Coastguard Worker   }
136*635a8641SAndroid Build Coastguard Worker 
is_connected_called() const137*635a8641SAndroid Build Coastguard Worker   bool is_connected_called() const { return is_connected_called_; }
138*635a8641SAndroid Build Coastguard Worker 
139*635a8641SAndroid Build Coastguard Worker  private:
140*635a8641SAndroid Build Coastguard Worker   bool is_connected_called_;
141*635a8641SAndroid Build Coastguard Worker };
142*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,ConnectedFromClient)143*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
144*635a8641SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestClient");
145*635a8641SAndroid Build Coastguard Worker 
146*635a8641SAndroid Build Coastguard Worker   // Set up IPC channel and start client.
147*635a8641SAndroid Build Coastguard Worker   TestChannelListenerWithExtraExpectations listener;
148*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
149*635a8641SAndroid Build Coastguard Worker   listener.Init(sender());
150*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
151*635a8641SAndroid Build Coastguard Worker 
152*635a8641SAndroid Build Coastguard Worker   IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
153*635a8641SAndroid Build Coastguard Worker 
154*635a8641SAndroid Build Coastguard Worker   base::RunLoop().Run();
155*635a8641SAndroid Build Coastguard Worker 
156*635a8641SAndroid Build Coastguard Worker   channel()->Close();
157*635a8641SAndroid Build Coastguard Worker 
158*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
159*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.is_connected_called());
160*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.HasSentAll());
161*635a8641SAndroid Build Coastguard Worker 
162*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
163*635a8641SAndroid Build Coastguard Worker }
164*635a8641SAndroid Build Coastguard Worker 
165*635a8641SAndroid Build Coastguard Worker // A long running process that connects to us
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient)166*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient) {
167*635a8641SAndroid Build Coastguard Worker   TestChannelListenerWithExtraExpectations listener;
168*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
169*635a8641SAndroid Build Coastguard Worker   listener.Init(channel());
170*635a8641SAndroid Build Coastguard Worker 
171*635a8641SAndroid Build Coastguard Worker   IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
172*635a8641SAndroid Build Coastguard Worker   base::RunLoop().Run();
173*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.is_connected_called());
174*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.HasSentAll());
175*635a8641SAndroid Build Coastguard Worker 
176*635a8641SAndroid Build Coastguard Worker   Close();
177*635a8641SAndroid Build Coastguard Worker }
178*635a8641SAndroid Build Coastguard Worker 
179*635a8641SAndroid Build Coastguard Worker class ListenerExpectingErrors : public TestListenerBase {
180*635a8641SAndroid Build Coastguard Worker  public:
ListenerExpectingErrors(base::OnceClosure quit_closure)181*635a8641SAndroid Build Coastguard Worker   ListenerExpectingErrors(base::OnceClosure quit_closure)
182*635a8641SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)), has_error_(false) {}
183*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)184*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
185*635a8641SAndroid Build Coastguard Worker 
OnChannelError()186*635a8641SAndroid Build Coastguard Worker   void OnChannelError() override {
187*635a8641SAndroid Build Coastguard Worker     has_error_ = true;
188*635a8641SAndroid Build Coastguard Worker     TestListenerBase::OnChannelError();
189*635a8641SAndroid Build Coastguard Worker   }
190*635a8641SAndroid Build Coastguard Worker 
has_error() const191*635a8641SAndroid Build Coastguard Worker   bool has_error() const { return has_error_; }
192*635a8641SAndroid Build Coastguard Worker 
193*635a8641SAndroid Build Coastguard Worker  private:
194*635a8641SAndroid Build Coastguard Worker   bool has_error_;
195*635a8641SAndroid Build Coastguard Worker };
196*635a8641SAndroid Build Coastguard Worker 
197*635a8641SAndroid Build Coastguard Worker class ListenerThatQuits : public IPC::Listener {
198*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatQuits(base::OnceClosure quit_closure)199*635a8641SAndroid Build Coastguard Worker   explicit ListenerThatQuits(base::OnceClosure quit_closure)
200*635a8641SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)) {}
201*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)202*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
203*635a8641SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)204*635a8641SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
205*635a8641SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
206*635a8641SAndroid Build Coastguard Worker   }
207*635a8641SAndroid Build Coastguard Worker 
208*635a8641SAndroid Build Coastguard Worker  private:
209*635a8641SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
210*635a8641SAndroid Build Coastguard Worker };
211*635a8641SAndroid Build Coastguard Worker 
212*635a8641SAndroid Build Coastguard Worker // A long running process that connects to us.
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient)213*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient) {
214*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
215*635a8641SAndroid Build Coastguard Worker   ListenerThatQuits listener(run_loop.QuitClosure());
216*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
217*635a8641SAndroid Build Coastguard Worker 
218*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
219*635a8641SAndroid Build Coastguard Worker 
220*635a8641SAndroid Build Coastguard Worker   Close();
221*635a8641SAndroid Build Coastguard Worker }
222*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendFailWithPendingMessages)223*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
224*635a8641SAndroid Build Coastguard Worker   Init("IPCChannelMojoErraticTestClient");
225*635a8641SAndroid Build Coastguard Worker 
226*635a8641SAndroid Build Coastguard Worker   // Set up IPC channel and start client.
227*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
228*635a8641SAndroid Build Coastguard Worker   ListenerExpectingErrors listener(run_loop.QuitClosure());
229*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
230*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
231*635a8641SAndroid Build Coastguard Worker 
232*635a8641SAndroid Build Coastguard Worker   // This matches a value in mojo/edk/system/constants.h
233*635a8641SAndroid Build Coastguard Worker   const int kMaxMessageNumBytes = 4 * 1024 * 1024;
234*635a8641SAndroid Build Coastguard Worker   std::string overly_large_data(kMaxMessageNumBytes, '*');
235*635a8641SAndroid Build Coastguard Worker   // This messages are queued as pending.
236*635a8641SAndroid Build Coastguard Worker   for (size_t i = 0; i < 10; ++i) {
237*635a8641SAndroid Build Coastguard Worker     IPC::TestChannelListener::SendOneMessage(sender(),
238*635a8641SAndroid Build Coastguard Worker                                              overly_large_data.c_str());
239*635a8641SAndroid Build Coastguard Worker   }
240*635a8641SAndroid Build Coastguard Worker 
241*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
242*635a8641SAndroid Build Coastguard Worker 
243*635a8641SAndroid Build Coastguard Worker   channel()->Close();
244*635a8641SAndroid Build Coastguard Worker 
245*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
246*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.has_error());
247*635a8641SAndroid Build Coastguard Worker 
248*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
249*635a8641SAndroid Build Coastguard Worker }
250*635a8641SAndroid Build Coastguard Worker 
251*635a8641SAndroid Build Coastguard Worker class ListenerThatBindsATestStructPasser : public IPC::Listener,
252*635a8641SAndroid Build Coastguard Worker                                            public IPC::mojom::TestStructPasser {
253*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatBindsATestStructPasser()254*635a8641SAndroid Build Coastguard Worker   ListenerThatBindsATestStructPasser() : binding_(this) {}
255*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)256*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
257*635a8641SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)258*635a8641SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {}
259*635a8641SAndroid Build Coastguard Worker 
OnChannelError()260*635a8641SAndroid Build Coastguard Worker   void OnChannelError() override { NOTREACHED(); }
261*635a8641SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)262*635a8641SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
263*635a8641SAndroid Build Coastguard Worker       const std::string& interface_name,
264*635a8641SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
265*635a8641SAndroid Build Coastguard Worker     CHECK_EQ(interface_name, IPC::mojom::TestStructPasser::Name_);
266*635a8641SAndroid Build Coastguard Worker     binding_.Bind(
267*635a8641SAndroid Build Coastguard Worker         IPC::mojom::TestStructPasserAssociatedRequest(std::move(handle)));
268*635a8641SAndroid Build Coastguard Worker   }
269*635a8641SAndroid Build Coastguard Worker 
270*635a8641SAndroid Build Coastguard Worker  private:
271*635a8641SAndroid Build Coastguard Worker   // IPC::mojom::TestStructPasser:
Pass(IPC::mojom::TestStructPtr)272*635a8641SAndroid Build Coastguard Worker   void Pass(IPC::mojom::TestStructPtr) override { NOTREACHED(); }
273*635a8641SAndroid Build Coastguard Worker 
274*635a8641SAndroid Build Coastguard Worker   mojo::AssociatedBinding<IPC::mojom::TestStructPasser> binding_;
275*635a8641SAndroid Build Coastguard Worker };
276*635a8641SAndroid Build Coastguard Worker 
277*635a8641SAndroid Build Coastguard Worker class ListenerThatExpectsNoError : public IPC::Listener {
278*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatExpectsNoError(base::OnceClosure connect_closure,base::OnceClosure quit_closure)279*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsNoError(base::OnceClosure connect_closure,
280*635a8641SAndroid Build Coastguard Worker                              base::OnceClosure quit_closure)
281*635a8641SAndroid Build Coastguard Worker       : connect_closure_(std::move(connect_closure)),
282*635a8641SAndroid Build Coastguard Worker         quit_closure_(std::move(quit_closure)) {}
283*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)284*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
285*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
286*635a8641SAndroid Build Coastguard Worker     std::string should_be_ok;
287*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(iter.ReadString(&should_be_ok));
288*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(should_be_ok, "OK");
289*635a8641SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
290*635a8641SAndroid Build Coastguard Worker     return true;
291*635a8641SAndroid Build Coastguard Worker   }
292*635a8641SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)293*635a8641SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
294*635a8641SAndroid Build Coastguard Worker     std::move(connect_closure_).Run();
295*635a8641SAndroid Build Coastguard Worker   }
296*635a8641SAndroid Build Coastguard Worker 
OnChannelError()297*635a8641SAndroid Build Coastguard Worker   void OnChannelError() override { NOTREACHED(); }
298*635a8641SAndroid Build Coastguard Worker 
299*635a8641SAndroid Build Coastguard Worker  private:
300*635a8641SAndroid Build Coastguard Worker   base::OnceClosure connect_closure_;
301*635a8641SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
302*635a8641SAndroid Build Coastguard Worker };
303*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoNoImplicitChanelClosureClient)304*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
305*635a8641SAndroid Build Coastguard Worker     IPCChannelMojoNoImplicitChanelClosureClient) {
306*635a8641SAndroid Build Coastguard Worker   base::RunLoop wait_to_connect_loop;
307*635a8641SAndroid Build Coastguard Worker   base::RunLoop wait_to_quit_loop;
308*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsNoError listener(wait_to_connect_loop.QuitClosure(),
309*635a8641SAndroid Build Coastguard Worker                                       wait_to_quit_loop.QuitClosure());
310*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
311*635a8641SAndroid Build Coastguard Worker   wait_to_connect_loop.Run();
312*635a8641SAndroid Build Coastguard Worker 
313*635a8641SAndroid Build Coastguard Worker   IPC::mojom::TestStructPasserAssociatedPtr passer;
314*635a8641SAndroid Build Coastguard Worker   channel()->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
315*635a8641SAndroid Build Coastguard Worker       &passer);
316*635a8641SAndroid Build Coastguard Worker 
317*635a8641SAndroid Build Coastguard Worker   // This avoids hitting DCHECKs in the serialization code meant to stop us from
318*635a8641SAndroid Build Coastguard Worker   // making such "mistakes" as the one we're about to make below.
319*635a8641SAndroid Build Coastguard Worker   mojo::internal::SerializationWarningObserverForTesting suppress_those_dchecks;
320*635a8641SAndroid Build Coastguard Worker 
321*635a8641SAndroid Build Coastguard Worker   // Send an invalid message. The TestStruct argument is not allowed to be null.
322*635a8641SAndroid Build Coastguard Worker   // This will elicit a validation error in the parent process, but should not
323*635a8641SAndroid Build Coastguard Worker   // actually disconnect the channel.
324*635a8641SAndroid Build Coastguard Worker   passer->Pass(nullptr);
325*635a8641SAndroid Build Coastguard Worker 
326*635a8641SAndroid Build Coastguard Worker   // Wait until the parent says it's OK to quit, so it has time to verify its
327*635a8641SAndroid Build Coastguard Worker   // expected behavior.
328*635a8641SAndroid Build Coastguard Worker   wait_to_quit_loop.Run();
329*635a8641SAndroid Build Coastguard Worker 
330*635a8641SAndroid Build Coastguard Worker   Close();
331*635a8641SAndroid Build Coastguard Worker }
332*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,NoImplicitChannelClosure)333*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, NoImplicitChannelClosure) {
334*635a8641SAndroid Build Coastguard Worker   // Verifies that OnChannelError is not invoked due to conditions other than
335*635a8641SAndroid Build Coastguard Worker   // peer closure (e.g. a malformed inbound message). Instead we should always
336*635a8641SAndroid Build Coastguard Worker   // be able to handle validation errors via Mojo bad message reporting.
337*635a8641SAndroid Build Coastguard Worker 
338*635a8641SAndroid Build Coastguard Worker   // NOTE: We can't create a RunLoop before Init() is called, but we have to set
339*635a8641SAndroid Build Coastguard Worker   // the default ProcessErrorCallback (which we want to reference the RunLoop)
340*635a8641SAndroid Build Coastguard Worker   // before Init() launches a child process. Hence the base::Optional here.
341*635a8641SAndroid Build Coastguard Worker   base::Optional<base::RunLoop> wait_for_error_loop;
342*635a8641SAndroid Build Coastguard Worker   bool process_error_received = false;
343*635a8641SAndroid Build Coastguard Worker   mojo::core::SetDefaultProcessErrorCallback(
344*635a8641SAndroid Build Coastguard Worker       base::BindLambdaForTesting([&](const std::string&) {
345*635a8641SAndroid Build Coastguard Worker         process_error_received = true;
346*635a8641SAndroid Build Coastguard Worker         wait_for_error_loop->Quit();
347*635a8641SAndroid Build Coastguard Worker       }));
348*635a8641SAndroid Build Coastguard Worker 
349*635a8641SAndroid Build Coastguard Worker   Init("IPCChannelMojoNoImplicitChanelClosureClient");
350*635a8641SAndroid Build Coastguard Worker 
351*635a8641SAndroid Build Coastguard Worker   wait_for_error_loop.emplace();
352*635a8641SAndroid Build Coastguard Worker   ListenerThatBindsATestStructPasser listener;
353*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
354*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
355*635a8641SAndroid Build Coastguard Worker 
356*635a8641SAndroid Build Coastguard Worker   wait_for_error_loop->Run();
357*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(process_error_received);
358*635a8641SAndroid Build Coastguard Worker 
359*635a8641SAndroid Build Coastguard Worker   // Tell the child it can quit and wait for it to shut down.
360*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsOK::SendOK(channel());
361*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
362*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
363*635a8641SAndroid Build Coastguard Worker }
364*635a8641SAndroid Build Coastguard Worker 
365*635a8641SAndroid Build Coastguard Worker struct TestingMessagePipe {
TestingMessagePipe__anon33c4f6f10111::TestingMessagePipe366*635a8641SAndroid Build Coastguard Worker   TestingMessagePipe() {
367*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
368*635a8641SAndroid Build Coastguard Worker   }
369*635a8641SAndroid Build Coastguard Worker 
370*635a8641SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle self;
371*635a8641SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle peer;
372*635a8641SAndroid Build Coastguard Worker };
373*635a8641SAndroid Build Coastguard Worker 
374*635a8641SAndroid Build Coastguard Worker class HandleSendingHelper {
375*635a8641SAndroid Build Coastguard Worker  public:
GetSendingFileContent()376*635a8641SAndroid Build Coastguard Worker   static std::string GetSendingFileContent() { return "Hello"; }
377*635a8641SAndroid Build Coastguard Worker 
WritePipe(IPC::Message * message,TestingMessagePipe * pipe)378*635a8641SAndroid Build Coastguard Worker   static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
379*635a8641SAndroid Build Coastguard Worker     std::string content = HandleSendingHelper::GetSendingFileContent();
380*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(MOJO_RESULT_OK,
381*635a8641SAndroid Build Coastguard Worker               mojo::WriteMessageRaw(pipe->self.get(), &content[0],
382*635a8641SAndroid Build Coastguard Worker                                     static_cast<uint32_t>(content.size()),
383*635a8641SAndroid Build Coastguard Worker                                     nullptr, 0, 0));
384*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
385*635a8641SAndroid Build Coastguard Worker         message, std::move(pipe->peer)));
386*635a8641SAndroid Build Coastguard Worker   }
387*635a8641SAndroid Build Coastguard Worker 
WritePipeThenSend(IPC::Sender * sender,TestingMessagePipe * pipe)388*635a8641SAndroid Build Coastguard Worker   static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
389*635a8641SAndroid Build Coastguard Worker     IPC::Message* message =
390*635a8641SAndroid Build Coastguard Worker         new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
391*635a8641SAndroid Build Coastguard Worker     WritePipe(message, pipe);
392*635a8641SAndroid Build Coastguard Worker     ASSERT_TRUE(sender->Send(message));
393*635a8641SAndroid Build Coastguard Worker   }
394*635a8641SAndroid Build Coastguard Worker 
ReadReceivedPipe(const IPC::Message & message,base::PickleIterator * iter)395*635a8641SAndroid Build Coastguard Worker   static void ReadReceivedPipe(const IPC::Message& message,
396*635a8641SAndroid Build Coastguard Worker                                base::PickleIterator* iter) {
397*635a8641SAndroid Build Coastguard Worker     mojo::ScopedMessagePipeHandle pipe;
398*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(
399*635a8641SAndroid Build Coastguard Worker         IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
400*635a8641SAndroid Build Coastguard Worker     std::vector<uint8_t> content;
401*635a8641SAndroid Build Coastguard Worker 
402*635a8641SAndroid Build Coastguard Worker     ASSERT_EQ(MOJO_RESULT_OK,
403*635a8641SAndroid Build Coastguard Worker               mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE));
404*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(MOJO_RESULT_OK,
405*635a8641SAndroid Build Coastguard Worker               mojo::ReadMessageRaw(pipe.get(), &content, nullptr, 0));
406*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(std::string(content.begin(), content.end()),
407*635a8641SAndroid Build Coastguard Worker               GetSendingFileContent());
408*635a8641SAndroid Build Coastguard Worker   }
409*635a8641SAndroid Build Coastguard Worker 
410*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
GetSendingFilePath(const base::FilePath & dir_path)411*635a8641SAndroid Build Coastguard Worker   static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
412*635a8641SAndroid Build Coastguard Worker     return dir_path.Append("ListenerThatExpectsFile.txt");
413*635a8641SAndroid Build Coastguard Worker   }
414*635a8641SAndroid Build Coastguard Worker 
WriteFile(IPC::Message * message,base::File & file)415*635a8641SAndroid Build Coastguard Worker   static void WriteFile(IPC::Message* message, base::File& file) {
416*635a8641SAndroid Build Coastguard Worker     std::string content = GetSendingFileContent();
417*635a8641SAndroid Build Coastguard Worker     file.WriteAtCurrentPos(content.data(), content.size());
418*635a8641SAndroid Build Coastguard Worker     file.Flush();
419*635a8641SAndroid Build Coastguard Worker     message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
420*635a8641SAndroid Build Coastguard Worker         base::ScopedFD(file.TakePlatformFile())));
421*635a8641SAndroid Build Coastguard Worker   }
422*635a8641SAndroid Build Coastguard Worker 
WriteFileThenSend(IPC::Sender * sender,base::File & file)423*635a8641SAndroid Build Coastguard Worker   static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
424*635a8641SAndroid Build Coastguard Worker     IPC::Message* message =
425*635a8641SAndroid Build Coastguard Worker         new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
426*635a8641SAndroid Build Coastguard Worker     WriteFile(message, file);
427*635a8641SAndroid Build Coastguard Worker     ASSERT_TRUE(sender->Send(message));
428*635a8641SAndroid Build Coastguard Worker   }
429*635a8641SAndroid Build Coastguard Worker 
WriteFileAndPipeThenSend(IPC::Sender * sender,base::File & file,TestingMessagePipe * pipe)430*635a8641SAndroid Build Coastguard Worker   static void WriteFileAndPipeThenSend(IPC::Sender* sender,
431*635a8641SAndroid Build Coastguard Worker                                        base::File& file,
432*635a8641SAndroid Build Coastguard Worker                                        TestingMessagePipe* pipe) {
433*635a8641SAndroid Build Coastguard Worker     IPC::Message* message =
434*635a8641SAndroid Build Coastguard Worker         new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
435*635a8641SAndroid Build Coastguard Worker     WriteFile(message, file);
436*635a8641SAndroid Build Coastguard Worker     WritePipe(message, pipe);
437*635a8641SAndroid Build Coastguard Worker     ASSERT_TRUE(sender->Send(message));
438*635a8641SAndroid Build Coastguard Worker   }
439*635a8641SAndroid Build Coastguard Worker 
ReadReceivedFile(const IPC::Message & message,base::PickleIterator * iter)440*635a8641SAndroid Build Coastguard Worker   static void ReadReceivedFile(const IPC::Message& message,
441*635a8641SAndroid Build Coastguard Worker                                base::PickleIterator* iter) {
442*635a8641SAndroid Build Coastguard Worker     scoped_refptr<base::Pickle::Attachment> attachment;
443*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
444*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(
445*635a8641SAndroid Build Coastguard Worker         IPC::MessageAttachment::Type::PLATFORM_FILE,
446*635a8641SAndroid Build Coastguard Worker         static_cast<IPC::MessageAttachment*>(attachment.get())->GetType());
447*635a8641SAndroid Build Coastguard Worker     base::File file(
448*635a8641SAndroid Build Coastguard Worker         static_cast<IPC::internal::PlatformFileAttachment*>(attachment.get())
449*635a8641SAndroid Build Coastguard Worker             ->TakePlatformFile());
450*635a8641SAndroid Build Coastguard Worker     std::string content(GetSendingFileContent().size(), ' ');
451*635a8641SAndroid Build Coastguard Worker     file.Read(0, &content[0], content.size());
452*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(content, GetSendingFileContent());
453*635a8641SAndroid Build Coastguard Worker   }
454*635a8641SAndroid Build Coastguard Worker #endif
455*635a8641SAndroid Build Coastguard Worker };
456*635a8641SAndroid Build Coastguard Worker 
457*635a8641SAndroid Build Coastguard Worker class ListenerThatExpectsMessagePipe : public TestListenerBase {
458*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatExpectsMessagePipe(base::OnceClosure quit_closure)459*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsMessagePipe(base::OnceClosure quit_closure)
460*635a8641SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
461*635a8641SAndroid Build Coastguard Worker 
462*635a8641SAndroid Build Coastguard Worker   ~ListenerThatExpectsMessagePipe() override = default;
463*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)464*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
465*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
466*635a8641SAndroid Build Coastguard Worker     HandleSendingHelper::ReadReceivedPipe(message, &iter);
467*635a8641SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
468*635a8641SAndroid Build Coastguard Worker     return true;
469*635a8641SAndroid Build Coastguard Worker   }
470*635a8641SAndroid Build Coastguard Worker };
471*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendMessagePipe)472*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendMessagePipe) {
473*635a8641SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestSendMessagePipeClient");
474*635a8641SAndroid Build Coastguard Worker 
475*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
476*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
477*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
478*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
479*635a8641SAndroid Build Coastguard Worker 
480*635a8641SAndroid Build Coastguard Worker   TestingMessagePipe pipe;
481*635a8641SAndroid Build Coastguard Worker   HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
482*635a8641SAndroid Build Coastguard Worker 
483*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
484*635a8641SAndroid Build Coastguard Worker   channel()->Close();
485*635a8641SAndroid Build Coastguard Worker 
486*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
487*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
488*635a8641SAndroid Build Coastguard Worker }
489*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient)490*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient) {
491*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
492*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsMessagePipe listener(run_loop.QuitClosure());
493*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
494*635a8641SAndroid Build Coastguard Worker   listener.set_sender(channel());
495*635a8641SAndroid Build Coastguard Worker 
496*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
497*635a8641SAndroid Build Coastguard Worker 
498*635a8641SAndroid Build Coastguard Worker   Close();
499*635a8641SAndroid Build Coastguard Worker }
500*635a8641SAndroid Build Coastguard Worker 
ReadOK(mojo::MessagePipeHandle pipe)501*635a8641SAndroid Build Coastguard Worker void ReadOK(mojo::MessagePipeHandle pipe) {
502*635a8641SAndroid Build Coastguard Worker   std::vector<uint8_t> should_be_ok;
503*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE));
504*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(MOJO_RESULT_OK,
505*635a8641SAndroid Build Coastguard Worker            mojo::ReadMessageRaw(pipe, &should_be_ok, nullptr, 0));
506*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("OK", std::string(should_be_ok.begin(), should_be_ok.end()));
507*635a8641SAndroid Build Coastguard Worker }
508*635a8641SAndroid Build Coastguard Worker 
WriteOK(mojo::MessagePipeHandle pipe)509*635a8641SAndroid Build Coastguard Worker void WriteOK(mojo::MessagePipeHandle pipe) {
510*635a8641SAndroid Build Coastguard Worker   std::string ok("OK");
511*635a8641SAndroid Build Coastguard Worker   CHECK_EQ(MOJO_RESULT_OK,
512*635a8641SAndroid Build Coastguard Worker            mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
513*635a8641SAndroid Build Coastguard Worker                                  nullptr, 0, 0));
514*635a8641SAndroid Build Coastguard Worker }
515*635a8641SAndroid Build Coastguard Worker 
516*635a8641SAndroid Build Coastguard Worker class ListenerThatExpectsMessagePipeUsingParamTrait : public TestListenerBase {
517*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatExpectsMessagePipeUsingParamTrait(base::OnceClosure quit_closure,bool receiving_valid)518*635a8641SAndroid Build Coastguard Worker   explicit ListenerThatExpectsMessagePipeUsingParamTrait(
519*635a8641SAndroid Build Coastguard Worker       base::OnceClosure quit_closure,
520*635a8641SAndroid Build Coastguard Worker       bool receiving_valid)
521*635a8641SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)),
522*635a8641SAndroid Build Coastguard Worker         receiving_valid_(receiving_valid) {}
523*635a8641SAndroid Build Coastguard Worker 
524*635a8641SAndroid Build Coastguard Worker   ~ListenerThatExpectsMessagePipeUsingParamTrait() override = default;
525*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)526*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
527*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
528*635a8641SAndroid Build Coastguard Worker     mojo::MessagePipeHandle handle;
529*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
530*635a8641SAndroid Build Coastguard Worker                                                                 &handle));
531*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(handle.is_valid(), receiving_valid_);
532*635a8641SAndroid Build Coastguard Worker     if (receiving_valid_) {
533*635a8641SAndroid Build Coastguard Worker       ReadOK(handle);
534*635a8641SAndroid Build Coastguard Worker       MojoClose(handle.value());
535*635a8641SAndroid Build Coastguard Worker     }
536*635a8641SAndroid Build Coastguard Worker 
537*635a8641SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
538*635a8641SAndroid Build Coastguard Worker     return true;
539*635a8641SAndroid Build Coastguard Worker   }
540*635a8641SAndroid Build Coastguard Worker 
541*635a8641SAndroid Build Coastguard Worker  private:
542*635a8641SAndroid Build Coastguard Worker   bool receiving_valid_;
543*635a8641SAndroid Build Coastguard Worker };
544*635a8641SAndroid Build Coastguard Worker 
545*635a8641SAndroid Build Coastguard Worker class ParamTraitMessagePipeClient : public IpcChannelMojoTestClient {
546*635a8641SAndroid Build Coastguard Worker  public:
RunTest(bool receiving_valid_handle)547*635a8641SAndroid Build Coastguard Worker   void RunTest(bool receiving_valid_handle) {
548*635a8641SAndroid Build Coastguard Worker     base::RunLoop run_loop;
549*635a8641SAndroid Build Coastguard Worker     ListenerThatExpectsMessagePipeUsingParamTrait listener(
550*635a8641SAndroid Build Coastguard Worker         run_loop.QuitClosure(), receiving_valid_handle);
551*635a8641SAndroid Build Coastguard Worker     Connect(&listener);
552*635a8641SAndroid Build Coastguard Worker     listener.set_sender(channel());
553*635a8641SAndroid Build Coastguard Worker 
554*635a8641SAndroid Build Coastguard Worker     run_loop.Run();
555*635a8641SAndroid Build Coastguard Worker 
556*635a8641SAndroid Build Coastguard Worker     Close();
557*635a8641SAndroid Build Coastguard Worker   }
558*635a8641SAndroid Build Coastguard Worker };
559*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,ParamTraitValidMessagePipe)560*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
561*635a8641SAndroid Build Coastguard Worker   Init("ParamTraitValidMessagePipeClient");
562*635a8641SAndroid Build Coastguard Worker 
563*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
564*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
565*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
566*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
567*635a8641SAndroid Build Coastguard Worker 
568*635a8641SAndroid Build Coastguard Worker   TestingMessagePipe pipe;
569*635a8641SAndroid Build Coastguard Worker 
570*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<IPC::Message> message(new IPC::Message());
571*635a8641SAndroid Build Coastguard Worker   IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
572*635a8641SAndroid Build Coastguard Worker                                                    pipe.peer.release());
573*635a8641SAndroid Build Coastguard Worker   WriteOK(pipe.self.get());
574*635a8641SAndroid Build Coastguard Worker 
575*635a8641SAndroid Build Coastguard Worker   channel()->Send(message.release());
576*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
577*635a8641SAndroid Build Coastguard Worker   channel()->Close();
578*635a8641SAndroid Build Coastguard Worker 
579*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
580*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
581*635a8641SAndroid Build Coastguard Worker }
582*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ParamTraitValidMessagePipeClient,ParamTraitMessagePipeClient)583*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
584*635a8641SAndroid Build Coastguard Worker     ParamTraitValidMessagePipeClient,
585*635a8641SAndroid Build Coastguard Worker     ParamTraitMessagePipeClient) {
586*635a8641SAndroid Build Coastguard Worker   RunTest(true);
587*635a8641SAndroid Build Coastguard Worker }
588*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,ParamTraitInvalidMessagePipe)589*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
590*635a8641SAndroid Build Coastguard Worker   Init("ParamTraitInvalidMessagePipeClient");
591*635a8641SAndroid Build Coastguard Worker 
592*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
593*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
594*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
595*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
596*635a8641SAndroid Build Coastguard Worker 
597*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipeHandle invalid_handle;
598*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<IPC::Message> message(new IPC::Message());
599*635a8641SAndroid Build Coastguard Worker   IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
600*635a8641SAndroid Build Coastguard Worker                                                    invalid_handle);
601*635a8641SAndroid Build Coastguard Worker 
602*635a8641SAndroid Build Coastguard Worker   channel()->Send(message.release());
603*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
604*635a8641SAndroid Build Coastguard Worker   channel()->Close();
605*635a8641SAndroid Build Coastguard Worker 
606*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
607*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
608*635a8641SAndroid Build Coastguard Worker }
609*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ParamTraitInvalidMessagePipeClient,ParamTraitMessagePipeClient)610*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
611*635a8641SAndroid Build Coastguard Worker     ParamTraitInvalidMessagePipeClient,
612*635a8641SAndroid Build Coastguard Worker     ParamTraitMessagePipeClient) {
613*635a8641SAndroid Build Coastguard Worker   RunTest(false);
614*635a8641SAndroid Build Coastguard Worker }
615*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendFailAfterClose)616*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
617*635a8641SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestSendOkClient");
618*635a8641SAndroid Build Coastguard Worker 
619*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
620*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
621*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
622*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
623*635a8641SAndroid Build Coastguard Worker 
624*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
625*635a8641SAndroid Build Coastguard Worker   channel()->Close();
626*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(channel()->Send(new IPC::Message()));
627*635a8641SAndroid Build Coastguard Worker 
628*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
629*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
630*635a8641SAndroid Build Coastguard Worker }
631*635a8641SAndroid Build Coastguard Worker 
632*635a8641SAndroid Build Coastguard Worker class ListenerSendingOneOk : public TestListenerBase {
633*635a8641SAndroid Build Coastguard Worker  public:
ListenerSendingOneOk(base::OnceClosure quit_closure)634*635a8641SAndroid Build Coastguard Worker   ListenerSendingOneOk(base::OnceClosure quit_closure)
635*635a8641SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
636*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)637*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
638*635a8641SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)639*635a8641SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
640*635a8641SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
641*635a8641SAndroid Build Coastguard Worker     RunQuitClosure();
642*635a8641SAndroid Build Coastguard Worker   }
643*635a8641SAndroid Build Coastguard Worker };
644*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient)645*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient) {
646*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
647*635a8641SAndroid Build Coastguard Worker   ListenerSendingOneOk listener(run_loop.QuitClosure());
648*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
649*635a8641SAndroid Build Coastguard Worker   listener.set_sender(channel());
650*635a8641SAndroid Build Coastguard Worker 
651*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
652*635a8641SAndroid Build Coastguard Worker 
653*635a8641SAndroid Build Coastguard Worker   Close();
654*635a8641SAndroid Build Coastguard Worker }
655*635a8641SAndroid Build Coastguard Worker 
656*635a8641SAndroid Build Coastguard Worker class ListenerWithSimpleAssociatedInterface
657*635a8641SAndroid Build Coastguard Worker     : public IPC::Listener,
658*635a8641SAndroid Build Coastguard Worker       public IPC::mojom::SimpleTestDriver {
659*635a8641SAndroid Build Coastguard Worker  public:
660*635a8641SAndroid Build Coastguard Worker   static const int kNumMessages;
661*635a8641SAndroid Build Coastguard Worker 
ListenerWithSimpleAssociatedInterface(base::OnceClosure quit_closure)662*635a8641SAndroid Build Coastguard Worker   explicit ListenerWithSimpleAssociatedInterface(base::OnceClosure quit_closure)
663*635a8641SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)), binding_(this) {}
664*635a8641SAndroid Build Coastguard Worker 
665*635a8641SAndroid Build Coastguard Worker   ~ListenerWithSimpleAssociatedInterface() override = default;
666*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)667*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
668*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
669*635a8641SAndroid Build Coastguard Worker     int32_t should_be_expected;
670*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(iter.ReadInt(&should_be_expected));
671*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(should_be_expected, next_expected_value_);
672*635a8641SAndroid Build Coastguard Worker     num_messages_received_++;
673*635a8641SAndroid Build Coastguard Worker     return true;
674*635a8641SAndroid Build Coastguard Worker   }
675*635a8641SAndroid Build Coastguard Worker 
OnChannelError()676*635a8641SAndroid Build Coastguard Worker   void OnChannelError() override { CHECK(!quit_closure_); }
677*635a8641SAndroid Build Coastguard Worker 
RegisterInterfaceFactory(IPC::Channel * channel)678*635a8641SAndroid Build Coastguard Worker   void RegisterInterfaceFactory(IPC::Channel* channel) {
679*635a8641SAndroid Build Coastguard Worker     channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
680*635a8641SAndroid Build Coastguard Worker         base::BindRepeating(&ListenerWithSimpleAssociatedInterface::BindRequest,
681*635a8641SAndroid Build Coastguard Worker                             base::Unretained(this)));
682*635a8641SAndroid Build Coastguard Worker   }
683*635a8641SAndroid Build Coastguard Worker 
684*635a8641SAndroid Build Coastguard Worker  private:
685*635a8641SAndroid Build Coastguard Worker   // IPC::mojom::SimpleTestDriver:
ExpectValue(int32_t value)686*635a8641SAndroid Build Coastguard Worker   void ExpectValue(int32_t value) override {
687*635a8641SAndroid Build Coastguard Worker     next_expected_value_ = value;
688*635a8641SAndroid Build Coastguard Worker   }
689*635a8641SAndroid Build Coastguard Worker 
GetExpectedValue(GetExpectedValueCallback callback)690*635a8641SAndroid Build Coastguard Worker   void GetExpectedValue(GetExpectedValueCallback callback) override {
691*635a8641SAndroid Build Coastguard Worker     NOTREACHED();
692*635a8641SAndroid Build Coastguard Worker   }
693*635a8641SAndroid Build Coastguard Worker 
RequestValue(RequestValueCallback callback)694*635a8641SAndroid Build Coastguard Worker   void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
695*635a8641SAndroid Build Coastguard Worker 
RequestQuit(RequestQuitCallback callback)696*635a8641SAndroid Build Coastguard Worker   void RequestQuit(RequestQuitCallback callback) override {
697*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(kNumMessages, num_messages_received_);
698*635a8641SAndroid Build Coastguard Worker     std::move(callback).Run();
699*635a8641SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
700*635a8641SAndroid Build Coastguard Worker   }
701*635a8641SAndroid Build Coastguard Worker 
BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request)702*635a8641SAndroid Build Coastguard Worker   void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
703*635a8641SAndroid Build Coastguard Worker     DCHECK(!binding_.is_bound());
704*635a8641SAndroid Build Coastguard Worker     binding_.Bind(std::move(request));
705*635a8641SAndroid Build Coastguard Worker   }
706*635a8641SAndroid Build Coastguard Worker 
707*635a8641SAndroid Build Coastguard Worker   int32_t next_expected_value_ = 0;
708*635a8641SAndroid Build Coastguard Worker   int num_messages_received_ = 0;
709*635a8641SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
710*635a8641SAndroid Build Coastguard Worker 
711*635a8641SAndroid Build Coastguard Worker   mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
712*635a8641SAndroid Build Coastguard Worker };
713*635a8641SAndroid Build Coastguard Worker 
714*635a8641SAndroid Build Coastguard Worker const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
715*635a8641SAndroid Build Coastguard Worker 
716*635a8641SAndroid Build Coastguard Worker class ListenerSendingAssociatedMessages : public IPC::Listener {
717*635a8641SAndroid Build Coastguard Worker  public:
ListenerSendingAssociatedMessages(base::OnceClosure quit_closure)718*635a8641SAndroid Build Coastguard Worker   explicit ListenerSendingAssociatedMessages(base::OnceClosure quit_closure)
719*635a8641SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)) {}
720*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)721*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
722*635a8641SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)723*635a8641SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
724*635a8641SAndroid Build Coastguard Worker     DCHECK(channel_);
725*635a8641SAndroid Build Coastguard Worker     channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
726*635a8641SAndroid Build Coastguard Worker         &driver_);
727*635a8641SAndroid Build Coastguard Worker 
728*635a8641SAndroid Build Coastguard Worker     // Send a bunch of interleaved messages, alternating between the associated
729*635a8641SAndroid Build Coastguard Worker     // interface and a legacy IPC::Message.
730*635a8641SAndroid Build Coastguard Worker     for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
731*635a8641SAndroid Build Coastguard Worker          ++i) {
732*635a8641SAndroid Build Coastguard Worker       driver_->ExpectValue(i);
733*635a8641SAndroid Build Coastguard Worker       SendValue(channel_, i);
734*635a8641SAndroid Build Coastguard Worker     }
735*635a8641SAndroid Build Coastguard Worker     driver_->RequestQuit(base::BindOnce(
736*635a8641SAndroid Build Coastguard Worker         &ListenerSendingAssociatedMessages::OnQuitAck, base::Unretained(this)));
737*635a8641SAndroid Build Coastguard Worker   }
738*635a8641SAndroid Build Coastguard Worker 
set_channel(IPC::Channel * channel)739*635a8641SAndroid Build Coastguard Worker   void set_channel(IPC::Channel* channel) { channel_ = channel; }
740*635a8641SAndroid Build Coastguard Worker 
741*635a8641SAndroid Build Coastguard Worker  private:
OnQuitAck()742*635a8641SAndroid Build Coastguard Worker   void OnQuitAck() { std::move(quit_closure_).Run(); }
743*635a8641SAndroid Build Coastguard Worker 
744*635a8641SAndroid Build Coastguard Worker   IPC::Channel* channel_ = nullptr;
745*635a8641SAndroid Build Coastguard Worker   IPC::mojom::SimpleTestDriverAssociatedPtr driver_;
746*635a8641SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
747*635a8641SAndroid Build Coastguard Worker };
748*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SimpleAssociatedInterface)749*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
750*635a8641SAndroid Build Coastguard Worker   Init("SimpleAssociatedInterfaceClient");
751*635a8641SAndroid Build Coastguard Worker 
752*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
753*635a8641SAndroid Build Coastguard Worker   ListenerWithSimpleAssociatedInterface listener(run_loop.QuitClosure());
754*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
755*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
756*635a8641SAndroid Build Coastguard Worker 
757*635a8641SAndroid Build Coastguard Worker   listener.RegisterInterfaceFactory(channel());
758*635a8641SAndroid Build Coastguard Worker 
759*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
760*635a8641SAndroid Build Coastguard Worker   channel()->Close();
761*635a8641SAndroid Build Coastguard Worker 
762*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
763*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
764*635a8641SAndroid Build Coastguard Worker }
765*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient)766*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient) {
767*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
768*635a8641SAndroid Build Coastguard Worker   ListenerSendingAssociatedMessages listener(run_loop.QuitClosure());
769*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
770*635a8641SAndroid Build Coastguard Worker   listener.set_channel(channel());
771*635a8641SAndroid Build Coastguard Worker 
772*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
773*635a8641SAndroid Build Coastguard Worker 
774*635a8641SAndroid Build Coastguard Worker   Close();
775*635a8641SAndroid Build Coastguard Worker }
776*635a8641SAndroid Build Coastguard Worker 
777*635a8641SAndroid Build Coastguard Worker class ChannelProxyRunner {
778*635a8641SAndroid Build Coastguard Worker  public:
ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,bool for_server)779*635a8641SAndroid Build Coastguard Worker   ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,
780*635a8641SAndroid Build Coastguard Worker                      bool for_server)
781*635a8641SAndroid Build Coastguard Worker       : for_server_(for_server),
782*635a8641SAndroid Build Coastguard Worker         handle_(std::move(handle)),
783*635a8641SAndroid Build Coastguard Worker         io_thread_("ChannelProxyRunner IO thread"),
784*635a8641SAndroid Build Coastguard Worker         never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
785*635a8641SAndroid Build Coastguard Worker                         base::WaitableEvent::InitialState::NOT_SIGNALED) {
786*635a8641SAndroid Build Coastguard Worker   }
787*635a8641SAndroid Build Coastguard Worker 
CreateProxy(IPC::Listener * listener)788*635a8641SAndroid Build Coastguard Worker   void CreateProxy(IPC::Listener* listener) {
789*635a8641SAndroid Build Coastguard Worker     io_thread_.StartWithOptions(
790*635a8641SAndroid Build Coastguard Worker         base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
791*635a8641SAndroid Build Coastguard Worker     proxy_ = IPC::SyncChannel::Create(listener, io_thread_.task_runner(),
792*635a8641SAndroid Build Coastguard Worker                                       base::ThreadTaskRunnerHandle::Get(),
793*635a8641SAndroid Build Coastguard Worker                                       &never_signaled_);
794*635a8641SAndroid Build Coastguard Worker   }
795*635a8641SAndroid Build Coastguard Worker 
RunProxy()796*635a8641SAndroid Build Coastguard Worker   void RunProxy() {
797*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<IPC::ChannelFactory> factory;
798*635a8641SAndroid Build Coastguard Worker     if (for_server_) {
799*635a8641SAndroid Build Coastguard Worker       factory = IPC::ChannelMojo::CreateServerFactory(
800*635a8641SAndroid Build Coastguard Worker           std::move(handle_), io_thread_.task_runner(),
801*635a8641SAndroid Build Coastguard Worker           base::ThreadTaskRunnerHandle::Get());
802*635a8641SAndroid Build Coastguard Worker     } else {
803*635a8641SAndroid Build Coastguard Worker       factory = IPC::ChannelMojo::CreateClientFactory(
804*635a8641SAndroid Build Coastguard Worker           std::move(handle_), io_thread_.task_runner(),
805*635a8641SAndroid Build Coastguard Worker           base::ThreadTaskRunnerHandle::Get());
806*635a8641SAndroid Build Coastguard Worker     }
807*635a8641SAndroid Build Coastguard Worker     proxy_->Init(std::move(factory), true);
808*635a8641SAndroid Build Coastguard Worker   }
809*635a8641SAndroid Build Coastguard Worker 
proxy()810*635a8641SAndroid Build Coastguard Worker   IPC::ChannelProxy* proxy() { return proxy_.get(); }
811*635a8641SAndroid Build Coastguard Worker 
812*635a8641SAndroid Build Coastguard Worker  private:
813*635a8641SAndroid Build Coastguard Worker   const bool for_server_;
814*635a8641SAndroid Build Coastguard Worker 
815*635a8641SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle handle_;
816*635a8641SAndroid Build Coastguard Worker   base::Thread io_thread_;
817*635a8641SAndroid Build Coastguard Worker   base::WaitableEvent never_signaled_;
818*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<IPC::ChannelProxy> proxy_;
819*635a8641SAndroid Build Coastguard Worker 
820*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ChannelProxyRunner);
821*635a8641SAndroid Build Coastguard Worker };
822*635a8641SAndroid Build Coastguard Worker 
823*635a8641SAndroid Build Coastguard Worker class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase {
824*635a8641SAndroid Build Coastguard Worker  public:
Init(const std::string & client_name)825*635a8641SAndroid Build Coastguard Worker   void Init(const std::string& client_name) {
826*635a8641SAndroid Build Coastguard Worker     IPCChannelMojoTestBase::Init(client_name);
827*635a8641SAndroid Build Coastguard Worker     runner_.reset(new ChannelProxyRunner(TakeHandle(), true));
828*635a8641SAndroid Build Coastguard Worker   }
CreateProxy(IPC::Listener * listener)829*635a8641SAndroid Build Coastguard Worker   void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
RunProxy()830*635a8641SAndroid Build Coastguard Worker   void RunProxy() {
831*635a8641SAndroid Build Coastguard Worker     runner_->RunProxy();
832*635a8641SAndroid Build Coastguard Worker   }
DestroyProxy()833*635a8641SAndroid Build Coastguard Worker   void DestroyProxy() {
834*635a8641SAndroid Build Coastguard Worker     runner_.reset();
835*635a8641SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
836*635a8641SAndroid Build Coastguard Worker   }
837*635a8641SAndroid Build Coastguard Worker 
proxy()838*635a8641SAndroid Build Coastguard Worker   IPC::ChannelProxy* proxy() { return runner_->proxy(); }
839*635a8641SAndroid Build Coastguard Worker 
840*635a8641SAndroid Build Coastguard Worker  private:
841*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<ChannelProxyRunner> runner_;
842*635a8641SAndroid Build Coastguard Worker };
843*635a8641SAndroid Build Coastguard Worker 
844*635a8641SAndroid Build Coastguard Worker class ListenerWithSimpleProxyAssociatedInterface
845*635a8641SAndroid Build Coastguard Worker     : public IPC::Listener,
846*635a8641SAndroid Build Coastguard Worker       public IPC::mojom::SimpleTestDriver {
847*635a8641SAndroid Build Coastguard Worker  public:
848*635a8641SAndroid Build Coastguard Worker   static const int kNumMessages;
849*635a8641SAndroid Build Coastguard Worker 
ListenerWithSimpleProxyAssociatedInterface(base::OnceClosure quit_closure)850*635a8641SAndroid Build Coastguard Worker   explicit ListenerWithSimpleProxyAssociatedInterface(
851*635a8641SAndroid Build Coastguard Worker       base::OnceClosure quit_closure)
852*635a8641SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)), binding_(this) {}
853*635a8641SAndroid Build Coastguard Worker 
854*635a8641SAndroid Build Coastguard Worker   ~ListenerWithSimpleProxyAssociatedInterface() override = default;
855*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)856*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
857*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
858*635a8641SAndroid Build Coastguard Worker     int32_t should_be_expected;
859*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(iter.ReadInt(&should_be_expected));
860*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(should_be_expected, next_expected_value_);
861*635a8641SAndroid Build Coastguard Worker     num_messages_received_++;
862*635a8641SAndroid Build Coastguard Worker     return true;
863*635a8641SAndroid Build Coastguard Worker   }
864*635a8641SAndroid Build Coastguard Worker 
OnChannelError()865*635a8641SAndroid Build Coastguard Worker   void OnChannelError() override { CHECK(!quit_closure_); }
866*635a8641SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)867*635a8641SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
868*635a8641SAndroid Build Coastguard Worker       const std::string& interface_name,
869*635a8641SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
870*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
871*635a8641SAndroid Build Coastguard Worker     binding_.Bind(
872*635a8641SAndroid Build Coastguard Worker         IPC::mojom::SimpleTestDriverAssociatedRequest(std::move(handle)));
873*635a8641SAndroid Build Coastguard Worker   }
874*635a8641SAndroid Build Coastguard Worker 
received_all_messages() const875*635a8641SAndroid Build Coastguard Worker   bool received_all_messages() const {
876*635a8641SAndroid Build Coastguard Worker     return num_messages_received_ == kNumMessages && !quit_closure_;
877*635a8641SAndroid Build Coastguard Worker   }
878*635a8641SAndroid Build Coastguard Worker 
879*635a8641SAndroid Build Coastguard Worker  private:
880*635a8641SAndroid Build Coastguard Worker   // IPC::mojom::SimpleTestDriver:
ExpectValue(int32_t value)881*635a8641SAndroid Build Coastguard Worker   void ExpectValue(int32_t value) override {
882*635a8641SAndroid Build Coastguard Worker     next_expected_value_ = value;
883*635a8641SAndroid Build Coastguard Worker   }
884*635a8641SAndroid Build Coastguard Worker 
GetExpectedValue(GetExpectedValueCallback callback)885*635a8641SAndroid Build Coastguard Worker   void GetExpectedValue(GetExpectedValueCallback callback) override {
886*635a8641SAndroid Build Coastguard Worker     std::move(callback).Run(next_expected_value_);
887*635a8641SAndroid Build Coastguard Worker   }
888*635a8641SAndroid Build Coastguard Worker 
RequestValue(RequestValueCallback callback)889*635a8641SAndroid Build Coastguard Worker   void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
890*635a8641SAndroid Build Coastguard Worker 
RequestQuit(RequestQuitCallback callback)891*635a8641SAndroid Build Coastguard Worker   void RequestQuit(RequestQuitCallback callback) override {
892*635a8641SAndroid Build Coastguard Worker     std::move(callback).Run();
893*635a8641SAndroid Build Coastguard Worker     binding_.Close();
894*635a8641SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
895*635a8641SAndroid Build Coastguard Worker   }
896*635a8641SAndroid Build Coastguard Worker 
BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request)897*635a8641SAndroid Build Coastguard Worker   void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
898*635a8641SAndroid Build Coastguard Worker     DCHECK(!binding_.is_bound());
899*635a8641SAndroid Build Coastguard Worker     binding_.Bind(std::move(request));
900*635a8641SAndroid Build Coastguard Worker   }
901*635a8641SAndroid Build Coastguard Worker 
902*635a8641SAndroid Build Coastguard Worker   int32_t next_expected_value_ = 0;
903*635a8641SAndroid Build Coastguard Worker   int num_messages_received_ = 0;
904*635a8641SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
905*635a8641SAndroid Build Coastguard Worker 
906*635a8641SAndroid Build Coastguard Worker   mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
907*635a8641SAndroid Build Coastguard Worker };
908*635a8641SAndroid Build Coastguard Worker 
909*635a8641SAndroid Build Coastguard Worker const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000;
910*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,ProxyThreadAssociatedInterface)911*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) {
912*635a8641SAndroid Build Coastguard Worker   Init("ProxyThreadAssociatedInterfaceClient");
913*635a8641SAndroid Build Coastguard Worker 
914*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
915*635a8641SAndroid Build Coastguard Worker   ListenerWithSimpleProxyAssociatedInterface listener(run_loop.QuitClosure());
916*635a8641SAndroid Build Coastguard Worker   CreateProxy(&listener);
917*635a8641SAndroid Build Coastguard Worker   RunProxy();
918*635a8641SAndroid Build Coastguard Worker 
919*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
920*635a8641SAndroid Build Coastguard Worker 
921*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
922*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.received_all_messages());
923*635a8641SAndroid Build Coastguard Worker 
924*635a8641SAndroid Build Coastguard Worker   DestroyProxy();
925*635a8641SAndroid Build Coastguard Worker }
926*635a8641SAndroid Build Coastguard Worker 
927*635a8641SAndroid Build Coastguard Worker class ChannelProxyClient {
928*635a8641SAndroid Build Coastguard Worker  public:
Init(mojo::ScopedMessagePipeHandle handle)929*635a8641SAndroid Build Coastguard Worker   void Init(mojo::ScopedMessagePipeHandle handle) {
930*635a8641SAndroid Build Coastguard Worker     runner_.reset(new ChannelProxyRunner(std::move(handle), false));
931*635a8641SAndroid Build Coastguard Worker   }
932*635a8641SAndroid Build Coastguard Worker 
CreateProxy(IPC::Listener * listener)933*635a8641SAndroid Build Coastguard Worker   void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
934*635a8641SAndroid Build Coastguard Worker 
RunProxy()935*635a8641SAndroid Build Coastguard Worker   void RunProxy() { runner_->RunProxy(); }
936*635a8641SAndroid Build Coastguard Worker 
DestroyProxy()937*635a8641SAndroid Build Coastguard Worker   void DestroyProxy() {
938*635a8641SAndroid Build Coastguard Worker     runner_.reset();
939*635a8641SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
940*635a8641SAndroid Build Coastguard Worker   }
941*635a8641SAndroid Build Coastguard Worker 
RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver * driver)942*635a8641SAndroid Build Coastguard Worker   void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) {
943*635a8641SAndroid Build Coastguard Worker     base::RunLoop loop;
944*635a8641SAndroid Build Coastguard Worker     driver->RequestQuit(loop.QuitClosure());
945*635a8641SAndroid Build Coastguard Worker     loop.Run();
946*635a8641SAndroid Build Coastguard Worker   }
947*635a8641SAndroid Build Coastguard Worker 
proxy()948*635a8641SAndroid Build Coastguard Worker   IPC::ChannelProxy* proxy() { return runner_->proxy(); }
949*635a8641SAndroid Build Coastguard Worker 
950*635a8641SAndroid Build Coastguard Worker  private:
951*635a8641SAndroid Build Coastguard Worker   base::MessageLoop message_loop_;
952*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<ChannelProxyRunner> runner_;
953*635a8641SAndroid Build Coastguard Worker };
954*635a8641SAndroid Build Coastguard Worker 
955*635a8641SAndroid Build Coastguard Worker class DummyListener : public IPC::Listener {
956*635a8641SAndroid Build Coastguard Worker  public:
957*635a8641SAndroid Build Coastguard Worker   // IPC::Listener
OnMessageReceived(const IPC::Message & message)958*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
959*635a8641SAndroid Build Coastguard Worker };
960*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ProxyThreadAssociatedInterfaceClient,ChannelProxyClient)961*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
962*635a8641SAndroid Build Coastguard Worker     ProxyThreadAssociatedInterfaceClient,
963*635a8641SAndroid Build Coastguard Worker     ChannelProxyClient) {
964*635a8641SAndroid Build Coastguard Worker   DummyListener listener;
965*635a8641SAndroid Build Coastguard Worker   CreateProxy(&listener);
966*635a8641SAndroid Build Coastguard Worker   RunProxy();
967*635a8641SAndroid Build Coastguard Worker 
968*635a8641SAndroid Build Coastguard Worker   // Send a bunch of interleaved messages, alternating between the associated
969*635a8641SAndroid Build Coastguard Worker   // interface and a legacy IPC::Message.
970*635a8641SAndroid Build Coastguard Worker   IPC::mojom::SimpleTestDriverAssociatedPtr driver;
971*635a8641SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(&driver);
972*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages;
973*635a8641SAndroid Build Coastguard Worker        ++i) {
974*635a8641SAndroid Build Coastguard Worker     driver->ExpectValue(i);
975*635a8641SAndroid Build Coastguard Worker     SendValue(proxy(), i);
976*635a8641SAndroid Build Coastguard Worker   }
977*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
978*635a8641SAndroid Build Coastguard Worker   driver->RequestQuit(run_loop.QuitClosure());
979*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
980*635a8641SAndroid Build Coastguard Worker 
981*635a8641SAndroid Build Coastguard Worker   DestroyProxy();
982*635a8641SAndroid Build Coastguard Worker }
983*635a8641SAndroid Build Coastguard Worker 
984*635a8641SAndroid Build Coastguard Worker class ListenerWithIndirectProxyAssociatedInterface
985*635a8641SAndroid Build Coastguard Worker     : public IPC::Listener,
986*635a8641SAndroid Build Coastguard Worker       public IPC::mojom::IndirectTestDriver,
987*635a8641SAndroid Build Coastguard Worker       public IPC::mojom::PingReceiver {
988*635a8641SAndroid Build Coastguard Worker  public:
ListenerWithIndirectProxyAssociatedInterface()989*635a8641SAndroid Build Coastguard Worker   ListenerWithIndirectProxyAssociatedInterface()
990*635a8641SAndroid Build Coastguard Worker       : driver_binding_(this), ping_receiver_binding_(this) {}
991*635a8641SAndroid Build Coastguard Worker   ~ListenerWithIndirectProxyAssociatedInterface() override = default;
992*635a8641SAndroid Build Coastguard Worker 
993*635a8641SAndroid Build Coastguard Worker   // IPC::Listener:
OnMessageReceived(const IPC::Message & message)994*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
995*635a8641SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)996*635a8641SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
997*635a8641SAndroid Build Coastguard Worker       const std::string& interface_name,
998*635a8641SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
999*635a8641SAndroid Build Coastguard Worker     DCHECK(!driver_binding_.is_bound());
1000*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(interface_name, IPC::mojom::IndirectTestDriver::Name_);
1001*635a8641SAndroid Build Coastguard Worker     driver_binding_.Bind(
1002*635a8641SAndroid Build Coastguard Worker         IPC::mojom::IndirectTestDriverAssociatedRequest(std::move(handle)));
1003*635a8641SAndroid Build Coastguard Worker   }
1004*635a8641SAndroid Build Coastguard Worker 
set_ping_handler(const base::RepeatingClosure & handler)1005*635a8641SAndroid Build Coastguard Worker   void set_ping_handler(const base::RepeatingClosure& handler) {
1006*635a8641SAndroid Build Coastguard Worker     ping_handler_ = handler;
1007*635a8641SAndroid Build Coastguard Worker   }
1008*635a8641SAndroid Build Coastguard Worker 
1009*635a8641SAndroid Build Coastguard Worker  private:
1010*635a8641SAndroid Build Coastguard Worker   // IPC::mojom::IndirectTestDriver:
GetPingReceiver(IPC::mojom::PingReceiverAssociatedRequest request)1011*635a8641SAndroid Build Coastguard Worker   void GetPingReceiver(
1012*635a8641SAndroid Build Coastguard Worker       IPC::mojom::PingReceiverAssociatedRequest request) override {
1013*635a8641SAndroid Build Coastguard Worker     ping_receiver_binding_.Bind(std::move(request));
1014*635a8641SAndroid Build Coastguard Worker   }
1015*635a8641SAndroid Build Coastguard Worker 
1016*635a8641SAndroid Build Coastguard Worker   // IPC::mojom::PingReceiver:
Ping(PingCallback callback)1017*635a8641SAndroid Build Coastguard Worker   void Ping(PingCallback callback) override {
1018*635a8641SAndroid Build Coastguard Worker     std::move(callback).Run();
1019*635a8641SAndroid Build Coastguard Worker     ping_handler_.Run();
1020*635a8641SAndroid Build Coastguard Worker   }
1021*635a8641SAndroid Build Coastguard Worker 
1022*635a8641SAndroid Build Coastguard Worker   mojo::AssociatedBinding<IPC::mojom::IndirectTestDriver> driver_binding_;
1023*635a8641SAndroid Build Coastguard Worker   mojo::AssociatedBinding<IPC::mojom::PingReceiver> ping_receiver_binding_;
1024*635a8641SAndroid Build Coastguard Worker 
1025*635a8641SAndroid Build Coastguard Worker   base::RepeatingClosure ping_handler_;
1026*635a8641SAndroid Build Coastguard Worker };
1027*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,ProxyThreadAssociatedInterfaceIndirect)1028*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterfaceIndirect) {
1029*635a8641SAndroid Build Coastguard Worker   // Tests that we can pipeline interface requests and subsequent messages
1030*635a8641SAndroid Build Coastguard Worker   // targeting proxy thread bindings, and the channel will still dispatch
1031*635a8641SAndroid Build Coastguard Worker   // messages appropriately.
1032*635a8641SAndroid Build Coastguard Worker 
1033*635a8641SAndroid Build Coastguard Worker   Init("ProxyThreadAssociatedInterfaceIndirectClient");
1034*635a8641SAndroid Build Coastguard Worker 
1035*635a8641SAndroid Build Coastguard Worker   ListenerWithIndirectProxyAssociatedInterface listener;
1036*635a8641SAndroid Build Coastguard Worker   CreateProxy(&listener);
1037*635a8641SAndroid Build Coastguard Worker   RunProxy();
1038*635a8641SAndroid Build Coastguard Worker 
1039*635a8641SAndroid Build Coastguard Worker   base::RunLoop loop;
1040*635a8641SAndroid Build Coastguard Worker   listener.set_ping_handler(loop.QuitClosure());
1041*635a8641SAndroid Build Coastguard Worker   loop.Run();
1042*635a8641SAndroid Build Coastguard Worker 
1043*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1044*635a8641SAndroid Build Coastguard Worker 
1045*635a8641SAndroid Build Coastguard Worker   DestroyProxy();
1046*635a8641SAndroid Build Coastguard Worker }
1047*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ProxyThreadAssociatedInterfaceIndirectClient,ChannelProxyClient)1048*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
1049*635a8641SAndroid Build Coastguard Worker     ProxyThreadAssociatedInterfaceIndirectClient,
1050*635a8641SAndroid Build Coastguard Worker     ChannelProxyClient) {
1051*635a8641SAndroid Build Coastguard Worker   DummyListener listener;
1052*635a8641SAndroid Build Coastguard Worker   CreateProxy(&listener);
1053*635a8641SAndroid Build Coastguard Worker   RunProxy();
1054*635a8641SAndroid Build Coastguard Worker 
1055*635a8641SAndroid Build Coastguard Worker   // Use an interface requested via another interface. On the remote end both
1056*635a8641SAndroid Build Coastguard Worker   // interfaces are bound on the proxy thread. This ensures that the Ping
1057*635a8641SAndroid Build Coastguard Worker   // message we send will still be dispatched properly even though the remote
1058*635a8641SAndroid Build Coastguard Worker   // endpoint may not have been bound yet by the time the message is initially
1059*635a8641SAndroid Build Coastguard Worker   // processed on the IO thread.
1060*635a8641SAndroid Build Coastguard Worker   IPC::mojom::IndirectTestDriverAssociatedPtr driver;
1061*635a8641SAndroid Build Coastguard Worker   IPC::mojom::PingReceiverAssociatedPtr ping_receiver;
1062*635a8641SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(&driver);
1063*635a8641SAndroid Build Coastguard Worker   driver->GetPingReceiver(mojo::MakeRequest(&ping_receiver));
1064*635a8641SAndroid Build Coastguard Worker 
1065*635a8641SAndroid Build Coastguard Worker   base::RunLoop loop;
1066*635a8641SAndroid Build Coastguard Worker   ping_receiver->Ping(loop.QuitClosure());
1067*635a8641SAndroid Build Coastguard Worker   loop.Run();
1068*635a8641SAndroid Build Coastguard Worker 
1069*635a8641SAndroid Build Coastguard Worker   DestroyProxy();
1070*635a8641SAndroid Build Coastguard Worker }
1071*635a8641SAndroid Build Coastguard Worker 
1072*635a8641SAndroid Build Coastguard Worker class ListenerWithSyncAssociatedInterface
1073*635a8641SAndroid Build Coastguard Worker     : public IPC::Listener,
1074*635a8641SAndroid Build Coastguard Worker       public IPC::mojom::SimpleTestDriver {
1075*635a8641SAndroid Build Coastguard Worker  public:
ListenerWithSyncAssociatedInterface()1076*635a8641SAndroid Build Coastguard Worker   ListenerWithSyncAssociatedInterface() : binding_(this) {}
1077*635a8641SAndroid Build Coastguard Worker   ~ListenerWithSyncAssociatedInterface() override = default;
1078*635a8641SAndroid Build Coastguard Worker 
set_sync_sender(IPC::Sender * sync_sender)1079*635a8641SAndroid Build Coastguard Worker   void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1080*635a8641SAndroid Build Coastguard Worker 
RunUntilQuitRequested()1081*635a8641SAndroid Build Coastguard Worker   void RunUntilQuitRequested() {
1082*635a8641SAndroid Build Coastguard Worker     base::RunLoop loop;
1083*635a8641SAndroid Build Coastguard Worker     quit_closure_ = loop.QuitClosure();
1084*635a8641SAndroid Build Coastguard Worker     loop.Run();
1085*635a8641SAndroid Build Coastguard Worker   }
1086*635a8641SAndroid Build Coastguard Worker 
CloseBinding()1087*635a8641SAndroid Build Coastguard Worker   void CloseBinding() { binding_.Close(); }
1088*635a8641SAndroid Build Coastguard Worker 
set_response_value(int32_t response)1089*635a8641SAndroid Build Coastguard Worker   void set_response_value(int32_t response) {
1090*635a8641SAndroid Build Coastguard Worker     response_value_ = response;
1091*635a8641SAndroid Build Coastguard Worker   }
1092*635a8641SAndroid Build Coastguard Worker 
1093*635a8641SAndroid Build Coastguard Worker  private:
1094*635a8641SAndroid Build Coastguard Worker   // IPC::mojom::SimpleTestDriver:
ExpectValue(int32_t value)1095*635a8641SAndroid Build Coastguard Worker   void ExpectValue(int32_t value) override {
1096*635a8641SAndroid Build Coastguard Worker     next_expected_value_ = value;
1097*635a8641SAndroid Build Coastguard Worker   }
1098*635a8641SAndroid Build Coastguard Worker 
GetExpectedValue(GetExpectedValueCallback callback)1099*635a8641SAndroid Build Coastguard Worker   void GetExpectedValue(GetExpectedValueCallback callback) override {
1100*635a8641SAndroid Build Coastguard Worker     std::move(callback).Run(next_expected_value_);
1101*635a8641SAndroid Build Coastguard Worker   }
1102*635a8641SAndroid Build Coastguard Worker 
RequestValue(RequestValueCallback callback)1103*635a8641SAndroid Build Coastguard Worker   void RequestValue(RequestValueCallback callback) override {
1104*635a8641SAndroid Build Coastguard Worker     std::move(callback).Run(response_value_);
1105*635a8641SAndroid Build Coastguard Worker   }
1106*635a8641SAndroid Build Coastguard Worker 
RequestQuit(RequestQuitCallback callback)1107*635a8641SAndroid Build Coastguard Worker   void RequestQuit(RequestQuitCallback callback) override {
1108*635a8641SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
1109*635a8641SAndroid Build Coastguard Worker     std::move(callback).Run();
1110*635a8641SAndroid Build Coastguard Worker   }
1111*635a8641SAndroid Build Coastguard Worker 
1112*635a8641SAndroid Build Coastguard Worker   // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1113*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1114*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(0u, message.type());
1115*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(message.is_sync());
1116*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(message.should_unblock());
1117*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<IPC::Message> reply(
1118*635a8641SAndroid Build Coastguard Worker         IPC::SyncMessage::GenerateReply(&message));
1119*635a8641SAndroid Build Coastguard Worker     reply->WriteInt(response_value_);
1120*635a8641SAndroid Build Coastguard Worker     DCHECK(sync_sender_);
1121*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(sync_sender_->Send(reply.release()));
1122*635a8641SAndroid Build Coastguard Worker     return true;
1123*635a8641SAndroid Build Coastguard Worker   }
1124*635a8641SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1125*635a8641SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
1126*635a8641SAndroid Build Coastguard Worker       const std::string& interface_name,
1127*635a8641SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
1128*635a8641SAndroid Build Coastguard Worker     DCHECK(!binding_.is_bound());
1129*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
1130*635a8641SAndroid Build Coastguard Worker     binding_.Bind(
1131*635a8641SAndroid Build Coastguard Worker         IPC::mojom::SimpleTestDriverAssociatedRequest(std::move(handle)));
1132*635a8641SAndroid Build Coastguard Worker   }
1133*635a8641SAndroid Build Coastguard Worker 
BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request)1134*635a8641SAndroid Build Coastguard Worker   void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) {
1135*635a8641SAndroid Build Coastguard Worker     DCHECK(!binding_.is_bound());
1136*635a8641SAndroid Build Coastguard Worker     binding_.Bind(std::move(request));
1137*635a8641SAndroid Build Coastguard Worker   }
1138*635a8641SAndroid Build Coastguard Worker 
1139*635a8641SAndroid Build Coastguard Worker   IPC::Sender* sync_sender_ = nullptr;
1140*635a8641SAndroid Build Coastguard Worker   int32_t next_expected_value_ = 0;
1141*635a8641SAndroid Build Coastguard Worker   int32_t response_value_ = 0;
1142*635a8641SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
1143*635a8641SAndroid Build Coastguard Worker 
1144*635a8641SAndroid Build Coastguard Worker   mojo::AssociatedBinding<IPC::mojom::SimpleTestDriver> binding_;
1145*635a8641SAndroid Build Coastguard Worker };
1146*635a8641SAndroid Build Coastguard Worker 
1147*635a8641SAndroid Build Coastguard Worker class SyncReplyReader : public IPC::MessageReplyDeserializer {
1148*635a8641SAndroid Build Coastguard Worker  public:
SyncReplyReader(int32_t * storage)1149*635a8641SAndroid Build Coastguard Worker   explicit SyncReplyReader(int32_t* storage) : storage_(storage) {}
1150*635a8641SAndroid Build Coastguard Worker   ~SyncReplyReader() override = default;
1151*635a8641SAndroid Build Coastguard Worker 
1152*635a8641SAndroid Build Coastguard Worker  private:
1153*635a8641SAndroid Build Coastguard Worker   // IPC::MessageReplyDeserializer:
SerializeOutputParameters(const IPC::Message & message,base::PickleIterator iter)1154*635a8641SAndroid Build Coastguard Worker   bool SerializeOutputParameters(const IPC::Message& message,
1155*635a8641SAndroid Build Coastguard Worker                                  base::PickleIterator iter) override {
1156*635a8641SAndroid Build Coastguard Worker     if (!iter.ReadInt(storage_))
1157*635a8641SAndroid Build Coastguard Worker       return false;
1158*635a8641SAndroid Build Coastguard Worker     return true;
1159*635a8641SAndroid Build Coastguard Worker   }
1160*635a8641SAndroid Build Coastguard Worker 
1161*635a8641SAndroid Build Coastguard Worker   int32_t* storage_;
1162*635a8641SAndroid Build Coastguard Worker 
1163*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(SyncReplyReader);
1164*635a8641SAndroid Build Coastguard Worker };
1165*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,SyncAssociatedInterface)1166*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) {
1167*635a8641SAndroid Build Coastguard Worker   Init("SyncAssociatedInterface");
1168*635a8641SAndroid Build Coastguard Worker 
1169*635a8641SAndroid Build Coastguard Worker   ListenerWithSyncAssociatedInterface listener;
1170*635a8641SAndroid Build Coastguard Worker   CreateProxy(&listener);
1171*635a8641SAndroid Build Coastguard Worker   listener.set_sync_sender(proxy());
1172*635a8641SAndroid Build Coastguard Worker   RunProxy();
1173*635a8641SAndroid Build Coastguard Worker 
1174*635a8641SAndroid Build Coastguard Worker   // Run the client's simple sanity check to completion.
1175*635a8641SAndroid Build Coastguard Worker   listener.RunUntilQuitRequested();
1176*635a8641SAndroid Build Coastguard Worker 
1177*635a8641SAndroid Build Coastguard Worker   // Verify that we can send a sync IPC and service an incoming sync request
1178*635a8641SAndroid Build Coastguard Worker   // while waiting on it
1179*635a8641SAndroid Build Coastguard Worker   listener.set_response_value(42);
1180*635a8641SAndroid Build Coastguard Worker   IPC::mojom::SimpleTestClientAssociatedPtr client;
1181*635a8641SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(&client);
1182*635a8641SAndroid Build Coastguard Worker   int32_t received_value;
1183*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(client->RequestValue(&received_value));
1184*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(42, received_value);
1185*635a8641SAndroid Build Coastguard Worker 
1186*635a8641SAndroid Build Coastguard Worker   // Do it again. This time the client will send a classical sync IPC to us
1187*635a8641SAndroid Build Coastguard Worker   // while we wait.
1188*635a8641SAndroid Build Coastguard Worker   received_value = 0;
1189*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(client->RequestValue(&received_value));
1190*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(42, received_value);
1191*635a8641SAndroid Build Coastguard Worker 
1192*635a8641SAndroid Build Coastguard Worker   // Now make a classical sync IPC request to the client. It will send a
1193*635a8641SAndroid Build Coastguard Worker   // sync associated interface message to us while we wait.
1194*635a8641SAndroid Build Coastguard Worker   received_value = 0;
1195*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<IPC::SyncMessage> request(
1196*635a8641SAndroid Build Coastguard Worker       new IPC::SyncMessage(0, 0, IPC::Message::PRIORITY_NORMAL,
1197*635a8641SAndroid Build Coastguard Worker                            new SyncReplyReader(&received_value)));
1198*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy()->Send(request.release()));
1199*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(42, received_value);
1200*635a8641SAndroid Build Coastguard Worker 
1201*635a8641SAndroid Build Coastguard Worker   listener.CloseBinding();
1202*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1203*635a8641SAndroid Build Coastguard Worker 
1204*635a8641SAndroid Build Coastguard Worker   DestroyProxy();
1205*635a8641SAndroid Build Coastguard Worker }
1206*635a8641SAndroid Build Coastguard Worker 
1207*635a8641SAndroid Build Coastguard Worker class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
1208*635a8641SAndroid Build Coastguard Worker                              public IPC::Listener {
1209*635a8641SAndroid Build Coastguard Worker  public:
SimpleTestClientImpl()1210*635a8641SAndroid Build Coastguard Worker   SimpleTestClientImpl() : binding_(this) {}
1211*635a8641SAndroid Build Coastguard Worker 
set_driver(IPC::mojom::SimpleTestDriver * driver)1212*635a8641SAndroid Build Coastguard Worker   void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; }
set_sync_sender(IPC::Sender * sync_sender)1213*635a8641SAndroid Build Coastguard Worker   void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1214*635a8641SAndroid Build Coastguard Worker 
WaitForValueRequest()1215*635a8641SAndroid Build Coastguard Worker   void WaitForValueRequest() {
1216*635a8641SAndroid Build Coastguard Worker     run_loop_.reset(new base::RunLoop);
1217*635a8641SAndroid Build Coastguard Worker     run_loop_->Run();
1218*635a8641SAndroid Build Coastguard Worker   }
1219*635a8641SAndroid Build Coastguard Worker 
UseSyncSenderForRequest(bool use_sync_sender)1220*635a8641SAndroid Build Coastguard Worker   void UseSyncSenderForRequest(bool use_sync_sender) {
1221*635a8641SAndroid Build Coastguard Worker     use_sync_sender_ = use_sync_sender;
1222*635a8641SAndroid Build Coastguard Worker   }
1223*635a8641SAndroid Build Coastguard Worker 
1224*635a8641SAndroid Build Coastguard Worker  private:
1225*635a8641SAndroid Build Coastguard Worker   // IPC::mojom::SimpleTestClient:
RequestValue(RequestValueCallback callback)1226*635a8641SAndroid Build Coastguard Worker   void RequestValue(RequestValueCallback callback) override {
1227*635a8641SAndroid Build Coastguard Worker     int32_t response = 0;
1228*635a8641SAndroid Build Coastguard Worker     if (use_sync_sender_) {
1229*635a8641SAndroid Build Coastguard Worker       std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage(
1230*635a8641SAndroid Build Coastguard Worker           0, 0, IPC::Message::PRIORITY_NORMAL, new SyncReplyReader(&response)));
1231*635a8641SAndroid Build Coastguard Worker       EXPECT_TRUE(sync_sender_->Send(reply.release()));
1232*635a8641SAndroid Build Coastguard Worker     } else {
1233*635a8641SAndroid Build Coastguard Worker       DCHECK(driver_);
1234*635a8641SAndroid Build Coastguard Worker       EXPECT_TRUE(driver_->RequestValue(&response));
1235*635a8641SAndroid Build Coastguard Worker     }
1236*635a8641SAndroid Build Coastguard Worker 
1237*635a8641SAndroid Build Coastguard Worker     std::move(callback).Run(response);
1238*635a8641SAndroid Build Coastguard Worker 
1239*635a8641SAndroid Build Coastguard Worker     DCHECK(run_loop_);
1240*635a8641SAndroid Build Coastguard Worker     run_loop_->Quit();
1241*635a8641SAndroid Build Coastguard Worker   }
1242*635a8641SAndroid Build Coastguard Worker 
1243*635a8641SAndroid Build Coastguard Worker   // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1244*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1245*635a8641SAndroid Build Coastguard Worker     int32_t response;
1246*635a8641SAndroid Build Coastguard Worker     DCHECK(driver_);
1247*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(driver_->RequestValue(&response));
1248*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<IPC::Message> reply(
1249*635a8641SAndroid Build Coastguard Worker         IPC::SyncMessage::GenerateReply(&message));
1250*635a8641SAndroid Build Coastguard Worker     reply->WriteInt(response);
1251*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(sync_sender_->Send(reply.release()));
1252*635a8641SAndroid Build Coastguard Worker 
1253*635a8641SAndroid Build Coastguard Worker     DCHECK(run_loop_);
1254*635a8641SAndroid Build Coastguard Worker     run_loop_->Quit();
1255*635a8641SAndroid Build Coastguard Worker     return true;
1256*635a8641SAndroid Build Coastguard Worker   }
1257*635a8641SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1258*635a8641SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
1259*635a8641SAndroid Build Coastguard Worker       const std::string& interface_name,
1260*635a8641SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
1261*635a8641SAndroid Build Coastguard Worker     DCHECK(!binding_.is_bound());
1262*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(interface_name, IPC::mojom::SimpleTestClient::Name_);
1263*635a8641SAndroid Build Coastguard Worker 
1264*635a8641SAndroid Build Coastguard Worker     binding_.Bind(
1265*635a8641SAndroid Build Coastguard Worker         IPC::mojom::SimpleTestClientAssociatedRequest(std::move(handle)));
1266*635a8641SAndroid Build Coastguard Worker   }
1267*635a8641SAndroid Build Coastguard Worker 
1268*635a8641SAndroid Build Coastguard Worker   bool use_sync_sender_ = false;
1269*635a8641SAndroid Build Coastguard Worker   mojo::AssociatedBinding<IPC::mojom::SimpleTestClient> binding_;
1270*635a8641SAndroid Build Coastguard Worker   IPC::Sender* sync_sender_ = nullptr;
1271*635a8641SAndroid Build Coastguard Worker   IPC::mojom::SimpleTestDriver* driver_ = nullptr;
1272*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<base::RunLoop> run_loop_;
1273*635a8641SAndroid Build Coastguard Worker 
1274*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(SimpleTestClientImpl);
1275*635a8641SAndroid Build Coastguard Worker };
1276*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,ChannelProxyClient)1277*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,
1278*635a8641SAndroid Build Coastguard Worker                                                         ChannelProxyClient) {
1279*635a8641SAndroid Build Coastguard Worker   SimpleTestClientImpl client_impl;
1280*635a8641SAndroid Build Coastguard Worker   CreateProxy(&client_impl);
1281*635a8641SAndroid Build Coastguard Worker   client_impl.set_sync_sender(proxy());
1282*635a8641SAndroid Build Coastguard Worker   RunProxy();
1283*635a8641SAndroid Build Coastguard Worker 
1284*635a8641SAndroid Build Coastguard Worker   IPC::mojom::SimpleTestDriverAssociatedPtr driver;
1285*635a8641SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(&driver);
1286*635a8641SAndroid Build Coastguard Worker   client_impl.set_driver(driver.get());
1287*635a8641SAndroid Build Coastguard Worker 
1288*635a8641SAndroid Build Coastguard Worker   // Simple sync message sanity check.
1289*635a8641SAndroid Build Coastguard Worker   driver->ExpectValue(42);
1290*635a8641SAndroid Build Coastguard Worker   int32_t expected_value = 0;
1291*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(driver->GetExpectedValue(&expected_value));
1292*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(42, expected_value);
1293*635a8641SAndroid Build Coastguard Worker   RequestQuitAndWaitForAck(driver.get());
1294*635a8641SAndroid Build Coastguard Worker 
1295*635a8641SAndroid Build Coastguard Worker   // Wait for the test driver to perform a sync call test with our own sync
1296*635a8641SAndroid Build Coastguard Worker   // associated interface message nested inside.
1297*635a8641SAndroid Build Coastguard Worker   client_impl.UseSyncSenderForRequest(false);
1298*635a8641SAndroid Build Coastguard Worker   client_impl.WaitForValueRequest();
1299*635a8641SAndroid Build Coastguard Worker 
1300*635a8641SAndroid Build Coastguard Worker   // Wait for the test driver to perform a sync call test with our own classical
1301*635a8641SAndroid Build Coastguard Worker   // sync IPC nested inside.
1302*635a8641SAndroid Build Coastguard Worker   client_impl.UseSyncSenderForRequest(true);
1303*635a8641SAndroid Build Coastguard Worker   client_impl.WaitForValueRequest();
1304*635a8641SAndroid Build Coastguard Worker 
1305*635a8641SAndroid Build Coastguard Worker   // Wait for the test driver to perform a classical sync IPC request, with our
1306*635a8641SAndroid Build Coastguard Worker   // own sync associated interface message nested inside.
1307*635a8641SAndroid Build Coastguard Worker   client_impl.UseSyncSenderForRequest(false);
1308*635a8641SAndroid Build Coastguard Worker   client_impl.WaitForValueRequest();
1309*635a8641SAndroid Build Coastguard Worker 
1310*635a8641SAndroid Build Coastguard Worker   DestroyProxy();
1311*635a8641SAndroid Build Coastguard Worker }
1312*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,Pause)1313*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, Pause) {
1314*635a8641SAndroid Build Coastguard Worker   // Ensures that pausing a channel elicits the expected behavior when sending
1315*635a8641SAndroid Build Coastguard Worker   // messages, unpausing, sending more messages, and then manually flushing.
1316*635a8641SAndroid Build Coastguard Worker   // Specifically a sequence like:
1317*635a8641SAndroid Build Coastguard Worker   //
1318*635a8641SAndroid Build Coastguard Worker   //   Connect()
1319*635a8641SAndroid Build Coastguard Worker   //   Send(A)
1320*635a8641SAndroid Build Coastguard Worker   //   Pause()
1321*635a8641SAndroid Build Coastguard Worker   //   Send(B)
1322*635a8641SAndroid Build Coastguard Worker   //   Send(C)
1323*635a8641SAndroid Build Coastguard Worker   //   Unpause(false)
1324*635a8641SAndroid Build Coastguard Worker   //   Send(D)
1325*635a8641SAndroid Build Coastguard Worker   //   Send(E)
1326*635a8641SAndroid Build Coastguard Worker   //   Flush()
1327*635a8641SAndroid Build Coastguard Worker   //
1328*635a8641SAndroid Build Coastguard Worker   // must result in the other end receiving messages A, D, E, B, D; in that
1329*635a8641SAndroid Build Coastguard Worker   // order.
1330*635a8641SAndroid Build Coastguard Worker   //
1331*635a8641SAndroid Build Coastguard Worker   // This behavior is required by some consumers of IPC::Channel, and it is not
1332*635a8641SAndroid Build Coastguard Worker   // sufficient to leave this up to the consumer to implement since associated
1333*635a8641SAndroid Build Coastguard Worker   // interface requests and messages also need to be queued according to the
1334*635a8641SAndroid Build Coastguard Worker   // same policy.
1335*635a8641SAndroid Build Coastguard Worker   Init("CreatePausedClient");
1336*635a8641SAndroid Build Coastguard Worker 
1337*635a8641SAndroid Build Coastguard Worker   DummyListener listener;
1338*635a8641SAndroid Build Coastguard Worker   CreateProxy(&listener);
1339*635a8641SAndroid Build Coastguard Worker   RunProxy();
1340*635a8641SAndroid Build Coastguard Worker 
1341*635a8641SAndroid Build Coastguard Worker   // This message must be sent immediately since the channel is unpaused.
1342*635a8641SAndroid Build Coastguard Worker   SendValue(proxy(), 1);
1343*635a8641SAndroid Build Coastguard Worker 
1344*635a8641SAndroid Build Coastguard Worker   proxy()->Pause();
1345*635a8641SAndroid Build Coastguard Worker 
1346*635a8641SAndroid Build Coastguard Worker   // These messages must be queued internally since the channel is paused.
1347*635a8641SAndroid Build Coastguard Worker   SendValue(proxy(), 2);
1348*635a8641SAndroid Build Coastguard Worker   SendValue(proxy(), 3);
1349*635a8641SAndroid Build Coastguard Worker 
1350*635a8641SAndroid Build Coastguard Worker   proxy()->Unpause(false /* flush */);
1351*635a8641SAndroid Build Coastguard Worker 
1352*635a8641SAndroid Build Coastguard Worker   // These messages must be sent immediately since the channel is unpaused.
1353*635a8641SAndroid Build Coastguard Worker   SendValue(proxy(), 4);
1354*635a8641SAndroid Build Coastguard Worker   SendValue(proxy(), 5);
1355*635a8641SAndroid Build Coastguard Worker 
1356*635a8641SAndroid Build Coastguard Worker   // Now we flush the previously queued messages.
1357*635a8641SAndroid Build Coastguard Worker   proxy()->Flush();
1358*635a8641SAndroid Build Coastguard Worker 
1359*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1360*635a8641SAndroid Build Coastguard Worker   DestroyProxy();
1361*635a8641SAndroid Build Coastguard Worker }
1362*635a8641SAndroid Build Coastguard Worker 
1363*635a8641SAndroid Build Coastguard Worker class ExpectValueSequenceListener : public IPC::Listener {
1364*635a8641SAndroid Build Coastguard Worker  public:
ExpectValueSequenceListener(base::queue<int32_t> * expected_values,base::OnceClosure quit_closure)1365*635a8641SAndroid Build Coastguard Worker   ExpectValueSequenceListener(base::queue<int32_t>* expected_values,
1366*635a8641SAndroid Build Coastguard Worker                               base::OnceClosure quit_closure)
1367*635a8641SAndroid Build Coastguard Worker       : expected_values_(expected_values),
1368*635a8641SAndroid Build Coastguard Worker         quit_closure_(std::move(quit_closure)) {}
1369*635a8641SAndroid Build Coastguard Worker   ~ExpectValueSequenceListener() override = default;
1370*635a8641SAndroid Build Coastguard Worker 
1371*635a8641SAndroid Build Coastguard Worker   // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1372*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1373*635a8641SAndroid Build Coastguard Worker     DCHECK(!expected_values_->empty());
1374*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
1375*635a8641SAndroid Build Coastguard Worker     int32_t should_be_expected;
1376*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(iter.ReadInt(&should_be_expected));
1377*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(expected_values_->front(), should_be_expected);
1378*635a8641SAndroid Build Coastguard Worker     expected_values_->pop();
1379*635a8641SAndroid Build Coastguard Worker     if (expected_values_->empty())
1380*635a8641SAndroid Build Coastguard Worker       std::move(quit_closure_).Run();
1381*635a8641SAndroid Build Coastguard Worker     return true;
1382*635a8641SAndroid Build Coastguard Worker   }
1383*635a8641SAndroid Build Coastguard Worker 
1384*635a8641SAndroid Build Coastguard Worker  private:
1385*635a8641SAndroid Build Coastguard Worker   base::queue<int32_t>* expected_values_;
1386*635a8641SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
1387*635a8641SAndroid Build Coastguard Worker 
1388*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ExpectValueSequenceListener);
1389*635a8641SAndroid Build Coastguard Worker };
1390*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,ChannelProxyClient)1391*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,
1392*635a8641SAndroid Build Coastguard Worker                                                         ChannelProxyClient) {
1393*635a8641SAndroid Build Coastguard Worker   base::queue<int32_t> expected_values;
1394*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1395*635a8641SAndroid Build Coastguard Worker   ExpectValueSequenceListener listener(&expected_values,
1396*635a8641SAndroid Build Coastguard Worker                                        run_loop.QuitClosure());
1397*635a8641SAndroid Build Coastguard Worker   CreateProxy(&listener);
1398*635a8641SAndroid Build Coastguard Worker   expected_values.push(1);
1399*635a8641SAndroid Build Coastguard Worker   expected_values.push(4);
1400*635a8641SAndroid Build Coastguard Worker   expected_values.push(5);
1401*635a8641SAndroid Build Coastguard Worker   expected_values.push(2);
1402*635a8641SAndroid Build Coastguard Worker   expected_values.push(3);
1403*635a8641SAndroid Build Coastguard Worker   RunProxy();
1404*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1405*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(expected_values.empty());
1406*635a8641SAndroid Build Coastguard Worker   DestroyProxy();
1407*635a8641SAndroid Build Coastguard Worker }
1408*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,AssociatedRequestClose)1409*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, AssociatedRequestClose) {
1410*635a8641SAndroid Build Coastguard Worker   Init("DropAssociatedRequest");
1411*635a8641SAndroid Build Coastguard Worker 
1412*635a8641SAndroid Build Coastguard Worker   DummyListener listener;
1413*635a8641SAndroid Build Coastguard Worker   CreateProxy(&listener);
1414*635a8641SAndroid Build Coastguard Worker   RunProxy();
1415*635a8641SAndroid Build Coastguard Worker 
1416*635a8641SAndroid Build Coastguard Worker   IPC::mojom::AssociatedInterfaceVendorAssociatedPtr vendor;
1417*635a8641SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(&vendor);
1418*635a8641SAndroid Build Coastguard Worker   IPC::mojom::SimpleTestDriverAssociatedPtr tester;
1419*635a8641SAndroid Build Coastguard Worker   vendor->GetTestInterface(mojo::MakeRequest(&tester));
1420*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1421*635a8641SAndroid Build Coastguard Worker   tester.set_connection_error_handler(run_loop.QuitClosure());
1422*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1423*635a8641SAndroid Build Coastguard Worker 
1424*635a8641SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(&tester);
1425*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1426*635a8641SAndroid Build Coastguard Worker   DestroyProxy();
1427*635a8641SAndroid Build Coastguard Worker }
1428*635a8641SAndroid Build Coastguard Worker 
1429*635a8641SAndroid Build Coastguard Worker class AssociatedInterfaceDroppingListener : public IPC::Listener {
1430*635a8641SAndroid Build Coastguard Worker  public:
AssociatedInterfaceDroppingListener(base::OnceClosure callback)1431*635a8641SAndroid Build Coastguard Worker   AssociatedInterfaceDroppingListener(base::OnceClosure callback)
1432*635a8641SAndroid Build Coastguard Worker       : callback_(std::move(callback)) {}
OnMessageReceived(const IPC::Message & message)1433*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return false; }
1434*635a8641SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1435*635a8641SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
1436*635a8641SAndroid Build Coastguard Worker       const std::string& interface_name,
1437*635a8641SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
1438*635a8641SAndroid Build Coastguard Worker     if (interface_name == IPC::mojom::SimpleTestDriver::Name_)
1439*635a8641SAndroid Build Coastguard Worker       std::move(callback_).Run();
1440*635a8641SAndroid Build Coastguard Worker   }
1441*635a8641SAndroid Build Coastguard Worker 
1442*635a8641SAndroid Build Coastguard Worker  private:
1443*635a8641SAndroid Build Coastguard Worker   base::OnceClosure callback_;
1444*635a8641SAndroid Build Coastguard Worker };
1445*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,ChannelProxyClient)1446*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,
1447*635a8641SAndroid Build Coastguard Worker                                                         ChannelProxyClient) {
1448*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1449*635a8641SAndroid Build Coastguard Worker   AssociatedInterfaceDroppingListener listener(run_loop.QuitClosure());
1450*635a8641SAndroid Build Coastguard Worker   CreateProxy(&listener);
1451*635a8641SAndroid Build Coastguard Worker   RunProxy();
1452*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1453*635a8641SAndroid Build Coastguard Worker   DestroyProxy();
1454*635a8641SAndroid Build Coastguard Worker }
1455*635a8641SAndroid Build Coastguard Worker 
1456*635a8641SAndroid Build Coastguard Worker #if !defined(OS_MACOSX)
1457*635a8641SAndroid Build Coastguard Worker // TODO(wez): On Mac we need to set up a MachPortBroker before we can transfer
1458*635a8641SAndroid Build Coastguard Worker // Mach ports (which underpin Sharedmemory on Mac) across IPC.
1459*635a8641SAndroid Build Coastguard Worker 
1460*635a8641SAndroid Build Coastguard Worker class ListenerThatExpectsSharedMemory : public TestListenerBase {
1461*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatExpectsSharedMemory(base::OnceClosure quit_closure)1462*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsSharedMemory(base::OnceClosure quit_closure)
1463*635a8641SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
1464*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)1465*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1466*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
1467*635a8641SAndroid Build Coastguard Worker 
1468*635a8641SAndroid Build Coastguard Worker     base::SharedMemoryHandle shared_memory;
1469*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(IPC::ReadParam(&message, &iter, &shared_memory));
1470*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(shared_memory.IsValid());
1471*635a8641SAndroid Build Coastguard Worker     shared_memory.Close();
1472*635a8641SAndroid Build Coastguard Worker 
1473*635a8641SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
1474*635a8641SAndroid Build Coastguard Worker     return true;
1475*635a8641SAndroid Build Coastguard Worker   }
1476*635a8641SAndroid Build Coastguard Worker };
1477*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendSharedMemory)1478*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendSharedMemory) {
1479*635a8641SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestSendSharedMemoryClient");
1480*635a8641SAndroid Build Coastguard Worker 
1481*635a8641SAndroid Build Coastguard Worker   // Create some shared-memory to share.
1482*635a8641SAndroid Build Coastguard Worker   base::SharedMemoryCreateOptions options;
1483*635a8641SAndroid Build Coastguard Worker   options.size = 1004;
1484*635a8641SAndroid Build Coastguard Worker 
1485*635a8641SAndroid Build Coastguard Worker   base::SharedMemory shmem;
1486*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(shmem.Create(options));
1487*635a8641SAndroid Build Coastguard Worker 
1488*635a8641SAndroid Build Coastguard Worker   // Create a success listener, and launch the child process.
1489*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1490*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
1491*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
1492*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
1493*635a8641SAndroid Build Coastguard Worker 
1494*635a8641SAndroid Build Coastguard Worker   // Send the child process an IPC with |shmem| attached, to verify
1495*635a8641SAndroid Build Coastguard Worker   // that is is correctly wrapped, transferred and unwrapped.
1496*635a8641SAndroid Build Coastguard Worker   IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
1497*635a8641SAndroid Build Coastguard Worker   IPC::WriteParam(message, shmem.handle());
1498*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(channel()->Send(message));
1499*635a8641SAndroid Build Coastguard Worker 
1500*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1501*635a8641SAndroid Build Coastguard Worker 
1502*635a8641SAndroid Build Coastguard Worker   channel()->Close();
1503*635a8641SAndroid Build Coastguard Worker 
1504*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1505*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
1506*635a8641SAndroid Build Coastguard Worker }
1507*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendSharedMemoryClient)1508*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendSharedMemoryClient) {
1509*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1510*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsSharedMemory listener(run_loop.QuitClosure());
1511*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
1512*635a8641SAndroid Build Coastguard Worker   listener.set_sender(channel());
1513*635a8641SAndroid Build Coastguard Worker 
1514*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1515*635a8641SAndroid Build Coastguard Worker 
1516*635a8641SAndroid Build Coastguard Worker   Close();
1517*635a8641SAndroid Build Coastguard Worker }
1518*635a8641SAndroid Build Coastguard Worker 
1519*635a8641SAndroid Build Coastguard Worker template <class SharedMemoryRegionType>
1520*635a8641SAndroid Build Coastguard Worker class IPCChannelMojoSharedMemoryRegionTypedTest : public IPCChannelMojoTest {};
1521*635a8641SAndroid Build Coastguard Worker 
1522*635a8641SAndroid Build Coastguard Worker struct WritableRegionTraits {
1523*635a8641SAndroid Build Coastguard Worker   using RegionType = base::WritableSharedMemoryRegion;
1524*635a8641SAndroid Build Coastguard Worker   static const char kClientName[];
1525*635a8641SAndroid Build Coastguard Worker };
1526*635a8641SAndroid Build Coastguard Worker const char WritableRegionTraits::kClientName[] =
1527*635a8641SAndroid Build Coastguard Worker     "IPCChannelMojoTestSendWritableSharedMemoryRegionClient";
1528*635a8641SAndroid Build Coastguard Worker struct UnsafeRegionTraits {
1529*635a8641SAndroid Build Coastguard Worker   using RegionType = base::UnsafeSharedMemoryRegion;
1530*635a8641SAndroid Build Coastguard Worker   static const char kClientName[];
1531*635a8641SAndroid Build Coastguard Worker };
1532*635a8641SAndroid Build Coastguard Worker const char UnsafeRegionTraits::kClientName[] =
1533*635a8641SAndroid Build Coastguard Worker     "IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient";
1534*635a8641SAndroid Build Coastguard Worker struct ReadOnlyRegionTraits {
1535*635a8641SAndroid Build Coastguard Worker   using RegionType = base::ReadOnlySharedMemoryRegion;
1536*635a8641SAndroid Build Coastguard Worker   static const char kClientName[];
1537*635a8641SAndroid Build Coastguard Worker };
1538*635a8641SAndroid Build Coastguard Worker const char ReadOnlyRegionTraits::kClientName[] =
1539*635a8641SAndroid Build Coastguard Worker     "IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient";
1540*635a8641SAndroid Build Coastguard Worker 
1541*635a8641SAndroid Build Coastguard Worker typedef ::testing::
1542*635a8641SAndroid Build Coastguard Worker     Types<WritableRegionTraits, UnsafeRegionTraits, ReadOnlyRegionTraits>
1543*635a8641SAndroid Build Coastguard Worker         AllSharedMemoryRegionTraits;
1544*635a8641SAndroid Build Coastguard Worker TYPED_TEST_CASE(IPCChannelMojoSharedMemoryRegionTypedTest,
1545*635a8641SAndroid Build Coastguard Worker                 AllSharedMemoryRegionTraits);
1546*635a8641SAndroid Build Coastguard Worker 
1547*635a8641SAndroid Build Coastguard Worker template <class SharedMemoryRegionType>
1548*635a8641SAndroid Build Coastguard Worker class ListenerThatExpectsSharedMemoryRegion : public TestListenerBase {
1549*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatExpectsSharedMemoryRegion(base::OnceClosure quit_closure)1550*635a8641SAndroid Build Coastguard Worker   explicit ListenerThatExpectsSharedMemoryRegion(base::OnceClosure quit_closure)
1551*635a8641SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
1552*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)1553*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1554*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
1555*635a8641SAndroid Build Coastguard Worker 
1556*635a8641SAndroid Build Coastguard Worker     SharedMemoryRegionType region;
1557*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(IPC::ReadParam(&message, &iter, &region));
1558*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(region.IsValid());
1559*635a8641SAndroid Build Coastguard Worker 
1560*635a8641SAndroid Build Coastguard Worker     // Verify the shared memory region has expected content.
1561*635a8641SAndroid Build Coastguard Worker     typename SharedMemoryRegionType::MappingType mapping = region.Map();
1562*635a8641SAndroid Build Coastguard Worker     std::string content = HandleSendingHelper::GetSendingFileContent();
1563*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(mapping.memory(), content.data(), content.size()));
1564*635a8641SAndroid Build Coastguard Worker 
1565*635a8641SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
1566*635a8641SAndroid Build Coastguard Worker     return true;
1567*635a8641SAndroid Build Coastguard Worker   }
1568*635a8641SAndroid Build Coastguard Worker };
1569*635a8641SAndroid Build Coastguard Worker 
TYPED_TEST(IPCChannelMojoSharedMemoryRegionTypedTest,Send)1570*635a8641SAndroid Build Coastguard Worker TYPED_TEST(IPCChannelMojoSharedMemoryRegionTypedTest, Send) {
1571*635a8641SAndroid Build Coastguard Worker   this->Init(TypeParam::kClientName);
1572*635a8641SAndroid Build Coastguard Worker 
1573*635a8641SAndroid Build Coastguard Worker   const size_t size = 1004;
1574*635a8641SAndroid Build Coastguard Worker   typename TypeParam::RegionType region;
1575*635a8641SAndroid Build Coastguard Worker   base::WritableSharedMemoryMapping mapping;
1576*635a8641SAndroid Build Coastguard Worker   std::tie(region, mapping) =
1577*635a8641SAndroid Build Coastguard Worker       base::CreateMappedRegion<typename TypeParam::RegionType>(size);
1578*635a8641SAndroid Build Coastguard Worker 
1579*635a8641SAndroid Build Coastguard Worker   std::string content = HandleSendingHelper::GetSendingFileContent();
1580*635a8641SAndroid Build Coastguard Worker   memcpy(mapping.memory(), content.data(), content.size());
1581*635a8641SAndroid Build Coastguard Worker 
1582*635a8641SAndroid Build Coastguard Worker   // Create a success listener, and launch the child process.
1583*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1584*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
1585*635a8641SAndroid Build Coastguard Worker   this->CreateChannel(&listener);
1586*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(this->ConnectChannel());
1587*635a8641SAndroid Build Coastguard Worker 
1588*635a8641SAndroid Build Coastguard Worker   // Send the child process an IPC with |shmem| attached, to verify
1589*635a8641SAndroid Build Coastguard Worker   // that is is correctly wrapped, transferred and unwrapped.
1590*635a8641SAndroid Build Coastguard Worker   IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
1591*635a8641SAndroid Build Coastguard Worker   IPC::WriteParam(message, region);
1592*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(this->channel()->Send(message));
1593*635a8641SAndroid Build Coastguard Worker 
1594*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1595*635a8641SAndroid Build Coastguard Worker 
1596*635a8641SAndroid Build Coastguard Worker   this->channel()->Close();
1597*635a8641SAndroid Build Coastguard Worker 
1598*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(this->WaitForClientShutdown());
1599*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(region.IsValid());
1600*635a8641SAndroid Build Coastguard Worker   this->DestroyChannel();
1601*635a8641SAndroid Build Coastguard Worker }
1602*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendWritableSharedMemoryRegionClient)1603*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1604*635a8641SAndroid Build Coastguard Worker     IPCChannelMojoTestSendWritableSharedMemoryRegionClient) {
1605*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1606*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsSharedMemoryRegion<base::WritableSharedMemoryRegion>
1607*635a8641SAndroid Build Coastguard Worker       listener(run_loop.QuitClosure());
1608*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
1609*635a8641SAndroid Build Coastguard Worker   listener.set_sender(channel());
1610*635a8641SAndroid Build Coastguard Worker 
1611*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1612*635a8641SAndroid Build Coastguard Worker 
1613*635a8641SAndroid Build Coastguard Worker   Close();
1614*635a8641SAndroid Build Coastguard Worker }
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient)1615*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1616*635a8641SAndroid Build Coastguard Worker     IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient) {
1617*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1618*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsSharedMemoryRegion<base::UnsafeSharedMemoryRegion>
1619*635a8641SAndroid Build Coastguard Worker       listener(run_loop.QuitClosure());
1620*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
1621*635a8641SAndroid Build Coastguard Worker   listener.set_sender(channel());
1622*635a8641SAndroid Build Coastguard Worker 
1623*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1624*635a8641SAndroid Build Coastguard Worker 
1625*635a8641SAndroid Build Coastguard Worker   Close();
1626*635a8641SAndroid Build Coastguard Worker }
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient)1627*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1628*635a8641SAndroid Build Coastguard Worker     IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient) {
1629*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1630*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsSharedMemoryRegion<base::ReadOnlySharedMemoryRegion>
1631*635a8641SAndroid Build Coastguard Worker       listener(run_loop.QuitClosure());
1632*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
1633*635a8641SAndroid Build Coastguard Worker   listener.set_sender(channel());
1634*635a8641SAndroid Build Coastguard Worker 
1635*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1636*635a8641SAndroid Build Coastguard Worker 
1637*635a8641SAndroid Build Coastguard Worker   Close();
1638*635a8641SAndroid Build Coastguard Worker }
1639*635a8641SAndroid Build Coastguard Worker #endif  // !defined(OS_MACOSX)
1640*635a8641SAndroid Build Coastguard Worker 
1641*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) || defined(OS_FUCHSIA)
1642*635a8641SAndroid Build Coastguard Worker 
1643*635a8641SAndroid Build Coastguard Worker class ListenerThatExpectsFile : public TestListenerBase {
1644*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatExpectsFile(base::OnceClosure quit_closure)1645*635a8641SAndroid Build Coastguard Worker   explicit ListenerThatExpectsFile(base::OnceClosure quit_closure)
1646*635a8641SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
1647*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)1648*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1649*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
1650*635a8641SAndroid Build Coastguard Worker     HandleSendingHelper::ReadReceivedFile(message, &iter);
1651*635a8641SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
1652*635a8641SAndroid Build Coastguard Worker     return true;
1653*635a8641SAndroid Build Coastguard Worker   }
1654*635a8641SAndroid Build Coastguard Worker };
1655*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendPlatformFile)1656*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendPlatformFile) {
1657*635a8641SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestSendPlatformFileClient");
1658*635a8641SAndroid Build Coastguard Worker 
1659*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1660*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
1661*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
1662*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
1663*635a8641SAndroid Build Coastguard Worker 
1664*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
1665*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1666*635a8641SAndroid Build Coastguard Worker   base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
1667*635a8641SAndroid Build Coastguard Worker                   base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1668*635a8641SAndroid Build Coastguard Worker                       base::File::FLAG_READ);
1669*635a8641SAndroid Build Coastguard Worker   HandleSendingHelper::WriteFileThenSend(channel(), file);
1670*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1671*635a8641SAndroid Build Coastguard Worker 
1672*635a8641SAndroid Build Coastguard Worker   channel()->Close();
1673*635a8641SAndroid Build Coastguard Worker 
1674*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1675*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
1676*635a8641SAndroid Build Coastguard Worker }
1677*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileClient)1678*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileClient) {
1679*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1680*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsFile listener(run_loop.QuitClosure());
1681*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
1682*635a8641SAndroid Build Coastguard Worker   listener.set_sender(channel());
1683*635a8641SAndroid Build Coastguard Worker 
1684*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1685*635a8641SAndroid Build Coastguard Worker 
1686*635a8641SAndroid Build Coastguard Worker   Close();
1687*635a8641SAndroid Build Coastguard Worker }
1688*635a8641SAndroid Build Coastguard Worker 
1689*635a8641SAndroid Build Coastguard Worker class ListenerThatExpectsFileAndMessagePipe : public TestListenerBase {
1690*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatExpectsFileAndMessagePipe(base::OnceClosure quit_closure)1691*635a8641SAndroid Build Coastguard Worker   explicit ListenerThatExpectsFileAndMessagePipe(base::OnceClosure quit_closure)
1692*635a8641SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
1693*635a8641SAndroid Build Coastguard Worker 
1694*635a8641SAndroid Build Coastguard Worker   ~ListenerThatExpectsFileAndMessagePipe() override = default;
1695*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)1696*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1697*635a8641SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
1698*635a8641SAndroid Build Coastguard Worker     HandleSendingHelper::ReadReceivedFile(message, &iter);
1699*635a8641SAndroid Build Coastguard Worker     HandleSendingHelper::ReadReceivedPipe(message, &iter);
1700*635a8641SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
1701*635a8641SAndroid Build Coastguard Worker     return true;
1702*635a8641SAndroid Build Coastguard Worker   }
1703*635a8641SAndroid Build Coastguard Worker };
1704*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendPlatformFileAndMessagePipe)1705*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendPlatformFileAndMessagePipe) {
1706*635a8641SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestSendPlatformFileAndMessagePipeClient");
1707*635a8641SAndroid Build Coastguard Worker 
1708*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1709*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
1710*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
1711*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
1712*635a8641SAndroid Build Coastguard Worker 
1713*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
1714*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1715*635a8641SAndroid Build Coastguard Worker   base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
1716*635a8641SAndroid Build Coastguard Worker                   base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1717*635a8641SAndroid Build Coastguard Worker                       base::File::FLAG_READ);
1718*635a8641SAndroid Build Coastguard Worker   TestingMessagePipe pipe;
1719*635a8641SAndroid Build Coastguard Worker   HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
1720*635a8641SAndroid Build Coastguard Worker 
1721*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1722*635a8641SAndroid Build Coastguard Worker   channel()->Close();
1723*635a8641SAndroid Build Coastguard Worker 
1724*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1725*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
1726*635a8641SAndroid Build Coastguard Worker }
1727*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileAndMessagePipeClient)1728*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1729*635a8641SAndroid Build Coastguard Worker     IPCChannelMojoTestSendPlatformFileAndMessagePipeClient) {
1730*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1731*635a8641SAndroid Build Coastguard Worker   ListenerThatExpectsFileAndMessagePipe listener(run_loop.QuitClosure());
1732*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
1733*635a8641SAndroid Build Coastguard Worker   listener.set_sender(channel());
1734*635a8641SAndroid Build Coastguard Worker 
1735*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1736*635a8641SAndroid Build Coastguard Worker 
1737*635a8641SAndroid Build Coastguard Worker   Close();
1738*635a8641SAndroid Build Coastguard Worker }
1739*635a8641SAndroid Build Coastguard Worker 
1740*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX) || defined(OS_FUCHSIA)
1741*635a8641SAndroid Build Coastguard Worker 
1742*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX)
1743*635a8641SAndroid Build Coastguard Worker 
1744*635a8641SAndroid Build Coastguard Worker const base::ProcessId kMagicChildId = 54321;
1745*635a8641SAndroid Build Coastguard Worker 
1746*635a8641SAndroid Build Coastguard Worker class ListenerThatVerifiesPeerPid : public TestListenerBase {
1747*635a8641SAndroid Build Coastguard Worker  public:
ListenerThatVerifiesPeerPid(base::OnceClosure quit_closure)1748*635a8641SAndroid Build Coastguard Worker   explicit ListenerThatVerifiesPeerPid(base::OnceClosure quit_closure)
1749*635a8641SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
1750*635a8641SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)1751*635a8641SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
1752*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(peer_pid, kMagicChildId);
1753*635a8641SAndroid Build Coastguard Worker     RunQuitClosure();
1754*635a8641SAndroid Build Coastguard Worker   }
1755*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)1756*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1757*635a8641SAndroid Build Coastguard Worker     NOTREACHED();
1758*635a8641SAndroid Build Coastguard Worker     return true;
1759*635a8641SAndroid Build Coastguard Worker   }
1760*635a8641SAndroid Build Coastguard Worker };
1761*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,VerifyGlobalPid)1762*635a8641SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
1763*635a8641SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestVerifyGlobalPidClient");
1764*635a8641SAndroid Build Coastguard Worker 
1765*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1766*635a8641SAndroid Build Coastguard Worker   ListenerThatVerifiesPeerPid listener(run_loop.QuitClosure());
1767*635a8641SAndroid Build Coastguard Worker   CreateChannel(&listener);
1768*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
1769*635a8641SAndroid Build Coastguard Worker 
1770*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1771*635a8641SAndroid Build Coastguard Worker   channel()->Close();
1772*635a8641SAndroid Build Coastguard Worker 
1773*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1774*635a8641SAndroid Build Coastguard Worker   DestroyChannel();
1775*635a8641SAndroid Build Coastguard Worker }
1776*635a8641SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient)1777*635a8641SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient) {
1778*635a8641SAndroid Build Coastguard Worker   IPC::Channel::SetGlobalPid(kMagicChildId);
1779*635a8641SAndroid Build Coastguard Worker 
1780*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1781*635a8641SAndroid Build Coastguard Worker   ListenerThatQuits listener(run_loop.QuitClosure());
1782*635a8641SAndroid Build Coastguard Worker   Connect(&listener);
1783*635a8641SAndroid Build Coastguard Worker 
1784*635a8641SAndroid Build Coastguard Worker   run_loop.Run();
1785*635a8641SAndroid Build Coastguard Worker 
1786*635a8641SAndroid Build Coastguard Worker   Close();
1787*635a8641SAndroid Build Coastguard Worker }
1788*635a8641SAndroid Build Coastguard Worker 
1789*635a8641SAndroid Build Coastguard Worker #endif  // OS_LINUX
1790*635a8641SAndroid Build Coastguard Worker 
1791*635a8641SAndroid Build Coastguard Worker }  // namespace
1792