xref: /aosp_15_r20/external/cronet/ipc/ipc_channel_mojo_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_channel_mojo.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <atomic>
11*6777b538SAndroid Build Coastguard Worker #include <cstdint>
12*6777b538SAndroid Build Coastguard Worker #include <memory>
13*6777b538SAndroid Build Coastguard Worker #include <optional>
14*6777b538SAndroid Build Coastguard Worker #include <utility>
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker #include "base/base_paths.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/containers/queue.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/files/file.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/files/scoped_temp_dir.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/memory/platform_shared_memory_region.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/memory/read_only_shared_memory_region.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/memory/shared_memory_mapping.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/memory/unsafe_shared_memory_region.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/memory/writable_shared_memory_region.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/message_loop/message_pump_type.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/path_service.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/pickle.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/process/process.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
35*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
36*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
37*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
38*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
39*6777b538SAndroid Build Coastguard Worker #include "base/test/test_io_thread.h"
40*6777b538SAndroid Build Coastguard Worker #include "base/test/test_shared_memory_util.h"
41*6777b538SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
42*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread.h"
43*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
44*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_channel_mojo_unittest.test-mojom.h"
45*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_message.h"
46*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_message_utils.h"
47*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_handle_attachment.h"
48*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_message_helper.h"
49*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_mojo_param_traits.h"
50*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_sync_channel.h"
51*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_sync_message.h"
52*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_test.mojom.h"
53*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_test_base.h"
54*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_test_channel_listener.h"
55*6777b538SAndroid Build Coastguard Worker #include "ipc/urgent_message_observer.h"
56*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/associated_receiver.h"
57*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/associated_remote.h"
58*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/features.h"
59*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/lib/validation_errors.h"
60*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
61*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
62*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/urgent_message_scope.h"
63*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/functions.h"
64*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/wait.h"
65*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
66*6777b538SAndroid Build Coastguard Worker 
67*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
68*6777b538SAndroid Build Coastguard Worker #include "base/file_descriptor_posix.h"
69*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_platform_file_attachment_posix.h"
70*6777b538SAndroid Build Coastguard Worker #endif
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker namespace ipc_channel_mojo_unittest {
73*6777b538SAndroid Build Coastguard Worker namespace {
74*6777b538SAndroid Build Coastguard Worker 
SendString(IPC::Sender * sender,const std::string & str)75*6777b538SAndroid Build Coastguard Worker void SendString(IPC::Sender* sender, const std::string& str) {
76*6777b538SAndroid Build Coastguard Worker   IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
77*6777b538SAndroid Build Coastguard Worker   message->WriteString(str);
78*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(sender->Send(message));
79*6777b538SAndroid Build Coastguard Worker }
80*6777b538SAndroid Build Coastguard Worker 
SendValue(IPC::Sender * sender,int32_t value)81*6777b538SAndroid Build Coastguard Worker void SendValue(IPC::Sender* sender, int32_t value) {
82*6777b538SAndroid Build Coastguard Worker   IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
83*6777b538SAndroid Build Coastguard Worker   message->WriteInt(value);
84*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(sender->Send(message));
85*6777b538SAndroid Build Coastguard Worker }
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker class ListenerThatExpectsOK : public IPC::Listener {
88*6777b538SAndroid Build Coastguard Worker  public:
ListenerThatExpectsOK(base::OnceClosure quit_closure)89*6777b538SAndroid Build Coastguard Worker   explicit ListenerThatExpectsOK(base::OnceClosure quit_closure)
90*6777b538SAndroid Build Coastguard Worker       : received_ok_(false), quit_closure_(std::move(quit_closure)) {}
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   ~ListenerThatExpectsOK() override = default;
93*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)94*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
95*6777b538SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
96*6777b538SAndroid Build Coastguard Worker     std::string should_be_ok;
97*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(iter.ReadString(&should_be_ok));
98*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(should_be_ok, "OK");
99*6777b538SAndroid Build Coastguard Worker     received_ok_ = true;
100*6777b538SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
101*6777b538SAndroid Build Coastguard Worker     return true;
102*6777b538SAndroid Build Coastguard Worker   }
103*6777b538SAndroid Build Coastguard Worker 
OnChannelError()104*6777b538SAndroid Build Coastguard Worker   void OnChannelError() override {
105*6777b538SAndroid Build Coastguard Worker     // The connection should be healthy while the listener is waiting
106*6777b538SAndroid Build Coastguard Worker     // message.  An error can occur after that because the peer
107*6777b538SAndroid Build Coastguard Worker     // process dies.
108*6777b538SAndroid Build Coastguard Worker     CHECK(received_ok_);
109*6777b538SAndroid Build Coastguard Worker   }
110*6777b538SAndroid Build Coastguard Worker 
SendOK(IPC::Sender * sender)111*6777b538SAndroid Build Coastguard Worker   static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker  private:
114*6777b538SAndroid Build Coastguard Worker   bool received_ok_;
115*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
116*6777b538SAndroid Build Coastguard Worker };
117*6777b538SAndroid Build Coastguard Worker 
118*6777b538SAndroid Build Coastguard Worker class TestListenerBase : public IPC::Listener {
119*6777b538SAndroid Build Coastguard Worker  public:
TestListenerBase(base::OnceClosure quit_closure)120*6777b538SAndroid Build Coastguard Worker   explicit TestListenerBase(base::OnceClosure quit_closure)
121*6777b538SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)) {}
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   ~TestListenerBase() override = default;
OnChannelError()124*6777b538SAndroid Build Coastguard Worker   void OnChannelError() override { RunQuitClosure(); }
125*6777b538SAndroid Build Coastguard Worker 
set_sender(IPC::Sender * sender)126*6777b538SAndroid Build Coastguard Worker   void set_sender(IPC::Sender* sender) { sender_ = sender; }
sender() const127*6777b538SAndroid Build Coastguard Worker   IPC::Sender* sender() const { return sender_; }
RunQuitClosure()128*6777b538SAndroid Build Coastguard Worker   void RunQuitClosure() {
129*6777b538SAndroid Build Coastguard Worker     if (quit_closure_)
130*6777b538SAndroid Build Coastguard Worker       std::move(quit_closure_).Run();
131*6777b538SAndroid Build Coastguard Worker   }
132*6777b538SAndroid Build Coastguard Worker 
133*6777b538SAndroid Build Coastguard Worker  private:
134*6777b538SAndroid Build Coastguard Worker   raw_ptr<IPC::Sender> sender_ = nullptr;
135*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
136*6777b538SAndroid Build Coastguard Worker };
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker using IPCChannelMojoTest = IPCChannelMojoTestBase;
139*6777b538SAndroid Build Coastguard Worker 
140*6777b538SAndroid Build Coastguard Worker class TestChannelListenerWithExtraExpectations
141*6777b538SAndroid Build Coastguard Worker     : public IPC::TestChannelListener {
142*6777b538SAndroid Build Coastguard Worker  public:
TestChannelListenerWithExtraExpectations()143*6777b538SAndroid Build Coastguard Worker   TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
144*6777b538SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)145*6777b538SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
146*6777b538SAndroid Build Coastguard Worker     IPC::TestChannelListener::OnChannelConnected(peer_pid);
147*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(base::kNullProcessId != peer_pid);
148*6777b538SAndroid Build Coastguard Worker     is_connected_called_ = true;
149*6777b538SAndroid Build Coastguard Worker   }
150*6777b538SAndroid Build Coastguard Worker 
is_connected_called() const151*6777b538SAndroid Build Coastguard Worker   bool is_connected_called() const { return is_connected_called_; }
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker  private:
154*6777b538SAndroid Build Coastguard Worker   bool is_connected_called_;
155*6777b538SAndroid Build Coastguard Worker };
156*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,ConnectedFromClient)157*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
158*6777b538SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestClient");
159*6777b538SAndroid Build Coastguard Worker 
160*6777b538SAndroid Build Coastguard Worker   // Set up IPC channel and start client.
161*6777b538SAndroid Build Coastguard Worker   TestChannelListenerWithExtraExpectations listener;
162*6777b538SAndroid Build Coastguard Worker   base::RunLoop loop;
163*6777b538SAndroid Build Coastguard Worker   listener.set_quit_closure(loop.QuitWhenIdleClosure());
164*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
165*6777b538SAndroid Build Coastguard Worker   listener.Init(sender());
166*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
167*6777b538SAndroid Build Coastguard Worker 
168*6777b538SAndroid Build Coastguard Worker   IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
169*6777b538SAndroid Build Coastguard Worker   loop.Run();
170*6777b538SAndroid Build Coastguard Worker 
171*6777b538SAndroid Build Coastguard Worker   channel()->Close();
172*6777b538SAndroid Build Coastguard Worker 
173*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
174*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.is_connected_called());
175*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.HasSentAll());
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
178*6777b538SAndroid Build Coastguard Worker }
179*6777b538SAndroid Build Coastguard Worker 
180*6777b538SAndroid Build Coastguard Worker // A long running process that connects to us
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient)181*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient) {
182*6777b538SAndroid Build Coastguard Worker   TestChannelListenerWithExtraExpectations listener;
183*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
184*6777b538SAndroid Build Coastguard Worker   listener.Init(channel());
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker   IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
187*6777b538SAndroid Build Coastguard Worker   base::RunLoop loop;
188*6777b538SAndroid Build Coastguard Worker   listener.set_quit_closure(loop.QuitWhenIdleClosure());
189*6777b538SAndroid Build Coastguard Worker   loop.Run();
190*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.is_connected_called());
191*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.HasSentAll());
192*6777b538SAndroid Build Coastguard Worker 
193*6777b538SAndroid Build Coastguard Worker   Close();
194*6777b538SAndroid Build Coastguard Worker }
195*6777b538SAndroid Build Coastguard Worker 
196*6777b538SAndroid Build Coastguard Worker class ListenerExpectingErrors : public TestListenerBase {
197*6777b538SAndroid Build Coastguard Worker  public:
ListenerExpectingErrors(base::OnceClosure quit_closure)198*6777b538SAndroid Build Coastguard Worker   ListenerExpectingErrors(base::OnceClosure quit_closure)
199*6777b538SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)), has_error_(false) {}
200*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)201*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
202*6777b538SAndroid Build Coastguard Worker 
OnChannelError()203*6777b538SAndroid Build Coastguard Worker   void OnChannelError() override {
204*6777b538SAndroid Build Coastguard Worker     has_error_ = true;
205*6777b538SAndroid Build Coastguard Worker     TestListenerBase::OnChannelError();
206*6777b538SAndroid Build Coastguard Worker   }
207*6777b538SAndroid Build Coastguard Worker 
has_error() const208*6777b538SAndroid Build Coastguard Worker   bool has_error() const { return has_error_; }
209*6777b538SAndroid Build Coastguard Worker 
210*6777b538SAndroid Build Coastguard Worker  private:
211*6777b538SAndroid Build Coastguard Worker   bool has_error_;
212*6777b538SAndroid Build Coastguard Worker };
213*6777b538SAndroid Build Coastguard Worker 
214*6777b538SAndroid Build Coastguard Worker class ListenerThatQuits : public IPC::Listener {
215*6777b538SAndroid Build Coastguard Worker  public:
ListenerThatQuits(base::OnceClosure quit_closure)216*6777b538SAndroid Build Coastguard Worker   explicit ListenerThatQuits(base::OnceClosure quit_closure)
217*6777b538SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)) {}
218*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)219*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
220*6777b538SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)221*6777b538SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
222*6777b538SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
223*6777b538SAndroid Build Coastguard Worker   }
224*6777b538SAndroid Build Coastguard Worker 
225*6777b538SAndroid Build Coastguard Worker  private:
226*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
227*6777b538SAndroid Build Coastguard Worker };
228*6777b538SAndroid Build Coastguard Worker 
229*6777b538SAndroid Build Coastguard Worker // A long running process that connects to us.
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient)230*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient) {
231*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
232*6777b538SAndroid Build Coastguard Worker   ListenerThatQuits listener(run_loop.QuitClosure());
233*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
234*6777b538SAndroid Build Coastguard Worker 
235*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
236*6777b538SAndroid Build Coastguard Worker 
237*6777b538SAndroid Build Coastguard Worker   Close();
238*6777b538SAndroid Build Coastguard Worker }
239*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendFailWithPendingMessages)240*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
241*6777b538SAndroid Build Coastguard Worker   Init("IPCChannelMojoErraticTestClient");
242*6777b538SAndroid Build Coastguard Worker 
243*6777b538SAndroid Build Coastguard Worker   // Set up IPC channel and start client.
244*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
245*6777b538SAndroid Build Coastguard Worker   ListenerExpectingErrors listener(run_loop.QuitClosure());
246*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
247*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
248*6777b538SAndroid Build Coastguard Worker 
249*6777b538SAndroid Build Coastguard Worker   // This matches a value in mojo/edk/system/constants.h
250*6777b538SAndroid Build Coastguard Worker   const int kMaxMessageNumBytes = 4 * 1024 * 1024;
251*6777b538SAndroid Build Coastguard Worker   std::string overly_large_data(kMaxMessageNumBytes, '*');
252*6777b538SAndroid Build Coastguard Worker   // This messages are queued as pending.
253*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < 10; ++i) {
254*6777b538SAndroid Build Coastguard Worker     IPC::TestChannelListener::SendOneMessage(sender(),
255*6777b538SAndroid Build Coastguard Worker                                              overly_large_data.c_str());
256*6777b538SAndroid Build Coastguard Worker   }
257*6777b538SAndroid Build Coastguard Worker 
258*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
259*6777b538SAndroid Build Coastguard Worker 
260*6777b538SAndroid Build Coastguard Worker   channel()->Close();
261*6777b538SAndroid Build Coastguard Worker 
262*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
263*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.has_error());
264*6777b538SAndroid Build Coastguard Worker 
265*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
266*6777b538SAndroid Build Coastguard Worker }
267*6777b538SAndroid Build Coastguard Worker 
268*6777b538SAndroid Build Coastguard Worker class ListenerThatBindsATestStructPasser : public IPC::Listener,
269*6777b538SAndroid Build Coastguard Worker                                            public IPC::mojom::TestStructPasser {
270*6777b538SAndroid Build Coastguard Worker  public:
271*6777b538SAndroid Build Coastguard Worker   ListenerThatBindsATestStructPasser() = default;
272*6777b538SAndroid Build Coastguard Worker   ~ListenerThatBindsATestStructPasser() override = default;
273*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)274*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
275*6777b538SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)276*6777b538SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {}
277*6777b538SAndroid Build Coastguard Worker 
OnChannelError()278*6777b538SAndroid Build Coastguard Worker   void OnChannelError() override { NOTREACHED(); }
279*6777b538SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)280*6777b538SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
281*6777b538SAndroid Build Coastguard Worker       const std::string& interface_name,
282*6777b538SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
283*6777b538SAndroid Build Coastguard Worker     CHECK_EQ(interface_name, IPC::mojom::TestStructPasser::Name_);
284*6777b538SAndroid Build Coastguard Worker     receiver_.Bind(
285*6777b538SAndroid Build Coastguard Worker         mojo::PendingAssociatedReceiver<IPC::mojom::TestStructPasser>(
286*6777b538SAndroid Build Coastguard Worker             std::move(handle)));
287*6777b538SAndroid Build Coastguard Worker   }
288*6777b538SAndroid Build Coastguard Worker 
289*6777b538SAndroid Build Coastguard Worker  private:
290*6777b538SAndroid Build Coastguard Worker   // IPC::mojom::TestStructPasser:
Pass(IPC::mojom::TestStructPtr)291*6777b538SAndroid Build Coastguard Worker   void Pass(IPC::mojom::TestStructPtr) override { NOTREACHED(); }
292*6777b538SAndroid Build Coastguard Worker 
293*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedReceiver<IPC::mojom::TestStructPasser> receiver_{this};
294*6777b538SAndroid Build Coastguard Worker };
295*6777b538SAndroid Build Coastguard Worker 
296*6777b538SAndroid Build Coastguard Worker class ListenerThatExpectsNoError : public IPC::Listener {
297*6777b538SAndroid Build Coastguard Worker  public:
ListenerThatExpectsNoError(base::OnceClosure connect_closure,base::OnceClosure quit_closure)298*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsNoError(base::OnceClosure connect_closure,
299*6777b538SAndroid Build Coastguard Worker                              base::OnceClosure quit_closure)
300*6777b538SAndroid Build Coastguard Worker       : connect_closure_(std::move(connect_closure)),
301*6777b538SAndroid Build Coastguard Worker         quit_closure_(std::move(quit_closure)) {}
302*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)303*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
304*6777b538SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
305*6777b538SAndroid Build Coastguard Worker     std::string should_be_ok;
306*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(iter.ReadString(&should_be_ok));
307*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(should_be_ok, "OK");
308*6777b538SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
309*6777b538SAndroid Build Coastguard Worker     return true;
310*6777b538SAndroid Build Coastguard Worker   }
311*6777b538SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)312*6777b538SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
313*6777b538SAndroid Build Coastguard Worker     std::move(connect_closure_).Run();
314*6777b538SAndroid Build Coastguard Worker   }
315*6777b538SAndroid Build Coastguard Worker 
OnChannelError()316*6777b538SAndroid Build Coastguard Worker   void OnChannelError() override { NOTREACHED(); }
317*6777b538SAndroid Build Coastguard Worker 
318*6777b538SAndroid Build Coastguard Worker  private:
319*6777b538SAndroid Build Coastguard Worker   base::OnceClosure connect_closure_;
320*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
321*6777b538SAndroid Build Coastguard Worker };
322*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoNoImplicitChanelClosureClient)323*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
324*6777b538SAndroid Build Coastguard Worker     IPCChannelMojoNoImplicitChanelClosureClient) {
325*6777b538SAndroid Build Coastguard Worker   base::RunLoop wait_to_connect_loop;
326*6777b538SAndroid Build Coastguard Worker   base::RunLoop wait_to_quit_loop;
327*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsNoError listener(wait_to_connect_loop.QuitClosure(),
328*6777b538SAndroid Build Coastguard Worker                                       wait_to_quit_loop.QuitClosure());
329*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
330*6777b538SAndroid Build Coastguard Worker   wait_to_connect_loop.Run();
331*6777b538SAndroid Build Coastguard Worker 
332*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::TestStructPasser> passer;
333*6777b538SAndroid Build Coastguard Worker   channel()->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
334*6777b538SAndroid Build Coastguard Worker       passer.BindNewEndpointAndPassReceiver());
335*6777b538SAndroid Build Coastguard Worker 
336*6777b538SAndroid Build Coastguard Worker   // This avoids hitting DCHECKs in the serialization code meant to stop us from
337*6777b538SAndroid Build Coastguard Worker   // making such "mistakes" as the one we're about to make below.
338*6777b538SAndroid Build Coastguard Worker   mojo::internal::SerializationWarningObserverForTesting suppress_those_dchecks;
339*6777b538SAndroid Build Coastguard Worker 
340*6777b538SAndroid Build Coastguard Worker   // Send an invalid message. The TestStruct argument is not allowed to be null.
341*6777b538SAndroid Build Coastguard Worker   // This will elicit a validation error in the parent process, but should not
342*6777b538SAndroid Build Coastguard Worker   // actually disconnect the channel.
343*6777b538SAndroid Build Coastguard Worker   passer->Pass(nullptr);
344*6777b538SAndroid Build Coastguard Worker 
345*6777b538SAndroid Build Coastguard Worker   // Wait until the parent says it's OK to quit, so it has time to verify its
346*6777b538SAndroid Build Coastguard Worker   // expected behavior.
347*6777b538SAndroid Build Coastguard Worker   wait_to_quit_loop.Run();
348*6777b538SAndroid Build Coastguard Worker 
349*6777b538SAndroid Build Coastguard Worker   Close();
350*6777b538SAndroid Build Coastguard Worker }
351*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,NoImplicitChannelClosure)352*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, NoImplicitChannelClosure) {
353*6777b538SAndroid Build Coastguard Worker   // Verifies that OnChannelError is not invoked due to conditions other than
354*6777b538SAndroid Build Coastguard Worker   // peer closure (e.g. a malformed inbound message). Instead we should always
355*6777b538SAndroid Build Coastguard Worker   // be able to handle validation errors via Mojo bad message reporting.
356*6777b538SAndroid Build Coastguard Worker 
357*6777b538SAndroid Build Coastguard Worker   // NOTE: We can't create a RunLoop before Init() is called, but we have to set
358*6777b538SAndroid Build Coastguard Worker   // the default ProcessErrorCallback (which we want to reference the RunLoop)
359*6777b538SAndroid Build Coastguard Worker   // before Init() launches a child process. Hence the std::optional here.
360*6777b538SAndroid Build Coastguard Worker   std::optional<base::RunLoop> wait_for_error_loop;
361*6777b538SAndroid Build Coastguard Worker   bool process_error_received = false;
362*6777b538SAndroid Build Coastguard Worker   mojo::SetDefaultProcessErrorHandler(
363*6777b538SAndroid Build Coastguard Worker       base::BindLambdaForTesting([&](const std::string&) {
364*6777b538SAndroid Build Coastguard Worker         process_error_received = true;
365*6777b538SAndroid Build Coastguard Worker         wait_for_error_loop->Quit();
366*6777b538SAndroid Build Coastguard Worker       }));
367*6777b538SAndroid Build Coastguard Worker 
368*6777b538SAndroid Build Coastguard Worker   Init("IPCChannelMojoNoImplicitChanelClosureClient");
369*6777b538SAndroid Build Coastguard Worker 
370*6777b538SAndroid Build Coastguard Worker   wait_for_error_loop.emplace();
371*6777b538SAndroid Build Coastguard Worker   ListenerThatBindsATestStructPasser listener;
372*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
373*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
374*6777b538SAndroid Build Coastguard Worker 
375*6777b538SAndroid Build Coastguard Worker   wait_for_error_loop->Run();
376*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(process_error_received);
377*6777b538SAndroid Build Coastguard Worker   mojo::SetDefaultProcessErrorHandler(base::NullCallback());
378*6777b538SAndroid Build Coastguard Worker 
379*6777b538SAndroid Build Coastguard Worker   // Tell the child it can quit and wait for it to shut down.
380*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsOK::SendOK(channel());
381*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
382*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
383*6777b538SAndroid Build Coastguard Worker }
384*6777b538SAndroid Build Coastguard Worker 
385*6777b538SAndroid Build Coastguard Worker struct TestingMessagePipe {
TestingMessagePipeipc_channel_mojo_unittest::__anon598173270111::TestingMessagePipe386*6777b538SAndroid Build Coastguard Worker   TestingMessagePipe() {
387*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
388*6777b538SAndroid Build Coastguard Worker   }
389*6777b538SAndroid Build Coastguard Worker 
390*6777b538SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle self;
391*6777b538SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle peer;
392*6777b538SAndroid Build Coastguard Worker };
393*6777b538SAndroid Build Coastguard Worker 
394*6777b538SAndroid Build Coastguard Worker class HandleSendingHelper {
395*6777b538SAndroid Build Coastguard Worker  public:
GetSendingFileContent()396*6777b538SAndroid Build Coastguard Worker   static std::string GetSendingFileContent() { return "Hello"; }
397*6777b538SAndroid Build Coastguard Worker 
WritePipe(IPC::Message * message,TestingMessagePipe * pipe)398*6777b538SAndroid Build Coastguard Worker   static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
399*6777b538SAndroid Build Coastguard Worker     std::string content = HandleSendingHelper::GetSendingFileContent();
400*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(MOJO_RESULT_OK,
401*6777b538SAndroid Build Coastguard Worker               mojo::WriteMessageRaw(pipe->self.get(), &content[0],
402*6777b538SAndroid Build Coastguard Worker                                     static_cast<uint32_t>(content.size()),
403*6777b538SAndroid Build Coastguard Worker                                     nullptr, 0, 0));
404*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
405*6777b538SAndroid Build Coastguard Worker         message, std::move(pipe->peer)));
406*6777b538SAndroid Build Coastguard Worker   }
407*6777b538SAndroid Build Coastguard Worker 
WritePipeThenSend(IPC::Sender * sender,TestingMessagePipe * pipe)408*6777b538SAndroid Build Coastguard Worker   static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
409*6777b538SAndroid Build Coastguard Worker     IPC::Message* message =
410*6777b538SAndroid Build Coastguard Worker         new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
411*6777b538SAndroid Build Coastguard Worker     WritePipe(message, pipe);
412*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(sender->Send(message));
413*6777b538SAndroid Build Coastguard Worker   }
414*6777b538SAndroid Build Coastguard Worker 
ReadReceivedPipe(const IPC::Message & message,base::PickleIterator * iter)415*6777b538SAndroid Build Coastguard Worker   static void ReadReceivedPipe(const IPC::Message& message,
416*6777b538SAndroid Build Coastguard Worker                                base::PickleIterator* iter) {
417*6777b538SAndroid Build Coastguard Worker     mojo::ScopedMessagePipeHandle pipe;
418*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(
419*6777b538SAndroid Build Coastguard Worker         IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
420*6777b538SAndroid Build Coastguard Worker     std::vector<uint8_t> content;
421*6777b538SAndroid Build Coastguard Worker 
422*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(MOJO_RESULT_OK,
423*6777b538SAndroid Build Coastguard Worker               mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE));
424*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(MOJO_RESULT_OK,
425*6777b538SAndroid Build Coastguard Worker               mojo::ReadMessageRaw(pipe.get(), &content, nullptr, 0));
426*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(std::string(content.begin(), content.end()),
427*6777b538SAndroid Build Coastguard Worker               GetSendingFileContent());
428*6777b538SAndroid Build Coastguard Worker   }
429*6777b538SAndroid Build Coastguard Worker 
430*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
GetSendingFilePath(const base::FilePath & dir_path)431*6777b538SAndroid Build Coastguard Worker   static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
432*6777b538SAndroid Build Coastguard Worker     return dir_path.Append("ListenerThatExpectsFile.txt");
433*6777b538SAndroid Build Coastguard Worker   }
434*6777b538SAndroid Build Coastguard Worker 
WriteFile(IPC::Message * message,base::File & file)435*6777b538SAndroid Build Coastguard Worker   static void WriteFile(IPC::Message* message, base::File& file) {
436*6777b538SAndroid Build Coastguard Worker     std::string content = GetSendingFileContent();
437*6777b538SAndroid Build Coastguard Worker     file.WriteAtCurrentPos(content.data(), content.size());
438*6777b538SAndroid Build Coastguard Worker     file.Flush();
439*6777b538SAndroid Build Coastguard Worker     message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
440*6777b538SAndroid Build Coastguard Worker         base::ScopedFD(file.TakePlatformFile())));
441*6777b538SAndroid Build Coastguard Worker   }
442*6777b538SAndroid Build Coastguard Worker 
WriteFileThenSend(IPC::Sender * sender,base::File & file)443*6777b538SAndroid Build Coastguard Worker   static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
444*6777b538SAndroid Build Coastguard Worker     IPC::Message* message =
445*6777b538SAndroid Build Coastguard Worker         new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
446*6777b538SAndroid Build Coastguard Worker     WriteFile(message, file);
447*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(sender->Send(message));
448*6777b538SAndroid Build Coastguard Worker   }
449*6777b538SAndroid Build Coastguard Worker 
WriteFileAndPipeThenSend(IPC::Sender * sender,base::File & file,TestingMessagePipe * pipe)450*6777b538SAndroid Build Coastguard Worker   static void WriteFileAndPipeThenSend(IPC::Sender* sender,
451*6777b538SAndroid Build Coastguard Worker                                        base::File& file,
452*6777b538SAndroid Build Coastguard Worker                                        TestingMessagePipe* pipe) {
453*6777b538SAndroid Build Coastguard Worker     IPC::Message* message =
454*6777b538SAndroid Build Coastguard Worker         new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
455*6777b538SAndroid Build Coastguard Worker     WriteFile(message, file);
456*6777b538SAndroid Build Coastguard Worker     WritePipe(message, pipe);
457*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(sender->Send(message));
458*6777b538SAndroid Build Coastguard Worker   }
459*6777b538SAndroid Build Coastguard Worker 
ReadReceivedFile(const IPC::Message & message,base::PickleIterator * iter)460*6777b538SAndroid Build Coastguard Worker   static void ReadReceivedFile(const IPC::Message& message,
461*6777b538SAndroid Build Coastguard Worker                                base::PickleIterator* iter) {
462*6777b538SAndroid Build Coastguard Worker     scoped_refptr<base::Pickle::Attachment> attachment;
463*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
464*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(
465*6777b538SAndroid Build Coastguard Worker         IPC::MessageAttachment::Type::PLATFORM_FILE,
466*6777b538SAndroid Build Coastguard Worker         static_cast<IPC::MessageAttachment*>(attachment.get())->GetType());
467*6777b538SAndroid Build Coastguard Worker     base::File file(
468*6777b538SAndroid Build Coastguard Worker         static_cast<IPC::internal::PlatformFileAttachment*>(attachment.get())
469*6777b538SAndroid Build Coastguard Worker             ->TakePlatformFile());
470*6777b538SAndroid Build Coastguard Worker     std::string content(GetSendingFileContent().size(), ' ');
471*6777b538SAndroid Build Coastguard Worker     file.Read(0, &content[0], content.size());
472*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(content, GetSendingFileContent());
473*6777b538SAndroid Build Coastguard Worker   }
474*6777b538SAndroid Build Coastguard Worker #endif
475*6777b538SAndroid Build Coastguard Worker };
476*6777b538SAndroid Build Coastguard Worker 
477*6777b538SAndroid Build Coastguard Worker class ListenerThatExpectsMessagePipe : public TestListenerBase {
478*6777b538SAndroid Build Coastguard Worker  public:
ListenerThatExpectsMessagePipe(base::OnceClosure quit_closure)479*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsMessagePipe(base::OnceClosure quit_closure)
480*6777b538SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
481*6777b538SAndroid Build Coastguard Worker 
482*6777b538SAndroid Build Coastguard Worker   ~ListenerThatExpectsMessagePipe() override = default;
483*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)484*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
485*6777b538SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
486*6777b538SAndroid Build Coastguard Worker     HandleSendingHelper::ReadReceivedPipe(message, &iter);
487*6777b538SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
488*6777b538SAndroid Build Coastguard Worker     return true;
489*6777b538SAndroid Build Coastguard Worker   }
490*6777b538SAndroid Build Coastguard Worker };
491*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendMessagePipe)492*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendMessagePipe) {
493*6777b538SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestSendMessagePipeClient");
494*6777b538SAndroid Build Coastguard Worker 
495*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
496*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
497*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
498*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
499*6777b538SAndroid Build Coastguard Worker 
500*6777b538SAndroid Build Coastguard Worker   TestingMessagePipe pipe;
501*6777b538SAndroid Build Coastguard Worker   HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
502*6777b538SAndroid Build Coastguard Worker 
503*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
504*6777b538SAndroid Build Coastguard Worker   channel()->Close();
505*6777b538SAndroid Build Coastguard Worker 
506*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
507*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
508*6777b538SAndroid Build Coastguard Worker }
509*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient)510*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient) {
511*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
512*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsMessagePipe listener(run_loop.QuitClosure());
513*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
514*6777b538SAndroid Build Coastguard Worker   listener.set_sender(channel());
515*6777b538SAndroid Build Coastguard Worker 
516*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
517*6777b538SAndroid Build Coastguard Worker 
518*6777b538SAndroid Build Coastguard Worker   Close();
519*6777b538SAndroid Build Coastguard Worker }
520*6777b538SAndroid Build Coastguard Worker 
ReadOK(mojo::MessagePipeHandle pipe)521*6777b538SAndroid Build Coastguard Worker void ReadOK(mojo::MessagePipeHandle pipe) {
522*6777b538SAndroid Build Coastguard Worker   std::vector<uint8_t> should_be_ok;
523*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE));
524*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(MOJO_RESULT_OK,
525*6777b538SAndroid Build Coastguard Worker            mojo::ReadMessageRaw(pipe, &should_be_ok, nullptr, 0));
526*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("OK", std::string(should_be_ok.begin(), should_be_ok.end()));
527*6777b538SAndroid Build Coastguard Worker }
528*6777b538SAndroid Build Coastguard Worker 
WriteOK(mojo::MessagePipeHandle pipe)529*6777b538SAndroid Build Coastguard Worker void WriteOK(mojo::MessagePipeHandle pipe) {
530*6777b538SAndroid Build Coastguard Worker   std::string ok("OK");
531*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(MOJO_RESULT_OK,
532*6777b538SAndroid Build Coastguard Worker            mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
533*6777b538SAndroid Build Coastguard Worker                                  nullptr, 0, 0));
534*6777b538SAndroid Build Coastguard Worker }
535*6777b538SAndroid Build Coastguard Worker 
536*6777b538SAndroid Build Coastguard Worker class ListenerThatExpectsMessagePipeUsingParamTrait : public TestListenerBase {
537*6777b538SAndroid Build Coastguard Worker  public:
ListenerThatExpectsMessagePipeUsingParamTrait(base::OnceClosure quit_closure,bool receiving_valid)538*6777b538SAndroid Build Coastguard Worker   explicit ListenerThatExpectsMessagePipeUsingParamTrait(
539*6777b538SAndroid Build Coastguard Worker       base::OnceClosure quit_closure,
540*6777b538SAndroid Build Coastguard Worker       bool receiving_valid)
541*6777b538SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)),
542*6777b538SAndroid Build Coastguard Worker         receiving_valid_(receiving_valid) {}
543*6777b538SAndroid Build Coastguard Worker 
544*6777b538SAndroid Build Coastguard Worker   ~ListenerThatExpectsMessagePipeUsingParamTrait() override = default;
545*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)546*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
547*6777b538SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
548*6777b538SAndroid Build Coastguard Worker     mojo::MessagePipeHandle handle;
549*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
550*6777b538SAndroid Build Coastguard Worker                                                                 &handle));
551*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(handle.is_valid(), receiving_valid_);
552*6777b538SAndroid Build Coastguard Worker     if (receiving_valid_) {
553*6777b538SAndroid Build Coastguard Worker       ReadOK(handle);
554*6777b538SAndroid Build Coastguard Worker       MojoClose(handle.value());
555*6777b538SAndroid Build Coastguard Worker     }
556*6777b538SAndroid Build Coastguard Worker 
557*6777b538SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
558*6777b538SAndroid Build Coastguard Worker     return true;
559*6777b538SAndroid Build Coastguard Worker   }
560*6777b538SAndroid Build Coastguard Worker 
561*6777b538SAndroid Build Coastguard Worker  private:
562*6777b538SAndroid Build Coastguard Worker   bool receiving_valid_;
563*6777b538SAndroid Build Coastguard Worker };
564*6777b538SAndroid Build Coastguard Worker 
565*6777b538SAndroid Build Coastguard Worker class ParamTraitMessagePipeClient : public IpcChannelMojoTestClient {
566*6777b538SAndroid Build Coastguard Worker  public:
RunTest(bool receiving_valid_handle)567*6777b538SAndroid Build Coastguard Worker   void RunTest(bool receiving_valid_handle) {
568*6777b538SAndroid Build Coastguard Worker     base::RunLoop run_loop;
569*6777b538SAndroid Build Coastguard Worker     ListenerThatExpectsMessagePipeUsingParamTrait listener(
570*6777b538SAndroid Build Coastguard Worker         run_loop.QuitClosure(), receiving_valid_handle);
571*6777b538SAndroid Build Coastguard Worker     Connect(&listener);
572*6777b538SAndroid Build Coastguard Worker     listener.set_sender(channel());
573*6777b538SAndroid Build Coastguard Worker 
574*6777b538SAndroid Build Coastguard Worker     run_loop.Run();
575*6777b538SAndroid Build Coastguard Worker 
576*6777b538SAndroid Build Coastguard Worker     Close();
577*6777b538SAndroid Build Coastguard Worker   }
578*6777b538SAndroid Build Coastguard Worker };
579*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,ParamTraitValidMessagePipe)580*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
581*6777b538SAndroid Build Coastguard Worker   Init("ParamTraitValidMessagePipeClient");
582*6777b538SAndroid Build Coastguard Worker 
583*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
584*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
585*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
586*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
587*6777b538SAndroid Build Coastguard Worker 
588*6777b538SAndroid Build Coastguard Worker   TestingMessagePipe pipe;
589*6777b538SAndroid Build Coastguard Worker 
590*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<IPC::Message> message(new IPC::Message());
591*6777b538SAndroid Build Coastguard Worker   IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
592*6777b538SAndroid Build Coastguard Worker                                                    pipe.peer.release());
593*6777b538SAndroid Build Coastguard Worker   WriteOK(pipe.self.get());
594*6777b538SAndroid Build Coastguard Worker 
595*6777b538SAndroid Build Coastguard Worker   channel()->Send(message.release());
596*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
597*6777b538SAndroid Build Coastguard Worker   channel()->Close();
598*6777b538SAndroid Build Coastguard Worker 
599*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
600*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
601*6777b538SAndroid Build Coastguard Worker }
602*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ParamTraitValidMessagePipeClient,ParamTraitMessagePipeClient)603*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
604*6777b538SAndroid Build Coastguard Worker     ParamTraitValidMessagePipeClient,
605*6777b538SAndroid Build Coastguard Worker     ParamTraitMessagePipeClient) {
606*6777b538SAndroid Build Coastguard Worker   RunTest(true);
607*6777b538SAndroid Build Coastguard Worker }
608*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,ParamTraitInvalidMessagePipe)609*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
610*6777b538SAndroid Build Coastguard Worker   Init("ParamTraitInvalidMessagePipeClient");
611*6777b538SAndroid Build Coastguard Worker 
612*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
613*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
614*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
615*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
616*6777b538SAndroid Build Coastguard Worker 
617*6777b538SAndroid Build Coastguard Worker   mojo::MessagePipeHandle invalid_handle;
618*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<IPC::Message> message(new IPC::Message());
619*6777b538SAndroid Build Coastguard Worker   IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
620*6777b538SAndroid Build Coastguard Worker                                                    invalid_handle);
621*6777b538SAndroid Build Coastguard Worker 
622*6777b538SAndroid Build Coastguard Worker   channel()->Send(message.release());
623*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
624*6777b538SAndroid Build Coastguard Worker   channel()->Close();
625*6777b538SAndroid Build Coastguard Worker 
626*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
627*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
628*6777b538SAndroid Build Coastguard Worker }
629*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ParamTraitInvalidMessagePipeClient,ParamTraitMessagePipeClient)630*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
631*6777b538SAndroid Build Coastguard Worker     ParamTraitInvalidMessagePipeClient,
632*6777b538SAndroid Build Coastguard Worker     ParamTraitMessagePipeClient) {
633*6777b538SAndroid Build Coastguard Worker   RunTest(false);
634*6777b538SAndroid Build Coastguard Worker }
635*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendFailAfterClose)636*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
637*6777b538SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestSendOkClient");
638*6777b538SAndroid Build Coastguard Worker 
639*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
640*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
641*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
642*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
643*6777b538SAndroid Build Coastguard Worker 
644*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
645*6777b538SAndroid Build Coastguard Worker   channel()->Close();
646*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(channel()->Send(new IPC::Message()));
647*6777b538SAndroid Build Coastguard Worker 
648*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
649*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
650*6777b538SAndroid Build Coastguard Worker }
651*6777b538SAndroid Build Coastguard Worker 
652*6777b538SAndroid Build Coastguard Worker class ListenerSendingOneOk : public TestListenerBase {
653*6777b538SAndroid Build Coastguard Worker  public:
ListenerSendingOneOk(base::OnceClosure quit_closure)654*6777b538SAndroid Build Coastguard Worker   ListenerSendingOneOk(base::OnceClosure quit_closure)
655*6777b538SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
656*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)657*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
658*6777b538SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)659*6777b538SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
660*6777b538SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
661*6777b538SAndroid Build Coastguard Worker     RunQuitClosure();
662*6777b538SAndroid Build Coastguard Worker   }
663*6777b538SAndroid Build Coastguard Worker };
664*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient)665*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient) {
666*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
667*6777b538SAndroid Build Coastguard Worker   ListenerSendingOneOk listener(run_loop.QuitClosure());
668*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
669*6777b538SAndroid Build Coastguard Worker   listener.set_sender(channel());
670*6777b538SAndroid Build Coastguard Worker 
671*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
672*6777b538SAndroid Build Coastguard Worker 
673*6777b538SAndroid Build Coastguard Worker   Close();
674*6777b538SAndroid Build Coastguard Worker }
675*6777b538SAndroid Build Coastguard Worker 
676*6777b538SAndroid Build Coastguard Worker class ListenerWithSimpleAssociatedInterface
677*6777b538SAndroid Build Coastguard Worker     : public IPC::Listener,
678*6777b538SAndroid Build Coastguard Worker       public IPC::mojom::SimpleTestDriver {
679*6777b538SAndroid Build Coastguard Worker  public:
680*6777b538SAndroid Build Coastguard Worker   static const int kNumMessages;
681*6777b538SAndroid Build Coastguard Worker 
ListenerWithSimpleAssociatedInterface(base::OnceClosure quit_closure)682*6777b538SAndroid Build Coastguard Worker   explicit ListenerWithSimpleAssociatedInterface(base::OnceClosure quit_closure)
683*6777b538SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)) {}
684*6777b538SAndroid Build Coastguard Worker 
685*6777b538SAndroid Build Coastguard Worker   ~ListenerWithSimpleAssociatedInterface() override = default;
686*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)687*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
688*6777b538SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
689*6777b538SAndroid Build Coastguard Worker     int32_t should_be_expected;
690*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(iter.ReadInt(&should_be_expected));
691*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(should_be_expected, next_expected_value_);
692*6777b538SAndroid Build Coastguard Worker     num_messages_received_++;
693*6777b538SAndroid Build Coastguard Worker     return true;
694*6777b538SAndroid Build Coastguard Worker   }
695*6777b538SAndroid Build Coastguard Worker 
OnChannelError()696*6777b538SAndroid Build Coastguard Worker   void OnChannelError() override { CHECK(!quit_closure_); }
697*6777b538SAndroid Build Coastguard Worker 
RegisterInterfaceFactory(IPC::Channel * channel)698*6777b538SAndroid Build Coastguard Worker   void RegisterInterfaceFactory(IPC::Channel* channel) {
699*6777b538SAndroid Build Coastguard Worker     channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
700*6777b538SAndroid Build Coastguard Worker         base::BindRepeating(
701*6777b538SAndroid Build Coastguard Worker             &ListenerWithSimpleAssociatedInterface::BindReceiver,
702*6777b538SAndroid Build Coastguard Worker             base::Unretained(this)));
703*6777b538SAndroid Build Coastguard Worker   }
704*6777b538SAndroid Build Coastguard Worker 
705*6777b538SAndroid Build Coastguard Worker  private:
706*6777b538SAndroid Build Coastguard Worker   // IPC::mojom::SimpleTestDriver:
ExpectValue(int32_t value)707*6777b538SAndroid Build Coastguard Worker   void ExpectValue(int32_t value) override {
708*6777b538SAndroid Build Coastguard Worker     next_expected_value_ = value;
709*6777b538SAndroid Build Coastguard Worker   }
710*6777b538SAndroid Build Coastguard Worker 
GetExpectedValue(GetExpectedValueCallback callback)711*6777b538SAndroid Build Coastguard Worker   void GetExpectedValue(GetExpectedValueCallback callback) override {
712*6777b538SAndroid Build Coastguard Worker     NOTREACHED();
713*6777b538SAndroid Build Coastguard Worker   }
714*6777b538SAndroid Build Coastguard Worker 
RequestValue(RequestValueCallback callback)715*6777b538SAndroid Build Coastguard Worker   void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
716*6777b538SAndroid Build Coastguard Worker 
RequestQuit(RequestQuitCallback callback)717*6777b538SAndroid Build Coastguard Worker   void RequestQuit(RequestQuitCallback callback) override {
718*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kNumMessages, num_messages_received_);
719*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run();
720*6777b538SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
721*6777b538SAndroid Build Coastguard Worker   }
722*6777b538SAndroid Build Coastguard Worker 
BindReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver)723*6777b538SAndroid Build Coastguard Worker   void BindReceiver(
724*6777b538SAndroid Build Coastguard Worker       mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
725*6777b538SAndroid Build Coastguard Worker     DCHECK(!receiver_.is_bound());
726*6777b538SAndroid Build Coastguard Worker     receiver_.Bind(std::move(receiver));
727*6777b538SAndroid Build Coastguard Worker   }
728*6777b538SAndroid Build Coastguard Worker 
729*6777b538SAndroid Build Coastguard Worker   int32_t next_expected_value_ = 0;
730*6777b538SAndroid Build Coastguard Worker   int num_messages_received_ = 0;
731*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
732*6777b538SAndroid Build Coastguard Worker 
733*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
734*6777b538SAndroid Build Coastguard Worker };
735*6777b538SAndroid Build Coastguard Worker 
736*6777b538SAndroid Build Coastguard Worker const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
737*6777b538SAndroid Build Coastguard Worker 
738*6777b538SAndroid Build Coastguard Worker class ListenerSendingAssociatedMessages : public IPC::Listener {
739*6777b538SAndroid Build Coastguard Worker  public:
ListenerSendingAssociatedMessages(base::OnceClosure quit_closure)740*6777b538SAndroid Build Coastguard Worker   explicit ListenerSendingAssociatedMessages(base::OnceClosure quit_closure)
741*6777b538SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)) {}
742*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)743*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
744*6777b538SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)745*6777b538SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
746*6777b538SAndroid Build Coastguard Worker     DCHECK(channel_);
747*6777b538SAndroid Build Coastguard Worker     channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
748*6777b538SAndroid Build Coastguard Worker         driver_.BindNewEndpointAndPassReceiver());
749*6777b538SAndroid Build Coastguard Worker 
750*6777b538SAndroid Build Coastguard Worker     // Send a bunch of interleaved messages, alternating between the associated
751*6777b538SAndroid Build Coastguard Worker     // interface and a legacy IPC::Message.
752*6777b538SAndroid Build Coastguard Worker     for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
753*6777b538SAndroid Build Coastguard Worker          ++i) {
754*6777b538SAndroid Build Coastguard Worker       driver_->ExpectValue(i);
755*6777b538SAndroid Build Coastguard Worker       SendValue(channel_, i);
756*6777b538SAndroid Build Coastguard Worker     }
757*6777b538SAndroid Build Coastguard Worker     driver_->RequestQuit(base::BindOnce(
758*6777b538SAndroid Build Coastguard Worker         &ListenerSendingAssociatedMessages::OnQuitAck, base::Unretained(this)));
759*6777b538SAndroid Build Coastguard Worker   }
760*6777b538SAndroid Build Coastguard Worker 
set_channel(IPC::Channel * channel)761*6777b538SAndroid Build Coastguard Worker   void set_channel(IPC::Channel* channel) { channel_ = channel; }
762*6777b538SAndroid Build Coastguard Worker 
763*6777b538SAndroid Build Coastguard Worker  private:
OnQuitAck()764*6777b538SAndroid Build Coastguard Worker   void OnQuitAck() { std::move(quit_closure_).Run(); }
765*6777b538SAndroid Build Coastguard Worker 
766*6777b538SAndroid Build Coastguard Worker   raw_ptr<IPC::Channel> channel_ = nullptr;
767*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver_;
768*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
769*6777b538SAndroid Build Coastguard Worker };
770*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SimpleAssociatedInterface)771*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
772*6777b538SAndroid Build Coastguard Worker   Init("SimpleAssociatedInterfaceClient");
773*6777b538SAndroid Build Coastguard Worker 
774*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
775*6777b538SAndroid Build Coastguard Worker   ListenerWithSimpleAssociatedInterface listener(run_loop.QuitClosure());
776*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
777*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
778*6777b538SAndroid Build Coastguard Worker 
779*6777b538SAndroid Build Coastguard Worker   listener.RegisterInterfaceFactory(channel());
780*6777b538SAndroid Build Coastguard Worker 
781*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
782*6777b538SAndroid Build Coastguard Worker   channel()->Close();
783*6777b538SAndroid Build Coastguard Worker 
784*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
785*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
786*6777b538SAndroid Build Coastguard Worker }
787*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient)788*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient) {
789*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
790*6777b538SAndroid Build Coastguard Worker   ListenerSendingAssociatedMessages listener(run_loop.QuitClosure());
791*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
792*6777b538SAndroid Build Coastguard Worker   listener.set_channel(channel());
793*6777b538SAndroid Build Coastguard Worker 
794*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
795*6777b538SAndroid Build Coastguard Worker 
796*6777b538SAndroid Build Coastguard Worker   Close();
797*6777b538SAndroid Build Coastguard Worker }
798*6777b538SAndroid Build Coastguard Worker 
799*6777b538SAndroid Build Coastguard Worker class ChannelProxyRunner {
800*6777b538SAndroid Build Coastguard Worker  public:
ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,bool for_server)801*6777b538SAndroid Build Coastguard Worker   ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,
802*6777b538SAndroid Build Coastguard Worker                      bool for_server)
803*6777b538SAndroid Build Coastguard Worker       : for_server_(for_server),
804*6777b538SAndroid Build Coastguard Worker         handle_(std::move(handle)),
805*6777b538SAndroid Build Coastguard Worker         io_thread_("ChannelProxyRunner IO thread"),
806*6777b538SAndroid Build Coastguard Worker         never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
807*6777b538SAndroid Build Coastguard Worker                         base::WaitableEvent::InitialState::NOT_SIGNALED) {
808*6777b538SAndroid Build Coastguard Worker   }
809*6777b538SAndroid Build Coastguard Worker 
810*6777b538SAndroid Build Coastguard Worker   ChannelProxyRunner(const ChannelProxyRunner&) = delete;
811*6777b538SAndroid Build Coastguard Worker   ChannelProxyRunner& operator=(const ChannelProxyRunner&) = delete;
812*6777b538SAndroid Build Coastguard Worker 
CreateProxy(IPC::Listener * listener,IPC::UrgentMessageObserver * urgent_message_observer=nullptr)813*6777b538SAndroid Build Coastguard Worker   void CreateProxy(
814*6777b538SAndroid Build Coastguard Worker       IPC::Listener* listener,
815*6777b538SAndroid Build Coastguard Worker       IPC::UrgentMessageObserver* urgent_message_observer = nullptr) {
816*6777b538SAndroid Build Coastguard Worker     io_thread_.StartWithOptions(
817*6777b538SAndroid Build Coastguard Worker         base::Thread::Options(base::MessagePumpType::IO, 0));
818*6777b538SAndroid Build Coastguard Worker     proxy_ = IPC::SyncChannel::Create(
819*6777b538SAndroid Build Coastguard Worker         listener, io_thread_.task_runner(),
820*6777b538SAndroid Build Coastguard Worker         base::SingleThreadTaskRunner::GetCurrentDefault(), &never_signaled_);
821*6777b538SAndroid Build Coastguard Worker     proxy_->SetUrgentMessageObserver(urgent_message_observer);
822*6777b538SAndroid Build Coastguard Worker   }
823*6777b538SAndroid Build Coastguard Worker 
RunProxy()824*6777b538SAndroid Build Coastguard Worker   void RunProxy() {
825*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<IPC::ChannelFactory> factory;
826*6777b538SAndroid Build Coastguard Worker     if (for_server_) {
827*6777b538SAndroid Build Coastguard Worker       factory = IPC::ChannelMojo::CreateServerFactory(
828*6777b538SAndroid Build Coastguard Worker           std::move(handle_), io_thread_.task_runner(),
829*6777b538SAndroid Build Coastguard Worker           base::SingleThreadTaskRunner::GetCurrentDefault());
830*6777b538SAndroid Build Coastguard Worker     } else {
831*6777b538SAndroid Build Coastguard Worker       factory = IPC::ChannelMojo::CreateClientFactory(
832*6777b538SAndroid Build Coastguard Worker           std::move(handle_), io_thread_.task_runner(),
833*6777b538SAndroid Build Coastguard Worker           base::SingleThreadTaskRunner::GetCurrentDefault());
834*6777b538SAndroid Build Coastguard Worker     }
835*6777b538SAndroid Build Coastguard Worker     proxy_->Init(std::move(factory), true);
836*6777b538SAndroid Build Coastguard Worker   }
837*6777b538SAndroid Build Coastguard Worker 
proxy()838*6777b538SAndroid Build Coastguard Worker   IPC::ChannelProxy* proxy() { return proxy_.get(); }
839*6777b538SAndroid Build Coastguard Worker 
840*6777b538SAndroid Build Coastguard Worker  private:
841*6777b538SAndroid Build Coastguard Worker   const bool for_server_;
842*6777b538SAndroid Build Coastguard Worker 
843*6777b538SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle handle_;
844*6777b538SAndroid Build Coastguard Worker   base::Thread io_thread_;
845*6777b538SAndroid Build Coastguard Worker   base::WaitableEvent never_signaled_;
846*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<IPC::ChannelProxy> proxy_;
847*6777b538SAndroid Build Coastguard Worker };
848*6777b538SAndroid Build Coastguard Worker 
849*6777b538SAndroid Build Coastguard Worker class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase {
850*6777b538SAndroid Build Coastguard Worker  public:
Init(const std::string & client_name)851*6777b538SAndroid Build Coastguard Worker   void Init(const std::string& client_name) {
852*6777b538SAndroid Build Coastguard Worker     IPCChannelMojoTestBase::Init(client_name);
853*6777b538SAndroid Build Coastguard Worker     runner_ = std::make_unique<ChannelProxyRunner>(TakeHandle(), true);
854*6777b538SAndroid Build Coastguard Worker   }
855*6777b538SAndroid Build Coastguard Worker 
CreateProxy(IPC::Listener * listener,IPC::UrgentMessageObserver * urgent_message_observer=nullptr)856*6777b538SAndroid Build Coastguard Worker   void CreateProxy(
857*6777b538SAndroid Build Coastguard Worker       IPC::Listener* listener,
858*6777b538SAndroid Build Coastguard Worker       IPC::UrgentMessageObserver* urgent_message_observer = nullptr) {
859*6777b538SAndroid Build Coastguard Worker     runner_->CreateProxy(listener, urgent_message_observer);
860*6777b538SAndroid Build Coastguard Worker   }
861*6777b538SAndroid Build Coastguard Worker 
RunProxy()862*6777b538SAndroid Build Coastguard Worker   void RunProxy() {
863*6777b538SAndroid Build Coastguard Worker     runner_->RunProxy();
864*6777b538SAndroid Build Coastguard Worker   }
865*6777b538SAndroid Build Coastguard Worker 
DestroyProxy()866*6777b538SAndroid Build Coastguard Worker   void DestroyProxy() {
867*6777b538SAndroid Build Coastguard Worker     runner_.reset();
868*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
869*6777b538SAndroid Build Coastguard Worker   }
870*6777b538SAndroid Build Coastguard Worker 
proxy()871*6777b538SAndroid Build Coastguard Worker   IPC::ChannelProxy* proxy() { return runner_->proxy(); }
872*6777b538SAndroid Build Coastguard Worker 
873*6777b538SAndroid Build Coastguard Worker  private:
874*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<ChannelProxyRunner> runner_;
875*6777b538SAndroid Build Coastguard Worker };
876*6777b538SAndroid Build Coastguard Worker 
877*6777b538SAndroid Build Coastguard Worker class ListenerWithSimpleProxyAssociatedInterface
878*6777b538SAndroid Build Coastguard Worker     : public IPC::Listener,
879*6777b538SAndroid Build Coastguard Worker       public IPC::mojom::SimpleTestDriver {
880*6777b538SAndroid Build Coastguard Worker  public:
881*6777b538SAndroid Build Coastguard Worker   static const int kNumMessages;
882*6777b538SAndroid Build Coastguard Worker 
ListenerWithSimpleProxyAssociatedInterface(base::OnceClosure quit_closure)883*6777b538SAndroid Build Coastguard Worker   explicit ListenerWithSimpleProxyAssociatedInterface(
884*6777b538SAndroid Build Coastguard Worker       base::OnceClosure quit_closure)
885*6777b538SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)) {}
886*6777b538SAndroid Build Coastguard Worker 
887*6777b538SAndroid Build Coastguard Worker   ~ListenerWithSimpleProxyAssociatedInterface() override = default;
888*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)889*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
890*6777b538SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
891*6777b538SAndroid Build Coastguard Worker     int32_t should_be_expected;
892*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(iter.ReadInt(&should_be_expected));
893*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(should_be_expected, next_expected_value_);
894*6777b538SAndroid Build Coastguard Worker     num_messages_received_++;
895*6777b538SAndroid Build Coastguard Worker     return true;
896*6777b538SAndroid Build Coastguard Worker   }
897*6777b538SAndroid Build Coastguard Worker 
OnChannelError()898*6777b538SAndroid Build Coastguard Worker   void OnChannelError() override { CHECK(!quit_closure_); }
899*6777b538SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)900*6777b538SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
901*6777b538SAndroid Build Coastguard Worker       const std::string& interface_name,
902*6777b538SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
903*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
904*6777b538SAndroid Build Coastguard Worker     receiver_.Bind(
905*6777b538SAndroid Build Coastguard Worker         mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver>(
906*6777b538SAndroid Build Coastguard Worker             std::move(handle)));
907*6777b538SAndroid Build Coastguard Worker   }
908*6777b538SAndroid Build Coastguard Worker 
received_all_messages() const909*6777b538SAndroid Build Coastguard Worker   bool received_all_messages() const {
910*6777b538SAndroid Build Coastguard Worker     return num_messages_received_ == kNumMessages && !quit_closure_;
911*6777b538SAndroid Build Coastguard Worker   }
912*6777b538SAndroid Build Coastguard Worker 
913*6777b538SAndroid Build Coastguard Worker  private:
914*6777b538SAndroid Build Coastguard Worker   // IPC::mojom::SimpleTestDriver:
ExpectValue(int32_t value)915*6777b538SAndroid Build Coastguard Worker   void ExpectValue(int32_t value) override {
916*6777b538SAndroid Build Coastguard Worker     next_expected_value_ = value;
917*6777b538SAndroid Build Coastguard Worker   }
918*6777b538SAndroid Build Coastguard Worker 
GetExpectedValue(GetExpectedValueCallback callback)919*6777b538SAndroid Build Coastguard Worker   void GetExpectedValue(GetExpectedValueCallback callback) override {
920*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run(next_expected_value_);
921*6777b538SAndroid Build Coastguard Worker   }
922*6777b538SAndroid Build Coastguard Worker 
RequestValue(RequestValueCallback callback)923*6777b538SAndroid Build Coastguard Worker   void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
924*6777b538SAndroid Build Coastguard Worker 
RequestQuit(RequestQuitCallback callback)925*6777b538SAndroid Build Coastguard Worker   void RequestQuit(RequestQuitCallback callback) override {
926*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run();
927*6777b538SAndroid Build Coastguard Worker     receiver_.reset();
928*6777b538SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
929*6777b538SAndroid Build Coastguard Worker   }
930*6777b538SAndroid Build Coastguard Worker 
BindReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver)931*6777b538SAndroid Build Coastguard Worker   void BindReceiver(
932*6777b538SAndroid Build Coastguard Worker       mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
933*6777b538SAndroid Build Coastguard Worker     DCHECK(!receiver_.is_bound());
934*6777b538SAndroid Build Coastguard Worker     receiver_.Bind(std::move(receiver));
935*6777b538SAndroid Build Coastguard Worker   }
936*6777b538SAndroid Build Coastguard Worker 
937*6777b538SAndroid Build Coastguard Worker   int32_t next_expected_value_ = 0;
938*6777b538SAndroid Build Coastguard Worker   int num_messages_received_ = 0;
939*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
940*6777b538SAndroid Build Coastguard Worker 
941*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
942*6777b538SAndroid Build Coastguard Worker };
943*6777b538SAndroid Build Coastguard Worker 
944*6777b538SAndroid Build Coastguard Worker const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000;
945*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,ProxyThreadAssociatedInterface)946*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) {
947*6777b538SAndroid Build Coastguard Worker   Init("ProxyThreadAssociatedInterfaceClient");
948*6777b538SAndroid Build Coastguard Worker 
949*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
950*6777b538SAndroid Build Coastguard Worker   ListenerWithSimpleProxyAssociatedInterface listener(run_loop.QuitClosure());
951*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
952*6777b538SAndroid Build Coastguard Worker   RunProxy();
953*6777b538SAndroid Build Coastguard Worker 
954*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
955*6777b538SAndroid Build Coastguard Worker 
956*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
957*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.received_all_messages());
958*6777b538SAndroid Build Coastguard Worker 
959*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
960*6777b538SAndroid Build Coastguard Worker }
961*6777b538SAndroid Build Coastguard Worker 
962*6777b538SAndroid Build Coastguard Worker class ChannelProxyClient {
963*6777b538SAndroid Build Coastguard Worker  public:
Init(mojo::ScopedMessagePipeHandle handle)964*6777b538SAndroid Build Coastguard Worker   void Init(mojo::ScopedMessagePipeHandle handle) {
965*6777b538SAndroid Build Coastguard Worker     runner_ = std::make_unique<ChannelProxyRunner>(std::move(handle), false);
966*6777b538SAndroid Build Coastguard Worker   }
967*6777b538SAndroid Build Coastguard Worker 
CreateProxy(IPC::Listener * listener)968*6777b538SAndroid Build Coastguard Worker   void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
969*6777b538SAndroid Build Coastguard Worker 
RunProxy()970*6777b538SAndroid Build Coastguard Worker   void RunProxy() { runner_->RunProxy(); }
971*6777b538SAndroid Build Coastguard Worker 
DestroyProxy()972*6777b538SAndroid Build Coastguard Worker   void DestroyProxy() {
973*6777b538SAndroid Build Coastguard Worker     runner_.reset();
974*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
975*6777b538SAndroid Build Coastguard Worker   }
976*6777b538SAndroid Build Coastguard Worker 
RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver * driver)977*6777b538SAndroid Build Coastguard Worker   void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) {
978*6777b538SAndroid Build Coastguard Worker     base::RunLoop loop;
979*6777b538SAndroid Build Coastguard Worker     driver->RequestQuit(loop.QuitClosure());
980*6777b538SAndroid Build Coastguard Worker     loop.Run();
981*6777b538SAndroid Build Coastguard Worker   }
982*6777b538SAndroid Build Coastguard Worker 
proxy()983*6777b538SAndroid Build Coastguard Worker   IPC::ChannelProxy* proxy() { return runner_->proxy(); }
984*6777b538SAndroid Build Coastguard Worker 
985*6777b538SAndroid Build Coastguard Worker  private:
986*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment_;
987*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<ChannelProxyRunner> runner_;
988*6777b538SAndroid Build Coastguard Worker };
989*6777b538SAndroid Build Coastguard Worker 
990*6777b538SAndroid Build Coastguard Worker class DummyListener : public IPC::Listener {
991*6777b538SAndroid Build Coastguard Worker  public:
992*6777b538SAndroid Build Coastguard Worker   // IPC::Listener
OnMessageReceived(const IPC::Message & message)993*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
994*6777b538SAndroid Build Coastguard Worker };
995*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ProxyThreadAssociatedInterfaceClient,ChannelProxyClient)996*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
997*6777b538SAndroid Build Coastguard Worker     ProxyThreadAssociatedInterfaceClient,
998*6777b538SAndroid Build Coastguard Worker     ChannelProxyClient) {
999*6777b538SAndroid Build Coastguard Worker   DummyListener listener;
1000*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1001*6777b538SAndroid Build Coastguard Worker   RunProxy();
1002*6777b538SAndroid Build Coastguard Worker 
1003*6777b538SAndroid Build Coastguard Worker   // Send a bunch of interleaved messages, alternating between the associated
1004*6777b538SAndroid Build Coastguard Worker   // interface and a legacy IPC::Message.
1005*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver;
1006*6777b538SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(
1007*6777b538SAndroid Build Coastguard Worker       driver.BindNewEndpointAndPassReceiver());
1008*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages;
1009*6777b538SAndroid Build Coastguard Worker        ++i) {
1010*6777b538SAndroid Build Coastguard Worker     driver->ExpectValue(i);
1011*6777b538SAndroid Build Coastguard Worker     SendValue(proxy(), i);
1012*6777b538SAndroid Build Coastguard Worker   }
1013*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1014*6777b538SAndroid Build Coastguard Worker   driver->RequestQuit(run_loop.QuitClosure());
1015*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1016*6777b538SAndroid Build Coastguard Worker 
1017*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1018*6777b538SAndroid Build Coastguard Worker }
1019*6777b538SAndroid Build Coastguard Worker 
1020*6777b538SAndroid Build Coastguard Worker class ListenerWithIndirectProxyAssociatedInterface
1021*6777b538SAndroid Build Coastguard Worker     : public IPC::Listener,
1022*6777b538SAndroid Build Coastguard Worker       public IPC::mojom::IndirectTestDriver,
1023*6777b538SAndroid Build Coastguard Worker       public IPC::mojom::PingReceiver {
1024*6777b538SAndroid Build Coastguard Worker  public:
1025*6777b538SAndroid Build Coastguard Worker   ListenerWithIndirectProxyAssociatedInterface() = default;
1026*6777b538SAndroid Build Coastguard Worker   ~ListenerWithIndirectProxyAssociatedInterface() override = default;
1027*6777b538SAndroid Build Coastguard Worker 
1028*6777b538SAndroid Build Coastguard Worker   // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1029*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
1030*6777b538SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1031*6777b538SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
1032*6777b538SAndroid Build Coastguard Worker       const std::string& interface_name,
1033*6777b538SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
1034*6777b538SAndroid Build Coastguard Worker     DCHECK(!driver_receiver_.is_bound());
1035*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(interface_name, IPC::mojom::IndirectTestDriver::Name_);
1036*6777b538SAndroid Build Coastguard Worker     driver_receiver_.Bind(
1037*6777b538SAndroid Build Coastguard Worker         mojo::PendingAssociatedReceiver<IPC::mojom::IndirectTestDriver>(
1038*6777b538SAndroid Build Coastguard Worker             std::move(handle)));
1039*6777b538SAndroid Build Coastguard Worker   }
1040*6777b538SAndroid Build Coastguard Worker 
set_ping_handler(const base::RepeatingClosure & handler)1041*6777b538SAndroid Build Coastguard Worker   void set_ping_handler(const base::RepeatingClosure& handler) {
1042*6777b538SAndroid Build Coastguard Worker     ping_handler_ = handler;
1043*6777b538SAndroid Build Coastguard Worker   }
1044*6777b538SAndroid Build Coastguard Worker 
1045*6777b538SAndroid Build Coastguard Worker  private:
1046*6777b538SAndroid Build Coastguard Worker   // IPC::mojom::IndirectTestDriver:
GetPingReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::PingReceiver> receiver)1047*6777b538SAndroid Build Coastguard Worker   void GetPingReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::PingReceiver>
1048*6777b538SAndroid Build Coastguard Worker                            receiver) override {
1049*6777b538SAndroid Build Coastguard Worker     ping_receiver_receiver_.Bind(std::move(receiver));
1050*6777b538SAndroid Build Coastguard Worker   }
1051*6777b538SAndroid Build Coastguard Worker 
1052*6777b538SAndroid Build Coastguard Worker   // IPC::mojom::PingReceiver:
Ping(PingCallback callback)1053*6777b538SAndroid Build Coastguard Worker   void Ping(PingCallback callback) override {
1054*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run();
1055*6777b538SAndroid Build Coastguard Worker     ping_handler_.Run();
1056*6777b538SAndroid Build Coastguard Worker   }
1057*6777b538SAndroid Build Coastguard Worker 
1058*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedReceiver<IPC::mojom::IndirectTestDriver> driver_receiver_{
1059*6777b538SAndroid Build Coastguard Worker       this};
1060*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedReceiver<IPC::mojom::PingReceiver> ping_receiver_receiver_{
1061*6777b538SAndroid Build Coastguard Worker       this};
1062*6777b538SAndroid Build Coastguard Worker 
1063*6777b538SAndroid Build Coastguard Worker   base::RepeatingClosure ping_handler_;
1064*6777b538SAndroid Build Coastguard Worker };
1065*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,ProxyThreadAssociatedInterfaceIndirect)1066*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterfaceIndirect) {
1067*6777b538SAndroid Build Coastguard Worker   // Tests that we can pipeline interface requests and subsequent messages
1068*6777b538SAndroid Build Coastguard Worker   // targeting proxy thread bindings, and the channel will still dispatch
1069*6777b538SAndroid Build Coastguard Worker   // messages appropriately.
1070*6777b538SAndroid Build Coastguard Worker 
1071*6777b538SAndroid Build Coastguard Worker   Init("ProxyThreadAssociatedInterfaceIndirectClient");
1072*6777b538SAndroid Build Coastguard Worker 
1073*6777b538SAndroid Build Coastguard Worker   ListenerWithIndirectProxyAssociatedInterface listener;
1074*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1075*6777b538SAndroid Build Coastguard Worker   RunProxy();
1076*6777b538SAndroid Build Coastguard Worker 
1077*6777b538SAndroid Build Coastguard Worker   base::RunLoop loop;
1078*6777b538SAndroid Build Coastguard Worker   listener.set_ping_handler(loop.QuitClosure());
1079*6777b538SAndroid Build Coastguard Worker   loop.Run();
1080*6777b538SAndroid Build Coastguard Worker 
1081*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1082*6777b538SAndroid Build Coastguard Worker 
1083*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1084*6777b538SAndroid Build Coastguard Worker }
1085*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(ProxyThreadAssociatedInterfaceIndirectClient,ChannelProxyClient)1086*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
1087*6777b538SAndroid Build Coastguard Worker     ProxyThreadAssociatedInterfaceIndirectClient,
1088*6777b538SAndroid Build Coastguard Worker     ChannelProxyClient) {
1089*6777b538SAndroid Build Coastguard Worker   DummyListener listener;
1090*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1091*6777b538SAndroid Build Coastguard Worker   RunProxy();
1092*6777b538SAndroid Build Coastguard Worker 
1093*6777b538SAndroid Build Coastguard Worker   // Use an interface requested via another interface. On the remote end both
1094*6777b538SAndroid Build Coastguard Worker   // interfaces are bound on the proxy thread. This ensures that the Ping
1095*6777b538SAndroid Build Coastguard Worker   // message we send will still be dispatched properly even though the remote
1096*6777b538SAndroid Build Coastguard Worker   // endpoint may not have been bound yet by the time the message is initially
1097*6777b538SAndroid Build Coastguard Worker   // processed on the IO thread.
1098*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::IndirectTestDriver> driver;
1099*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::PingReceiver> ping_receiver;
1100*6777b538SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(
1101*6777b538SAndroid Build Coastguard Worker       driver.BindNewEndpointAndPassReceiver());
1102*6777b538SAndroid Build Coastguard Worker   driver->GetPingReceiver(ping_receiver.BindNewEndpointAndPassReceiver());
1103*6777b538SAndroid Build Coastguard Worker 
1104*6777b538SAndroid Build Coastguard Worker   base::RunLoop loop;
1105*6777b538SAndroid Build Coastguard Worker   ping_receiver->Ping(loop.QuitClosure());
1106*6777b538SAndroid Build Coastguard Worker   loop.Run();
1107*6777b538SAndroid Build Coastguard Worker 
1108*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1109*6777b538SAndroid Build Coastguard Worker }
1110*6777b538SAndroid Build Coastguard Worker 
1111*6777b538SAndroid Build Coastguard Worker class ListenerWithSyncAssociatedInterface
1112*6777b538SAndroid Build Coastguard Worker     : public IPC::Listener,
1113*6777b538SAndroid Build Coastguard Worker       public IPC::mojom::SimpleTestDriver {
1114*6777b538SAndroid Build Coastguard Worker  public:
1115*6777b538SAndroid Build Coastguard Worker   ListenerWithSyncAssociatedInterface() = default;
1116*6777b538SAndroid Build Coastguard Worker   ~ListenerWithSyncAssociatedInterface() override = default;
1117*6777b538SAndroid Build Coastguard Worker 
set_sync_sender(IPC::Sender * sync_sender)1118*6777b538SAndroid Build Coastguard Worker   void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1119*6777b538SAndroid Build Coastguard Worker 
RunUntilQuitRequested()1120*6777b538SAndroid Build Coastguard Worker   void RunUntilQuitRequested() {
1121*6777b538SAndroid Build Coastguard Worker     base::RunLoop loop;
1122*6777b538SAndroid Build Coastguard Worker     quit_closure_ = loop.QuitClosure();
1123*6777b538SAndroid Build Coastguard Worker     loop.Run();
1124*6777b538SAndroid Build Coastguard Worker   }
1125*6777b538SAndroid Build Coastguard Worker 
CloseBinding()1126*6777b538SAndroid Build Coastguard Worker   void CloseBinding() { receiver_.reset(); }
1127*6777b538SAndroid Build Coastguard Worker 
set_response_value(int32_t response)1128*6777b538SAndroid Build Coastguard Worker   void set_response_value(int32_t response) {
1129*6777b538SAndroid Build Coastguard Worker     response_value_ = response;
1130*6777b538SAndroid Build Coastguard Worker   }
1131*6777b538SAndroid Build Coastguard Worker 
1132*6777b538SAndroid Build Coastguard Worker  private:
1133*6777b538SAndroid Build Coastguard Worker   // IPC::mojom::SimpleTestDriver:
ExpectValue(int32_t value)1134*6777b538SAndroid Build Coastguard Worker   void ExpectValue(int32_t value) override {
1135*6777b538SAndroid Build Coastguard Worker     next_expected_value_ = value;
1136*6777b538SAndroid Build Coastguard Worker   }
1137*6777b538SAndroid Build Coastguard Worker 
GetExpectedValue(GetExpectedValueCallback callback)1138*6777b538SAndroid Build Coastguard Worker   void GetExpectedValue(GetExpectedValueCallback callback) override {
1139*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run(next_expected_value_);
1140*6777b538SAndroid Build Coastguard Worker   }
1141*6777b538SAndroid Build Coastguard Worker 
RequestValue(RequestValueCallback callback)1142*6777b538SAndroid Build Coastguard Worker   void RequestValue(RequestValueCallback callback) override {
1143*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run(response_value_);
1144*6777b538SAndroid Build Coastguard Worker   }
1145*6777b538SAndroid Build Coastguard Worker 
RequestQuit(RequestQuitCallback callback)1146*6777b538SAndroid Build Coastguard Worker   void RequestQuit(RequestQuitCallback callback) override {
1147*6777b538SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
1148*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run();
1149*6777b538SAndroid Build Coastguard Worker   }
1150*6777b538SAndroid Build Coastguard Worker 
1151*6777b538SAndroid Build Coastguard Worker   // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1152*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1153*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0u, message.type());
1154*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(message.is_sync());
1155*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(message.should_unblock());
1156*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<IPC::Message> reply(
1157*6777b538SAndroid Build Coastguard Worker         IPC::SyncMessage::GenerateReply(&message));
1158*6777b538SAndroid Build Coastguard Worker     reply->WriteInt(response_value_);
1159*6777b538SAndroid Build Coastguard Worker     DCHECK(sync_sender_);
1160*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(sync_sender_->Send(reply.release()));
1161*6777b538SAndroid Build Coastguard Worker     return true;
1162*6777b538SAndroid Build Coastguard Worker   }
1163*6777b538SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1164*6777b538SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
1165*6777b538SAndroid Build Coastguard Worker       const std::string& interface_name,
1166*6777b538SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
1167*6777b538SAndroid Build Coastguard Worker     DCHECK(!receiver_.is_bound());
1168*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
1169*6777b538SAndroid Build Coastguard Worker     receiver_.Bind(
1170*6777b538SAndroid Build Coastguard Worker         mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver>(
1171*6777b538SAndroid Build Coastguard Worker             std::move(handle)));
1172*6777b538SAndroid Build Coastguard Worker   }
1173*6777b538SAndroid Build Coastguard Worker 
BindReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver)1174*6777b538SAndroid Build Coastguard Worker   void BindReceiver(
1175*6777b538SAndroid Build Coastguard Worker       mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
1176*6777b538SAndroid Build Coastguard Worker     DCHECK(!receiver_.is_bound());
1177*6777b538SAndroid Build Coastguard Worker     receiver_.Bind(std::move(receiver));
1178*6777b538SAndroid Build Coastguard Worker   }
1179*6777b538SAndroid Build Coastguard Worker 
1180*6777b538SAndroid Build Coastguard Worker   raw_ptr<IPC::Sender, DanglingUntriaged> sync_sender_ = nullptr;
1181*6777b538SAndroid Build Coastguard Worker   int32_t next_expected_value_ = 0;
1182*6777b538SAndroid Build Coastguard Worker   int32_t response_value_ = 0;
1183*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
1184*6777b538SAndroid Build Coastguard Worker 
1185*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
1186*6777b538SAndroid Build Coastguard Worker };
1187*6777b538SAndroid Build Coastguard Worker 
1188*6777b538SAndroid Build Coastguard Worker class SyncReplyReader : public IPC::MessageReplyDeserializer {
1189*6777b538SAndroid Build Coastguard Worker  public:
SyncReplyReader(int32_t * storage)1190*6777b538SAndroid Build Coastguard Worker   explicit SyncReplyReader(int32_t* storage) : storage_(storage) {}
1191*6777b538SAndroid Build Coastguard Worker 
1192*6777b538SAndroid Build Coastguard Worker   SyncReplyReader(const SyncReplyReader&) = delete;
1193*6777b538SAndroid Build Coastguard Worker   SyncReplyReader& operator=(const SyncReplyReader&) = delete;
1194*6777b538SAndroid Build Coastguard Worker 
1195*6777b538SAndroid Build Coastguard Worker   ~SyncReplyReader() override = default;
1196*6777b538SAndroid Build Coastguard Worker 
1197*6777b538SAndroid Build Coastguard Worker  private:
1198*6777b538SAndroid Build Coastguard Worker   // IPC::MessageReplyDeserializer:
SerializeOutputParameters(const IPC::Message & message,base::PickleIterator iter)1199*6777b538SAndroid Build Coastguard Worker   bool SerializeOutputParameters(const IPC::Message& message,
1200*6777b538SAndroid Build Coastguard Worker                                  base::PickleIterator iter) override {
1201*6777b538SAndroid Build Coastguard Worker     if (!iter.ReadInt(storage_))
1202*6777b538SAndroid Build Coastguard Worker       return false;
1203*6777b538SAndroid Build Coastguard Worker     return true;
1204*6777b538SAndroid Build Coastguard Worker   }
1205*6777b538SAndroid Build Coastguard Worker 
1206*6777b538SAndroid Build Coastguard Worker   raw_ptr<int32_t> storage_;
1207*6777b538SAndroid Build Coastguard Worker };
1208*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,SyncAssociatedInterface)1209*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) {
1210*6777b538SAndroid Build Coastguard Worker   Init("SyncAssociatedInterface");
1211*6777b538SAndroid Build Coastguard Worker 
1212*6777b538SAndroid Build Coastguard Worker   ListenerWithSyncAssociatedInterface listener;
1213*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1214*6777b538SAndroid Build Coastguard Worker   listener.set_sync_sender(proxy());
1215*6777b538SAndroid Build Coastguard Worker   RunProxy();
1216*6777b538SAndroid Build Coastguard Worker 
1217*6777b538SAndroid Build Coastguard Worker   // Run the client's simple sanity check to completion.
1218*6777b538SAndroid Build Coastguard Worker   listener.RunUntilQuitRequested();
1219*6777b538SAndroid Build Coastguard Worker 
1220*6777b538SAndroid Build Coastguard Worker   // Verify that we can send a sync IPC and service an incoming sync request
1221*6777b538SAndroid Build Coastguard Worker   // while waiting on it
1222*6777b538SAndroid Build Coastguard Worker   listener.set_response_value(42);
1223*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::SimpleTestClient> client;
1224*6777b538SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(
1225*6777b538SAndroid Build Coastguard Worker       client.BindNewEndpointAndPassReceiver());
1226*6777b538SAndroid Build Coastguard Worker   int32_t received_value;
1227*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(client->RequestValue(&received_value));
1228*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(42, received_value);
1229*6777b538SAndroid Build Coastguard Worker 
1230*6777b538SAndroid Build Coastguard Worker   // Do it again. This time the client will send a classical sync IPC to us
1231*6777b538SAndroid Build Coastguard Worker   // while we wait.
1232*6777b538SAndroid Build Coastguard Worker   received_value = 0;
1233*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(client->RequestValue(&received_value));
1234*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(42, received_value);
1235*6777b538SAndroid Build Coastguard Worker 
1236*6777b538SAndroid Build Coastguard Worker   // Now make a classical sync IPC request to the client. It will send a
1237*6777b538SAndroid Build Coastguard Worker   // sync associated interface message to us while we wait.
1238*6777b538SAndroid Build Coastguard Worker   received_value = 0;
1239*6777b538SAndroid Build Coastguard Worker   auto request = std::make_unique<IPC::SyncMessage>(
1240*6777b538SAndroid Build Coastguard Worker       0, 0, IPC::Message::PRIORITY_NORMAL,
1241*6777b538SAndroid Build Coastguard Worker       std::make_unique<SyncReplyReader>(&received_value));
1242*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy()->Send(request.release()));
1243*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(42, received_value);
1244*6777b538SAndroid Build Coastguard Worker 
1245*6777b538SAndroid Build Coastguard Worker   listener.CloseBinding();
1246*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1247*6777b538SAndroid Build Coastguard Worker 
1248*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1249*6777b538SAndroid Build Coastguard Worker }
1250*6777b538SAndroid Build Coastguard Worker 
1251*6777b538SAndroid Build Coastguard Worker class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
1252*6777b538SAndroid Build Coastguard Worker                              public IPC::Listener {
1253*6777b538SAndroid Build Coastguard Worker  public:
1254*6777b538SAndroid Build Coastguard Worker   SimpleTestClientImpl() = default;
1255*6777b538SAndroid Build Coastguard Worker 
1256*6777b538SAndroid Build Coastguard Worker   SimpleTestClientImpl(const SimpleTestClientImpl&) = delete;
1257*6777b538SAndroid Build Coastguard Worker   SimpleTestClientImpl& operator=(const SimpleTestClientImpl&) = delete;
1258*6777b538SAndroid Build Coastguard Worker 
1259*6777b538SAndroid Build Coastguard Worker   ~SimpleTestClientImpl() override = default;
1260*6777b538SAndroid Build Coastguard Worker 
set_driver(IPC::mojom::SimpleTestDriver * driver)1261*6777b538SAndroid Build Coastguard Worker   void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; }
set_sync_sender(IPC::Sender * sync_sender)1262*6777b538SAndroid Build Coastguard Worker   void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1263*6777b538SAndroid Build Coastguard Worker 
WaitForValueRequest()1264*6777b538SAndroid Build Coastguard Worker   void WaitForValueRequest() { Run(); }
1265*6777b538SAndroid Build Coastguard Worker 
Run()1266*6777b538SAndroid Build Coastguard Worker   void Run() {
1267*6777b538SAndroid Build Coastguard Worker     run_loop_ = std::make_unique<base::RunLoop>();
1268*6777b538SAndroid Build Coastguard Worker     run_loop_->Run();
1269*6777b538SAndroid Build Coastguard Worker   }
1270*6777b538SAndroid Build Coastguard Worker 
UseSyncSenderForRequest(bool use_sync_sender)1271*6777b538SAndroid Build Coastguard Worker   void UseSyncSenderForRequest(bool use_sync_sender) {
1272*6777b538SAndroid Build Coastguard Worker     use_sync_sender_ = use_sync_sender;
1273*6777b538SAndroid Build Coastguard Worker   }
1274*6777b538SAndroid Build Coastguard Worker 
1275*6777b538SAndroid Build Coastguard Worker  private:
1276*6777b538SAndroid Build Coastguard Worker   // IPC::mojom::SimpleTestClient:
RequestValue(RequestValueCallback callback)1277*6777b538SAndroid Build Coastguard Worker   void RequestValue(RequestValueCallback callback) override {
1278*6777b538SAndroid Build Coastguard Worker     int32_t response = 0;
1279*6777b538SAndroid Build Coastguard Worker     if (use_sync_sender_) {
1280*6777b538SAndroid Build Coastguard Worker       auto reply = std::make_unique<IPC::SyncMessage>(
1281*6777b538SAndroid Build Coastguard Worker           0, 0, IPC::Message::PRIORITY_NORMAL,
1282*6777b538SAndroid Build Coastguard Worker           std::make_unique<SyncReplyReader>(&response));
1283*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(sync_sender_->Send(reply.release()));
1284*6777b538SAndroid Build Coastguard Worker     } else {
1285*6777b538SAndroid Build Coastguard Worker       DCHECK(driver_);
1286*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(driver_->RequestValue(&response));
1287*6777b538SAndroid Build Coastguard Worker     }
1288*6777b538SAndroid Build Coastguard Worker 
1289*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run(response);
1290*6777b538SAndroid Build Coastguard Worker 
1291*6777b538SAndroid Build Coastguard Worker     DCHECK(run_loop_);
1292*6777b538SAndroid Build Coastguard Worker     run_loop_->Quit();
1293*6777b538SAndroid Build Coastguard Worker   }
1294*6777b538SAndroid Build Coastguard Worker 
1295*6777b538SAndroid Build Coastguard Worker   // No implementation needed. Only called on an endpoint which never binds its
1296*6777b538SAndroid Build Coastguard Worker   // receiver.
BindSync(mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestClient> receiver,BindSyncCallback callback)1297*6777b538SAndroid Build Coastguard Worker   void BindSync(
1298*6777b538SAndroid Build Coastguard Worker       mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestClient> receiver,
1299*6777b538SAndroid Build Coastguard Worker       BindSyncCallback callback) override {
1300*6777b538SAndroid Build Coastguard Worker     NOTREACHED();
1301*6777b538SAndroid Build Coastguard Worker   }
1302*6777b538SAndroid Build Coastguard Worker 
GetReceiverWithQueuedSyncMessage(GetReceiverWithQueuedSyncMessageCallback callback)1303*6777b538SAndroid Build Coastguard Worker   void GetReceiverWithQueuedSyncMessage(
1304*6777b538SAndroid Build Coastguard Worker       GetReceiverWithQueuedSyncMessageCallback callback) override {
1305*6777b538SAndroid Build Coastguard Worker     // Immediately send back a sync IPC over the new pipe and expect the call to
1306*6777b538SAndroid Build Coastguard Worker     // be interrupted without a reply. Note that we also reply *before* issuing
1307*6777b538SAndroid Build Coastguard Worker     // the sync call to allow the main test process to make progress.
1308*6777b538SAndroid Build Coastguard Worker     mojo::AssociatedRemote<IPC::mojom::SimpleTestClient> remote;
1309*6777b538SAndroid Build Coastguard Worker     mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestClient>
1310*6777b538SAndroid Build Coastguard Worker         queued_receiver;
1311*6777b538SAndroid Build Coastguard Worker     {
1312*6777b538SAndroid Build Coastguard Worker       // The nested receiver we send will already know its peer is closed when
1313*6777b538SAndroid Build Coastguard Worker       // it arrives.
1314*6777b538SAndroid Build Coastguard Worker       mojo::AssociatedRemote<IPC::mojom::SimpleTestClient> unused;
1315*6777b538SAndroid Build Coastguard Worker       queued_receiver = unused.BindNewEndpointAndPassReceiver();
1316*6777b538SAndroid Build Coastguard Worker     }
1317*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run(remote.BindNewEndpointAndPassReceiver());
1318*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(remote->BindSync(std::move(queued_receiver)));
1319*6777b538SAndroid Build Coastguard Worker   }
1320*6777b538SAndroid Build Coastguard Worker 
1321*6777b538SAndroid Build Coastguard Worker   // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1322*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1323*6777b538SAndroid Build Coastguard Worker     int32_t response;
1324*6777b538SAndroid Build Coastguard Worker     DCHECK(driver_);
1325*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(driver_->RequestValue(&response));
1326*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<IPC::Message> reply(
1327*6777b538SAndroid Build Coastguard Worker         IPC::SyncMessage::GenerateReply(&message));
1328*6777b538SAndroid Build Coastguard Worker     reply->WriteInt(response);
1329*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(sync_sender_->Send(reply.release()));
1330*6777b538SAndroid Build Coastguard Worker 
1331*6777b538SAndroid Build Coastguard Worker     DCHECK(run_loop_);
1332*6777b538SAndroid Build Coastguard Worker     run_loop_->Quit();
1333*6777b538SAndroid Build Coastguard Worker     return true;
1334*6777b538SAndroid Build Coastguard Worker   }
1335*6777b538SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1336*6777b538SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
1337*6777b538SAndroid Build Coastguard Worker       const std::string& interface_name,
1338*6777b538SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
1339*6777b538SAndroid Build Coastguard Worker     DCHECK(!receiver_.is_bound());
1340*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(interface_name, IPC::mojom::SimpleTestClient::Name_);
1341*6777b538SAndroid Build Coastguard Worker 
1342*6777b538SAndroid Build Coastguard Worker     receiver_.Bind(
1343*6777b538SAndroid Build Coastguard Worker         mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestClient>(
1344*6777b538SAndroid Build Coastguard Worker             std::move(handle)));
1345*6777b538SAndroid Build Coastguard Worker   }
1346*6777b538SAndroid Build Coastguard Worker 
1347*6777b538SAndroid Build Coastguard Worker   bool use_sync_sender_ = false;
1348*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedReceiver<IPC::mojom::SimpleTestClient> receiver_{this};
1349*6777b538SAndroid Build Coastguard Worker   raw_ptr<IPC::Sender> sync_sender_ = nullptr;
1350*6777b538SAndroid Build Coastguard Worker   raw_ptr<IPC::mojom::SimpleTestDriver> driver_ = nullptr;
1351*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::RunLoop> run_loop_;
1352*6777b538SAndroid Build Coastguard Worker };
1353*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,ChannelProxyClient)1354*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,
1355*6777b538SAndroid Build Coastguard Worker                                                         ChannelProxyClient) {
1356*6777b538SAndroid Build Coastguard Worker   SimpleTestClientImpl client_impl;
1357*6777b538SAndroid Build Coastguard Worker   CreateProxy(&client_impl);
1358*6777b538SAndroid Build Coastguard Worker   client_impl.set_sync_sender(proxy());
1359*6777b538SAndroid Build Coastguard Worker   RunProxy();
1360*6777b538SAndroid Build Coastguard Worker 
1361*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver;
1362*6777b538SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(
1363*6777b538SAndroid Build Coastguard Worker       driver.BindNewEndpointAndPassReceiver());
1364*6777b538SAndroid Build Coastguard Worker   client_impl.set_driver(driver.get());
1365*6777b538SAndroid Build Coastguard Worker 
1366*6777b538SAndroid Build Coastguard Worker   // Simple sync message sanity check.
1367*6777b538SAndroid Build Coastguard Worker   driver->ExpectValue(42);
1368*6777b538SAndroid Build Coastguard Worker   int32_t expected_value = 0;
1369*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(driver->GetExpectedValue(&expected_value));
1370*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(42, expected_value);
1371*6777b538SAndroid Build Coastguard Worker   RequestQuitAndWaitForAck(driver.get());
1372*6777b538SAndroid Build Coastguard Worker 
1373*6777b538SAndroid Build Coastguard Worker   // Wait for the test driver to perform a sync call test with our own sync
1374*6777b538SAndroid Build Coastguard Worker   // associated interface message nested inside.
1375*6777b538SAndroid Build Coastguard Worker   client_impl.UseSyncSenderForRequest(false);
1376*6777b538SAndroid Build Coastguard Worker   client_impl.WaitForValueRequest();
1377*6777b538SAndroid Build Coastguard Worker 
1378*6777b538SAndroid Build Coastguard Worker   // Wait for the test driver to perform a sync call test with our own classical
1379*6777b538SAndroid Build Coastguard Worker   // sync IPC nested inside.
1380*6777b538SAndroid Build Coastguard Worker   client_impl.UseSyncSenderForRequest(true);
1381*6777b538SAndroid Build Coastguard Worker   client_impl.WaitForValueRequest();
1382*6777b538SAndroid Build Coastguard Worker 
1383*6777b538SAndroid Build Coastguard Worker   // Wait for the test driver to perform a classical sync IPC request, with our
1384*6777b538SAndroid Build Coastguard Worker   // own sync associated interface message nested inside.
1385*6777b538SAndroid Build Coastguard Worker   client_impl.UseSyncSenderForRequest(false);
1386*6777b538SAndroid Build Coastguard Worker   client_impl.WaitForValueRequest();
1387*6777b538SAndroid Build Coastguard Worker 
1388*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1389*6777b538SAndroid Build Coastguard Worker }
1390*6777b538SAndroid Build Coastguard Worker 
1391*6777b538SAndroid Build Coastguard Worker class ListenerWithClumsyBinder : public IPC::Listener {
1392*6777b538SAndroid Build Coastguard Worker  public:
1393*6777b538SAndroid Build Coastguard Worker   ListenerWithClumsyBinder() = default;
1394*6777b538SAndroid Build Coastguard Worker   ~ListenerWithClumsyBinder() override = default;
1395*6777b538SAndroid Build Coastguard Worker 
RunUntilClientQuit()1396*6777b538SAndroid Build Coastguard Worker   void RunUntilClientQuit() { run_loop_.Run(); }
1397*6777b538SAndroid Build Coastguard Worker 
1398*6777b538SAndroid Build Coastguard Worker  private:
1399*6777b538SAndroid Build Coastguard Worker   // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1400*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1401*6777b538SAndroid Build Coastguard Worker     run_loop_.Quit();
1402*6777b538SAndroid Build Coastguard Worker     return true;
1403*6777b538SAndroid Build Coastguard Worker   }
1404*6777b538SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1405*6777b538SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
1406*6777b538SAndroid Build Coastguard Worker       const std::string& interface_name,
1407*6777b538SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
1408*6777b538SAndroid Build Coastguard Worker     // Ignore and drop the endpoint so it's closed.
1409*6777b538SAndroid Build Coastguard Worker   }
1410*6777b538SAndroid Build Coastguard Worker 
1411*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop_;
1412*6777b538SAndroid Build Coastguard Worker };
1413*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,DropAssociatedReceiverWithSyncCallInFlight)1414*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, DropAssociatedReceiverWithSyncCallInFlight) {
1415*6777b538SAndroid Build Coastguard Worker   // Regression test for https://crbug.com/331636067. Verifies that endpoint
1416*6777b538SAndroid Build Coastguard Worker   // lifetime is properly managed when associated endpoints are serialized into
1417*6777b538SAndroid Build Coastguard Worker   // a message that gets dropped before transmission.
1418*6777b538SAndroid Build Coastguard Worker 
1419*6777b538SAndroid Build Coastguard Worker   Init("SyncCallToDroppedReceiver");
1420*6777b538SAndroid Build Coastguard Worker   ListenerWithClumsyBinder listener;
1421*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1422*6777b538SAndroid Build Coastguard Worker   RunProxy();
1423*6777b538SAndroid Build Coastguard Worker   listener.RunUntilClientQuit();
1424*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1425*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1426*6777b538SAndroid Build Coastguard Worker }
1427*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncCallToDroppedReceiver,ChannelProxyClient)1428*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
1429*6777b538SAndroid Build Coastguard Worker     SyncCallToDroppedReceiver,
1430*6777b538SAndroid Build Coastguard Worker     ChannelProxyClient) {
1431*6777b538SAndroid Build Coastguard Worker   // Force-enable the fix, since ipc_tests doesn't initialize FeatureList.
1432*6777b538SAndroid Build Coastguard Worker   const base::test::ScopedFeatureList kFeatures(
1433*6777b538SAndroid Build Coastguard Worker       mojo::features::kMojoFixAssociatedHandleLeak);
1434*6777b538SAndroid Build Coastguard Worker 
1435*6777b538SAndroid Build Coastguard Worker   DummyListener listener;
1436*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1437*6777b538SAndroid Build Coastguard Worker   RunProxy();
1438*6777b538SAndroid Build Coastguard Worker 
1439*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<mojom::Binder> binder;
1440*6777b538SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(
1441*6777b538SAndroid Build Coastguard Worker       binder.BindNewEndpointAndPassReceiver());
1442*6777b538SAndroid Build Coastguard Worker 
1443*6777b538SAndroid Build Coastguard Worker   // Wait for disconnection to be observed. This way we know any subsequent
1444*6777b538SAndroid Build Coastguard Worker   // outgoing messages on `binder` will not be sent.
1445*6777b538SAndroid Build Coastguard Worker   base::RunLoop loop;
1446*6777b538SAndroid Build Coastguard Worker   binder.set_disconnect_handler(loop.QuitClosure());
1447*6777b538SAndroid Build Coastguard Worker   loop.Run();
1448*6777b538SAndroid Build Coastguard Worker 
1449*6777b538SAndroid Build Coastguard Worker   // Send another endpoint over. This receiver will be dropped, and the remote
1450*6777b538SAndroid Build Coastguard Worker   // should be properly notified of peer closure to terminate the sync call. The
1451*6777b538SAndroid Build Coastguard Worker   // call should return false (because no reply), but shouldn't hang.
1452*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<mojom::Binder> another_binder;
1453*6777b538SAndroid Build Coastguard Worker   binder->Bind(another_binder.BindNewEndpointAndPassReceiver());
1454*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(another_binder->Ping());
1455*6777b538SAndroid Build Coastguard Worker 
1456*6777b538SAndroid Build Coastguard Worker   SendString(proxy(), "ok bye");
1457*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1458*6777b538SAndroid Build Coastguard Worker }
1459*6777b538SAndroid Build Coastguard Worker 
1460*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/1500560): Disabled for flaky behavior of forced
1461*6777b538SAndroid Build Coastguard Worker // process termination. Will be re-enabled with a fix.
TEST_F(IPCChannelProxyMojoTest,DISABLED_SyncAssociatedInterfacePipeError)1462*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, DISABLED_SyncAssociatedInterfacePipeError) {
1463*6777b538SAndroid Build Coastguard Worker   // Regression test for https://crbug.com/1494461.
1464*6777b538SAndroid Build Coastguard Worker 
1465*6777b538SAndroid Build Coastguard Worker   Init("SyncAssociatedInterfacePipeError");
1466*6777b538SAndroid Build Coastguard Worker 
1467*6777b538SAndroid Build Coastguard Worker   ListenerWithSyncAssociatedInterface listener;
1468*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1469*6777b538SAndroid Build Coastguard Worker   listener.set_sync_sender(proxy());
1470*6777b538SAndroid Build Coastguard Worker   RunProxy();
1471*6777b538SAndroid Build Coastguard Worker 
1472*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::SimpleTestClient> client;
1473*6777b538SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(
1474*6777b538SAndroid Build Coastguard Worker       client.BindNewEndpointAndPassReceiver());
1475*6777b538SAndroid Build Coastguard Worker 
1476*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::Terminator> terminator;
1477*6777b538SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(
1478*6777b538SAndroid Build Coastguard Worker       terminator.BindNewEndpointAndPassReceiver());
1479*6777b538SAndroid Build Coastguard Worker 
1480*6777b538SAndroid Build Coastguard Worker   // The setup here is to have the client process add a new associated endpoint
1481*6777b538SAndroid Build Coastguard Worker   // with a sync message queued on it, towards us. As soon as we receive the
1482*6777b538SAndroid Build Coastguard Worker   // endpoint we close it, but its state (including its inbound sync message
1483*6777b538SAndroid Build Coastguard Worker   // queue) isn't actually destroyed until the peer is closed too.
1484*6777b538SAndroid Build Coastguard Worker   //
1485*6777b538SAndroid Build Coastguard Worker   // Note that the client creates the endpoint rather than us, because client
1486*6777b538SAndroid Build Coastguard Worker   // endpoints are assigned lower interface IDs and will thus elicit the
1487*6777b538SAndroid Build Coastguard Worker   // necessary endpoint ordering to trigger https://crbug.com/1494461 below.
1488*6777b538SAndroid Build Coastguard Worker   {
1489*6777b538SAndroid Build Coastguard Worker     base::RunLoop loop;
1490*6777b538SAndroid Build Coastguard Worker     client->GetReceiverWithQueuedSyncMessage(base::BindLambdaForTesting(
1491*6777b538SAndroid Build Coastguard Worker         [&loop](mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestClient>
1492*6777b538SAndroid Build Coastguard Worker                     receiver) { loop.Quit(); }));
1493*6777b538SAndroid Build Coastguard Worker     loop.Run();
1494*6777b538SAndroid Build Coastguard Worker   }
1495*6777b538SAndroid Build Coastguard Worker 
1496*6777b538SAndroid Build Coastguard Worker   // If https://crbug.com/1494461 is present, it should be hit within this call,
1497*6777b538SAndroid Build Coastguard Worker   // as soon as client termination signals a local pipe error and marks the
1498*6777b538SAndroid Build Coastguard Worker   // above endpoint's peer as closed.
1499*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(terminator->Terminate());
1500*6777b538SAndroid Build Coastguard Worker 
1501*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
1502*6777b538SAndroid Build Coastguard Worker   // NOTE: On Android, the client's forced termination will look like an error,
1503*6777b538SAndroid Build Coastguard Worker   // but it is not.
1504*6777b538SAndroid Build Coastguard Worker   WaitForClientShutdown();
1505*6777b538SAndroid Build Coastguard Worker #else
1506*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1507*6777b538SAndroid Build Coastguard Worker #endif
1508*6777b538SAndroid Build Coastguard Worker 
1509*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1510*6777b538SAndroid Build Coastguard Worker }
1511*6777b538SAndroid Build Coastguard Worker 
1512*6777b538SAndroid Build Coastguard Worker class TerminatorImpl : public IPC::mojom::Terminator {
1513*6777b538SAndroid Build Coastguard Worker  public:
1514*6777b538SAndroid Build Coastguard Worker   TerminatorImpl() = default;
1515*6777b538SAndroid Build Coastguard Worker   ~TerminatorImpl() override = default;
1516*6777b538SAndroid Build Coastguard Worker 
Create(mojo::PendingAssociatedReceiver<IPC::mojom::Terminator> receiver)1517*6777b538SAndroid Build Coastguard Worker   static void Create(
1518*6777b538SAndroid Build Coastguard Worker       mojo::PendingAssociatedReceiver<IPC::mojom::Terminator> receiver) {
1519*6777b538SAndroid Build Coastguard Worker     mojo::MakeSelfOwnedAssociatedReceiver(std::make_unique<TerminatorImpl>(),
1520*6777b538SAndroid Build Coastguard Worker                                           std::move(receiver));
1521*6777b538SAndroid Build Coastguard Worker   }
1522*6777b538SAndroid Build Coastguard Worker 
1523*6777b538SAndroid Build Coastguard Worker   // IPC::mojom::Terminator:
Terminate(TerminateCallback callback)1524*6777b538SAndroid Build Coastguard Worker   void Terminate(TerminateCallback callback) override {
1525*6777b538SAndroid Build Coastguard Worker     base::Process::TerminateCurrentProcessImmediately(0);
1526*6777b538SAndroid Build Coastguard Worker   }
1527*6777b538SAndroid Build Coastguard Worker };
1528*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterfacePipeError,ChannelProxyClient)1529*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
1530*6777b538SAndroid Build Coastguard Worker     SyncAssociatedInterfacePipeError,
1531*6777b538SAndroid Build Coastguard Worker     ChannelProxyClient) {
1532*6777b538SAndroid Build Coastguard Worker   SimpleTestClientImpl client_impl;
1533*6777b538SAndroid Build Coastguard Worker   CreateProxy(&client_impl);
1534*6777b538SAndroid Build Coastguard Worker 
1535*6777b538SAndroid Build Coastguard Worker   // Let the IO thread receive a message to self-terminate this process. This
1536*6777b538SAndroid Build Coastguard Worker   // is used to forcibly shut down the client on the test's request. Without
1537*6777b538SAndroid Build Coastguard Worker   // doing this (and doing a clean shutdown instead) the client will clean up
1538*6777b538SAndroid Build Coastguard Worker   // interfaces and make it impossible to trigger the regression path for
1539*6777b538SAndroid Build Coastguard Worker   // https://crbug.com/1494461.
1540*6777b538SAndroid Build Coastguard Worker   proxy()->AddAssociatedInterfaceForIOThread(
1541*6777b538SAndroid Build Coastguard Worker       base::BindRepeating(&TerminatorImpl::Create));
1542*6777b538SAndroid Build Coastguard Worker 
1543*6777b538SAndroid Build Coastguard Worker   RunProxy();
1544*6777b538SAndroid Build Coastguard Worker   client_impl.Run();
1545*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1546*6777b538SAndroid Build Coastguard Worker }
1547*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,Pause)1548*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, Pause) {
1549*6777b538SAndroid Build Coastguard Worker   // Ensures that pausing a channel elicits the expected behavior when sending
1550*6777b538SAndroid Build Coastguard Worker   // messages, unpausing, sending more messages, and then manually flushing.
1551*6777b538SAndroid Build Coastguard Worker   // Specifically a sequence like:
1552*6777b538SAndroid Build Coastguard Worker   //
1553*6777b538SAndroid Build Coastguard Worker   //   Connect()
1554*6777b538SAndroid Build Coastguard Worker   //   Send(A)
1555*6777b538SAndroid Build Coastguard Worker   //   Pause()
1556*6777b538SAndroid Build Coastguard Worker   //   Send(B)
1557*6777b538SAndroid Build Coastguard Worker   //   Send(C)
1558*6777b538SAndroid Build Coastguard Worker   //   Unpause(false)
1559*6777b538SAndroid Build Coastguard Worker   //   Send(D)
1560*6777b538SAndroid Build Coastguard Worker   //   Send(E)
1561*6777b538SAndroid Build Coastguard Worker   //   Flush()
1562*6777b538SAndroid Build Coastguard Worker   //
1563*6777b538SAndroid Build Coastguard Worker   // must result in the other end receiving messages A, D, E, B, D; in that
1564*6777b538SAndroid Build Coastguard Worker   // order.
1565*6777b538SAndroid Build Coastguard Worker   //
1566*6777b538SAndroid Build Coastguard Worker   // This behavior is required by some consumers of IPC::Channel, and it is not
1567*6777b538SAndroid Build Coastguard Worker   // sufficient to leave this up to the consumer to implement since associated
1568*6777b538SAndroid Build Coastguard Worker   // interface requests and messages also need to be queued according to the
1569*6777b538SAndroid Build Coastguard Worker   // same policy.
1570*6777b538SAndroid Build Coastguard Worker   Init("CreatePausedClient");
1571*6777b538SAndroid Build Coastguard Worker 
1572*6777b538SAndroid Build Coastguard Worker   DummyListener listener;
1573*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1574*6777b538SAndroid Build Coastguard Worker   RunProxy();
1575*6777b538SAndroid Build Coastguard Worker 
1576*6777b538SAndroid Build Coastguard Worker   // This message must be sent immediately since the channel is unpaused.
1577*6777b538SAndroid Build Coastguard Worker   SendValue(proxy(), 1);
1578*6777b538SAndroid Build Coastguard Worker 
1579*6777b538SAndroid Build Coastguard Worker   proxy()->Pause();
1580*6777b538SAndroid Build Coastguard Worker 
1581*6777b538SAndroid Build Coastguard Worker   // These messages must be queued internally since the channel is paused.
1582*6777b538SAndroid Build Coastguard Worker   SendValue(proxy(), 2);
1583*6777b538SAndroid Build Coastguard Worker   SendValue(proxy(), 3);
1584*6777b538SAndroid Build Coastguard Worker 
1585*6777b538SAndroid Build Coastguard Worker   proxy()->Unpause(false /* flush */);
1586*6777b538SAndroid Build Coastguard Worker 
1587*6777b538SAndroid Build Coastguard Worker   // These messages must be sent immediately since the channel is unpaused.
1588*6777b538SAndroid Build Coastguard Worker   SendValue(proxy(), 4);
1589*6777b538SAndroid Build Coastguard Worker   SendValue(proxy(), 5);
1590*6777b538SAndroid Build Coastguard Worker 
1591*6777b538SAndroid Build Coastguard Worker   // Now we flush the previously queued messages.
1592*6777b538SAndroid Build Coastguard Worker   proxy()->Flush();
1593*6777b538SAndroid Build Coastguard Worker 
1594*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1595*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1596*6777b538SAndroid Build Coastguard Worker }
1597*6777b538SAndroid Build Coastguard Worker 
1598*6777b538SAndroid Build Coastguard Worker class ExpectValueSequenceListener : public IPC::Listener {
1599*6777b538SAndroid Build Coastguard Worker  public:
ExpectValueSequenceListener(base::queue<int32_t> * expected_values,base::OnceClosure quit_closure)1600*6777b538SAndroid Build Coastguard Worker   ExpectValueSequenceListener(base::queue<int32_t>* expected_values,
1601*6777b538SAndroid Build Coastguard Worker                               base::OnceClosure quit_closure)
1602*6777b538SAndroid Build Coastguard Worker       : expected_values_(expected_values),
1603*6777b538SAndroid Build Coastguard Worker         quit_closure_(std::move(quit_closure)) {}
1604*6777b538SAndroid Build Coastguard Worker 
1605*6777b538SAndroid Build Coastguard Worker   ExpectValueSequenceListener(const ExpectValueSequenceListener&) = delete;
1606*6777b538SAndroid Build Coastguard Worker   ExpectValueSequenceListener& operator=(const ExpectValueSequenceListener&) =
1607*6777b538SAndroid Build Coastguard Worker       delete;
1608*6777b538SAndroid Build Coastguard Worker 
1609*6777b538SAndroid Build Coastguard Worker   ~ExpectValueSequenceListener() override = default;
1610*6777b538SAndroid Build Coastguard Worker 
1611*6777b538SAndroid Build Coastguard Worker   // IPC::Listener:
OnMessageReceived(const IPC::Message & message)1612*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1613*6777b538SAndroid Build Coastguard Worker     DCHECK(!expected_values_->empty());
1614*6777b538SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
1615*6777b538SAndroid Build Coastguard Worker     int32_t should_be_expected;
1616*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(iter.ReadInt(&should_be_expected));
1617*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(expected_values_->front(), should_be_expected);
1618*6777b538SAndroid Build Coastguard Worker     expected_values_->pop();
1619*6777b538SAndroid Build Coastguard Worker     if (expected_values_->empty())
1620*6777b538SAndroid Build Coastguard Worker       std::move(quit_closure_).Run();
1621*6777b538SAndroid Build Coastguard Worker     return true;
1622*6777b538SAndroid Build Coastguard Worker   }
1623*6777b538SAndroid Build Coastguard Worker 
1624*6777b538SAndroid Build Coastguard Worker  private:
1625*6777b538SAndroid Build Coastguard Worker   raw_ptr<base::queue<int32_t>> expected_values_;
1626*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
1627*6777b538SAndroid Build Coastguard Worker };
1628*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,ChannelProxyClient)1629*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,
1630*6777b538SAndroid Build Coastguard Worker                                                         ChannelProxyClient) {
1631*6777b538SAndroid Build Coastguard Worker   base::queue<int32_t> expected_values;
1632*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1633*6777b538SAndroid Build Coastguard Worker   ExpectValueSequenceListener listener(&expected_values,
1634*6777b538SAndroid Build Coastguard Worker                                        run_loop.QuitClosure());
1635*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1636*6777b538SAndroid Build Coastguard Worker   expected_values.push(1);
1637*6777b538SAndroid Build Coastguard Worker   expected_values.push(4);
1638*6777b538SAndroid Build Coastguard Worker   expected_values.push(5);
1639*6777b538SAndroid Build Coastguard Worker   expected_values.push(2);
1640*6777b538SAndroid Build Coastguard Worker   expected_values.push(3);
1641*6777b538SAndroid Build Coastguard Worker   RunProxy();
1642*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1643*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(expected_values.empty());
1644*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1645*6777b538SAndroid Build Coastguard Worker }
1646*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,AssociatedRequestClose)1647*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, AssociatedRequestClose) {
1648*6777b538SAndroid Build Coastguard Worker   Init("DropAssociatedRequest");
1649*6777b538SAndroid Build Coastguard Worker 
1650*6777b538SAndroid Build Coastguard Worker   DummyListener listener;
1651*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1652*6777b538SAndroid Build Coastguard Worker   RunProxy();
1653*6777b538SAndroid Build Coastguard Worker 
1654*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::AssociatedInterfaceVendor> vendor;
1655*6777b538SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(
1656*6777b538SAndroid Build Coastguard Worker       vendor.BindNewEndpointAndPassReceiver());
1657*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> tester;
1658*6777b538SAndroid Build Coastguard Worker   vendor->GetTestInterface(tester.BindNewEndpointAndPassReceiver());
1659*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1660*6777b538SAndroid Build Coastguard Worker   tester.set_disconnect_handler(run_loop.QuitClosure());
1661*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1662*6777b538SAndroid Build Coastguard Worker 
1663*6777b538SAndroid Build Coastguard Worker   tester.reset();
1664*6777b538SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(
1665*6777b538SAndroid Build Coastguard Worker       tester.BindNewEndpointAndPassReceiver());
1666*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1667*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1668*6777b538SAndroid Build Coastguard Worker }
1669*6777b538SAndroid Build Coastguard Worker 
1670*6777b538SAndroid Build Coastguard Worker class AssociatedInterfaceDroppingListener : public IPC::Listener {
1671*6777b538SAndroid Build Coastguard Worker  public:
AssociatedInterfaceDroppingListener(base::OnceClosure callback)1672*6777b538SAndroid Build Coastguard Worker   AssociatedInterfaceDroppingListener(base::OnceClosure callback)
1673*6777b538SAndroid Build Coastguard Worker       : callback_(std::move(callback)) {}
OnMessageReceived(const IPC::Message & message)1674*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return false; }
1675*6777b538SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)1676*6777b538SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
1677*6777b538SAndroid Build Coastguard Worker       const std::string& interface_name,
1678*6777b538SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
1679*6777b538SAndroid Build Coastguard Worker     if (interface_name == IPC::mojom::SimpleTestDriver::Name_)
1680*6777b538SAndroid Build Coastguard Worker       std::move(callback_).Run();
1681*6777b538SAndroid Build Coastguard Worker   }
1682*6777b538SAndroid Build Coastguard Worker 
1683*6777b538SAndroid Build Coastguard Worker  private:
1684*6777b538SAndroid Build Coastguard Worker   base::OnceClosure callback_;
1685*6777b538SAndroid Build Coastguard Worker };
1686*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,ChannelProxyClient)1687*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,
1688*6777b538SAndroid Build Coastguard Worker                                                         ChannelProxyClient) {
1689*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1690*6777b538SAndroid Build Coastguard Worker   AssociatedInterfaceDroppingListener listener(run_loop.QuitClosure());
1691*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
1692*6777b538SAndroid Build Coastguard Worker   RunProxy();
1693*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1694*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
1695*6777b538SAndroid Build Coastguard Worker }
1696*6777b538SAndroid Build Coastguard Worker 
1697*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_APPLE)
1698*6777b538SAndroid Build Coastguard Worker // TODO(wez): On Mac we need to set up a MachPortBroker before we can transfer
1699*6777b538SAndroid Build Coastguard Worker // Mach ports (which underpin Sharedmemory on Mac) across IPC.
1700*6777b538SAndroid Build Coastguard Worker 
1701*6777b538SAndroid Build Coastguard Worker template <class SharedMemoryRegionType>
1702*6777b538SAndroid Build Coastguard Worker class IPCChannelMojoSharedMemoryRegionTypedTest : public IPCChannelMojoTest {};
1703*6777b538SAndroid Build Coastguard Worker 
1704*6777b538SAndroid Build Coastguard Worker struct WritableRegionTraits {
1705*6777b538SAndroid Build Coastguard Worker   using RegionType = base::WritableSharedMemoryRegion;
1706*6777b538SAndroid Build Coastguard Worker   static const char kClientName[];
1707*6777b538SAndroid Build Coastguard Worker };
1708*6777b538SAndroid Build Coastguard Worker const char WritableRegionTraits::kClientName[] =
1709*6777b538SAndroid Build Coastguard Worker     "IPCChannelMojoTestSendWritableSharedMemoryRegionClient";
1710*6777b538SAndroid Build Coastguard Worker struct UnsafeRegionTraits {
1711*6777b538SAndroid Build Coastguard Worker   using RegionType = base::UnsafeSharedMemoryRegion;
1712*6777b538SAndroid Build Coastguard Worker   static const char kClientName[];
1713*6777b538SAndroid Build Coastguard Worker };
1714*6777b538SAndroid Build Coastguard Worker const char UnsafeRegionTraits::kClientName[] =
1715*6777b538SAndroid Build Coastguard Worker     "IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient";
1716*6777b538SAndroid Build Coastguard Worker struct ReadOnlyRegionTraits {
1717*6777b538SAndroid Build Coastguard Worker   using RegionType = base::ReadOnlySharedMemoryRegion;
1718*6777b538SAndroid Build Coastguard Worker   static const char kClientName[];
1719*6777b538SAndroid Build Coastguard Worker };
1720*6777b538SAndroid Build Coastguard Worker const char ReadOnlyRegionTraits::kClientName[] =
1721*6777b538SAndroid Build Coastguard Worker     "IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient";
1722*6777b538SAndroid Build Coastguard Worker 
1723*6777b538SAndroid Build Coastguard Worker typedef ::testing::
1724*6777b538SAndroid Build Coastguard Worker     Types<WritableRegionTraits, UnsafeRegionTraits, ReadOnlyRegionTraits>
1725*6777b538SAndroid Build Coastguard Worker         AllSharedMemoryRegionTraits;
1726*6777b538SAndroid Build Coastguard Worker TYPED_TEST_SUITE(IPCChannelMojoSharedMemoryRegionTypedTest,
1727*6777b538SAndroid Build Coastguard Worker                  AllSharedMemoryRegionTraits);
1728*6777b538SAndroid Build Coastguard Worker 
1729*6777b538SAndroid Build Coastguard Worker template <class SharedMemoryRegionType>
1730*6777b538SAndroid Build Coastguard Worker class ListenerThatExpectsSharedMemoryRegion : public TestListenerBase {
1731*6777b538SAndroid Build Coastguard Worker  public:
ListenerThatExpectsSharedMemoryRegion(base::OnceClosure quit_closure)1732*6777b538SAndroid Build Coastguard Worker   explicit ListenerThatExpectsSharedMemoryRegion(base::OnceClosure quit_closure)
1733*6777b538SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
1734*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)1735*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1736*6777b538SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
1737*6777b538SAndroid Build Coastguard Worker 
1738*6777b538SAndroid Build Coastguard Worker     SharedMemoryRegionType region;
1739*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(IPC::ReadParam(&message, &iter, &region));
1740*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(region.IsValid());
1741*6777b538SAndroid Build Coastguard Worker 
1742*6777b538SAndroid Build Coastguard Worker     // Verify the shared memory region has expected content.
1743*6777b538SAndroid Build Coastguard Worker     typename SharedMemoryRegionType::MappingType mapping = region.Map();
1744*6777b538SAndroid Build Coastguard Worker     std::string content = HandleSendingHelper::GetSendingFileContent();
1745*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(mapping.memory(), content.data(), content.size()));
1746*6777b538SAndroid Build Coastguard Worker 
1747*6777b538SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
1748*6777b538SAndroid Build Coastguard Worker     return true;
1749*6777b538SAndroid Build Coastguard Worker   }
1750*6777b538SAndroid Build Coastguard Worker };
1751*6777b538SAndroid Build Coastguard Worker 
TYPED_TEST(IPCChannelMojoSharedMemoryRegionTypedTest,Send)1752*6777b538SAndroid Build Coastguard Worker TYPED_TEST(IPCChannelMojoSharedMemoryRegionTypedTest, Send) {
1753*6777b538SAndroid Build Coastguard Worker   this->Init(TypeParam::kClientName);
1754*6777b538SAndroid Build Coastguard Worker 
1755*6777b538SAndroid Build Coastguard Worker   const size_t size = 1004;
1756*6777b538SAndroid Build Coastguard Worker   typename TypeParam::RegionType region;
1757*6777b538SAndroid Build Coastguard Worker   base::WritableSharedMemoryMapping mapping;
1758*6777b538SAndroid Build Coastguard Worker   std::tie(region, mapping) =
1759*6777b538SAndroid Build Coastguard Worker       base::CreateMappedRegion<typename TypeParam::RegionType>(size);
1760*6777b538SAndroid Build Coastguard Worker 
1761*6777b538SAndroid Build Coastguard Worker   std::string content = HandleSendingHelper::GetSendingFileContent();
1762*6777b538SAndroid Build Coastguard Worker   memcpy(mapping.memory(), content.data(), content.size());
1763*6777b538SAndroid Build Coastguard Worker 
1764*6777b538SAndroid Build Coastguard Worker   // Create a success listener, and launch the child process.
1765*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1766*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
1767*6777b538SAndroid Build Coastguard Worker   this->CreateChannel(&listener);
1768*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(this->ConnectChannel());
1769*6777b538SAndroid Build Coastguard Worker 
1770*6777b538SAndroid Build Coastguard Worker   // Send the child process an IPC with |shmem| attached, to verify
1771*6777b538SAndroid Build Coastguard Worker   // that is is correctly wrapped, transferred and unwrapped.
1772*6777b538SAndroid Build Coastguard Worker   IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
1773*6777b538SAndroid Build Coastguard Worker   IPC::WriteParam(message, region);
1774*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(this->channel()->Send(message));
1775*6777b538SAndroid Build Coastguard Worker 
1776*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1777*6777b538SAndroid Build Coastguard Worker 
1778*6777b538SAndroid Build Coastguard Worker   this->channel()->Close();
1779*6777b538SAndroid Build Coastguard Worker 
1780*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(this->WaitForClientShutdown());
1781*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(region.IsValid());
1782*6777b538SAndroid Build Coastguard Worker   this->DestroyChannel();
1783*6777b538SAndroid Build Coastguard Worker }
1784*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendWritableSharedMemoryRegionClient)1785*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1786*6777b538SAndroid Build Coastguard Worker     IPCChannelMojoTestSendWritableSharedMemoryRegionClient) {
1787*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1788*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsSharedMemoryRegion<base::WritableSharedMemoryRegion>
1789*6777b538SAndroid Build Coastguard Worker       listener(run_loop.QuitClosure());
1790*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
1791*6777b538SAndroid Build Coastguard Worker   listener.set_sender(channel());
1792*6777b538SAndroid Build Coastguard Worker 
1793*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1794*6777b538SAndroid Build Coastguard Worker 
1795*6777b538SAndroid Build Coastguard Worker   Close();
1796*6777b538SAndroid Build Coastguard Worker }
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient)1797*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1798*6777b538SAndroid Build Coastguard Worker     IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient) {
1799*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1800*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsSharedMemoryRegion<base::UnsafeSharedMemoryRegion>
1801*6777b538SAndroid Build Coastguard Worker       listener(run_loop.QuitClosure());
1802*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
1803*6777b538SAndroid Build Coastguard Worker   listener.set_sender(channel());
1804*6777b538SAndroid Build Coastguard Worker 
1805*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1806*6777b538SAndroid Build Coastguard Worker 
1807*6777b538SAndroid Build Coastguard Worker   Close();
1808*6777b538SAndroid Build Coastguard Worker }
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient)1809*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1810*6777b538SAndroid Build Coastguard Worker     IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient) {
1811*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1812*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsSharedMemoryRegion<base::ReadOnlySharedMemoryRegion>
1813*6777b538SAndroid Build Coastguard Worker       listener(run_loop.QuitClosure());
1814*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
1815*6777b538SAndroid Build Coastguard Worker   listener.set_sender(channel());
1816*6777b538SAndroid Build Coastguard Worker 
1817*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1818*6777b538SAndroid Build Coastguard Worker 
1819*6777b538SAndroid Build Coastguard Worker   Close();
1820*6777b538SAndroid Build Coastguard Worker }
1821*6777b538SAndroid Build Coastguard Worker #endif  // !BUILDFLAG(IS_APPLE)
1822*6777b538SAndroid Build Coastguard Worker 
1823*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
1824*6777b538SAndroid Build Coastguard Worker 
1825*6777b538SAndroid Build Coastguard Worker class ListenerThatExpectsFile : public TestListenerBase {
1826*6777b538SAndroid Build Coastguard Worker  public:
ListenerThatExpectsFile(base::OnceClosure quit_closure)1827*6777b538SAndroid Build Coastguard Worker   explicit ListenerThatExpectsFile(base::OnceClosure quit_closure)
1828*6777b538SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
1829*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)1830*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1831*6777b538SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
1832*6777b538SAndroid Build Coastguard Worker     HandleSendingHelper::ReadReceivedFile(message, &iter);
1833*6777b538SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
1834*6777b538SAndroid Build Coastguard Worker     return true;
1835*6777b538SAndroid Build Coastguard Worker   }
1836*6777b538SAndroid Build Coastguard Worker };
1837*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendPlatformFile)1838*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendPlatformFile) {
1839*6777b538SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestSendPlatformFileClient");
1840*6777b538SAndroid Build Coastguard Worker 
1841*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1842*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
1843*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
1844*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
1845*6777b538SAndroid Build Coastguard Worker 
1846*6777b538SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
1847*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1848*6777b538SAndroid Build Coastguard Worker   base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
1849*6777b538SAndroid Build Coastguard Worker                   base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1850*6777b538SAndroid Build Coastguard Worker                       base::File::FLAG_READ);
1851*6777b538SAndroid Build Coastguard Worker   HandleSendingHelper::WriteFileThenSend(channel(), file);
1852*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1853*6777b538SAndroid Build Coastguard Worker 
1854*6777b538SAndroid Build Coastguard Worker   channel()->Close();
1855*6777b538SAndroid Build Coastguard Worker 
1856*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1857*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
1858*6777b538SAndroid Build Coastguard Worker }
1859*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileClient)1860*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileClient) {
1861*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1862*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsFile listener(run_loop.QuitClosure());
1863*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
1864*6777b538SAndroid Build Coastguard Worker   listener.set_sender(channel());
1865*6777b538SAndroid Build Coastguard Worker 
1866*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1867*6777b538SAndroid Build Coastguard Worker 
1868*6777b538SAndroid Build Coastguard Worker   Close();
1869*6777b538SAndroid Build Coastguard Worker }
1870*6777b538SAndroid Build Coastguard Worker 
1871*6777b538SAndroid Build Coastguard Worker class ListenerThatExpectsFileAndMessagePipe : public TestListenerBase {
1872*6777b538SAndroid Build Coastguard Worker  public:
ListenerThatExpectsFileAndMessagePipe(base::OnceClosure quit_closure)1873*6777b538SAndroid Build Coastguard Worker   explicit ListenerThatExpectsFileAndMessagePipe(base::OnceClosure quit_closure)
1874*6777b538SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
1875*6777b538SAndroid Build Coastguard Worker 
1876*6777b538SAndroid Build Coastguard Worker   ~ListenerThatExpectsFileAndMessagePipe() override = default;
1877*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)1878*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1879*6777b538SAndroid Build Coastguard Worker     base::PickleIterator iter(message);
1880*6777b538SAndroid Build Coastguard Worker     HandleSendingHelper::ReadReceivedFile(message, &iter);
1881*6777b538SAndroid Build Coastguard Worker     HandleSendingHelper::ReadReceivedPipe(message, &iter);
1882*6777b538SAndroid Build Coastguard Worker     ListenerThatExpectsOK::SendOK(sender());
1883*6777b538SAndroid Build Coastguard Worker     return true;
1884*6777b538SAndroid Build Coastguard Worker   }
1885*6777b538SAndroid Build Coastguard Worker };
1886*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelMojoTest,SendPlatformFileAndMessagePipe)1887*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, SendPlatformFileAndMessagePipe) {
1888*6777b538SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestSendPlatformFileAndMessagePipeClient");
1889*6777b538SAndroid Build Coastguard Worker 
1890*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1891*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsOK listener(run_loop.QuitClosure());
1892*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
1893*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
1894*6777b538SAndroid Build Coastguard Worker 
1895*6777b538SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
1896*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1897*6777b538SAndroid Build Coastguard Worker   base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
1898*6777b538SAndroid Build Coastguard Worker                   base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1899*6777b538SAndroid Build Coastguard Worker                       base::File::FLAG_READ);
1900*6777b538SAndroid Build Coastguard Worker   TestingMessagePipe pipe;
1901*6777b538SAndroid Build Coastguard Worker   HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
1902*6777b538SAndroid Build Coastguard Worker 
1903*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1904*6777b538SAndroid Build Coastguard Worker   channel()->Close();
1905*6777b538SAndroid Build Coastguard Worker 
1906*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1907*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
1908*6777b538SAndroid Build Coastguard Worker }
1909*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileAndMessagePipeClient)1910*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1911*6777b538SAndroid Build Coastguard Worker     IPCChannelMojoTestSendPlatformFileAndMessagePipeClient) {
1912*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1913*6777b538SAndroid Build Coastguard Worker   ListenerThatExpectsFileAndMessagePipe listener(run_loop.QuitClosure());
1914*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
1915*6777b538SAndroid Build Coastguard Worker   listener.set_sender(channel());
1916*6777b538SAndroid Build Coastguard Worker 
1917*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1918*6777b538SAndroid Build Coastguard Worker 
1919*6777b538SAndroid Build Coastguard Worker   Close();
1920*6777b538SAndroid Build Coastguard Worker }
1921*6777b538SAndroid Build Coastguard Worker 
1922*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
1923*6777b538SAndroid Build Coastguard Worker 
1924*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
1925*6777b538SAndroid Build Coastguard Worker 
1926*6777b538SAndroid Build Coastguard Worker const base::ProcessId kMagicChildId = 54321;
1927*6777b538SAndroid Build Coastguard Worker 
1928*6777b538SAndroid Build Coastguard Worker class ListenerThatVerifiesPeerPid : public TestListenerBase {
1929*6777b538SAndroid Build Coastguard Worker  public:
ListenerThatVerifiesPeerPid(base::OnceClosure quit_closure)1930*6777b538SAndroid Build Coastguard Worker   explicit ListenerThatVerifiesPeerPid(base::OnceClosure quit_closure)
1931*6777b538SAndroid Build Coastguard Worker       : TestListenerBase(std::move(quit_closure)) {}
1932*6777b538SAndroid Build Coastguard Worker 
OnChannelConnected(int32_t peer_pid)1933*6777b538SAndroid Build Coastguard Worker   void OnChannelConnected(int32_t peer_pid) override {
1934*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(peer_pid, kMagicChildId);
1935*6777b538SAndroid Build Coastguard Worker     RunQuitClosure();
1936*6777b538SAndroid Build Coastguard Worker   }
1937*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const IPC::Message & message)1938*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override {
1939*6777b538SAndroid Build Coastguard Worker     NOTREACHED();
1940*6777b538SAndroid Build Coastguard Worker     return true;
1941*6777b538SAndroid Build Coastguard Worker   }
1942*6777b538SAndroid Build Coastguard Worker };
1943*6777b538SAndroid Build Coastguard Worker 
1944*6777b538SAndroid Build Coastguard Worker // The global PID is only used on systems that use the zygote. Hence, this
1945*6777b538SAndroid Build Coastguard Worker // test is disabled on other platforms.
TEST_F(IPCChannelMojoTest,VerifyGlobalPid)1946*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
1947*6777b538SAndroid Build Coastguard Worker   Init("IPCChannelMojoTestVerifyGlobalPidClient");
1948*6777b538SAndroid Build Coastguard Worker 
1949*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1950*6777b538SAndroid Build Coastguard Worker   ListenerThatVerifiesPeerPid listener(run_loop.QuitClosure());
1951*6777b538SAndroid Build Coastguard Worker   CreateChannel(&listener);
1952*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectChannel());
1953*6777b538SAndroid Build Coastguard Worker 
1954*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1955*6777b538SAndroid Build Coastguard Worker   channel()->Close();
1956*6777b538SAndroid Build Coastguard Worker 
1957*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
1958*6777b538SAndroid Build Coastguard Worker   DestroyChannel();
1959*6777b538SAndroid Build Coastguard Worker }
1960*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient)1961*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient) {
1962*6777b538SAndroid Build Coastguard Worker   IPC::Channel::SetGlobalPid(kMagicChildId);
1963*6777b538SAndroid Build Coastguard Worker 
1964*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
1965*6777b538SAndroid Build Coastguard Worker   ListenerThatQuits listener(run_loop.QuitClosure());
1966*6777b538SAndroid Build Coastguard Worker   Connect(&listener);
1967*6777b538SAndroid Build Coastguard Worker 
1968*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
1969*6777b538SAndroid Build Coastguard Worker 
1970*6777b538SAndroid Build Coastguard Worker   Close();
1971*6777b538SAndroid Build Coastguard Worker }
1972*6777b538SAndroid Build Coastguard Worker 
1973*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
1974*6777b538SAndroid Build Coastguard Worker 
1975*6777b538SAndroid Build Coastguard Worker class ListenerWithUrgentMessageAssociatedInterface
1976*6777b538SAndroid Build Coastguard Worker     : public IPC::mojom::InterfaceWithUrgentMethod,
1977*6777b538SAndroid Build Coastguard Worker       public IPC::Listener,
1978*6777b538SAndroid Build Coastguard Worker       public IPC::UrgentMessageObserver {
1979*6777b538SAndroid Build Coastguard Worker  public:
ListenerWithUrgentMessageAssociatedInterface(base::OnceClosure quit_closure)1980*6777b538SAndroid Build Coastguard Worker   explicit ListenerWithUrgentMessageAssociatedInterface(
1981*6777b538SAndroid Build Coastguard Worker       base::OnceClosure quit_closure)
1982*6777b538SAndroid Build Coastguard Worker       : quit_closure_(std::move(quit_closure)) {}
1983*6777b538SAndroid Build Coastguard Worker 
1984*6777b538SAndroid Build Coastguard Worker   ListenerWithUrgentMessageAssociatedInterface(
1985*6777b538SAndroid Build Coastguard Worker       const ListenerWithUrgentMessageAssociatedInterface&) = delete;
1986*6777b538SAndroid Build Coastguard Worker   ListenerWithUrgentMessageAssociatedInterface& operator=(
1987*6777b538SAndroid Build Coastguard Worker       const ListenerWithUrgentMessageAssociatedInterface&) = delete;
1988*6777b538SAndroid Build Coastguard Worker 
1989*6777b538SAndroid Build Coastguard Worker   ~ListenerWithUrgentMessageAssociatedInterface() override = default;
1990*6777b538SAndroid Build Coastguard Worker 
num_maybe_urgent_messages_received() const1991*6777b538SAndroid Build Coastguard Worker   uint32_t num_maybe_urgent_messages_received() const {
1992*6777b538SAndroid Build Coastguard Worker     return num_maybe_urgent_messages_received_;
1993*6777b538SAndroid Build Coastguard Worker   }
1994*6777b538SAndroid Build Coastguard Worker 
num_urgent_messages_received() const1995*6777b538SAndroid Build Coastguard Worker   uint32_t num_urgent_messages_received() const {
1996*6777b538SAndroid Build Coastguard Worker     return num_urgent_messages_received_;
1997*6777b538SAndroid Build Coastguard Worker   }
1998*6777b538SAndroid Build Coastguard Worker 
num_non_urgent_messages_received() const1999*6777b538SAndroid Build Coastguard Worker   uint32_t num_non_urgent_messages_received() const {
2000*6777b538SAndroid Build Coastguard Worker     return num_non_urgent_messages_received_;
2001*6777b538SAndroid Build Coastguard Worker   }
2002*6777b538SAndroid Build Coastguard Worker 
num_observer_urgent_messages_received() const2003*6777b538SAndroid Build Coastguard Worker   uint32_t num_observer_urgent_messages_received() const {
2004*6777b538SAndroid Build Coastguard Worker     return num_observer_urgent_messages_received_.load(
2005*6777b538SAndroid Build Coastguard Worker         std::memory_order_relaxed);
2006*6777b538SAndroid Build Coastguard Worker   }
2007*6777b538SAndroid Build Coastguard Worker 
num_observer_urgent_messages_processed() const2008*6777b538SAndroid Build Coastguard Worker   uint32_t num_observer_urgent_messages_processed() const {
2009*6777b538SAndroid Build Coastguard Worker     return num_observer_urgent_messages_processed_.load(
2010*6777b538SAndroid Build Coastguard Worker         std::memory_order_relaxed);
2011*6777b538SAndroid Build Coastguard Worker   }
2012*6777b538SAndroid Build Coastguard Worker 
was_process_callback_pending_during_ipc_dispatch() const2013*6777b538SAndroid Build Coastguard Worker   bool was_process_callback_pending_during_ipc_dispatch() const {
2014*6777b538SAndroid Build Coastguard Worker     return was_process_callback_pending_during_ipc_dispatch_;
2015*6777b538SAndroid Build Coastguard Worker   }
2016*6777b538SAndroid Build Coastguard Worker 
2017*6777b538SAndroid Build Coastguard Worker  private:
2018*6777b538SAndroid Build Coastguard Worker   // IPC::mojom::InterfaceWithUrgentMethod:
MaybeUrgentMessage(bool is_urgent)2019*6777b538SAndroid Build Coastguard Worker   void MaybeUrgentMessage(bool is_urgent) override {
2020*6777b538SAndroid Build Coastguard Worker     ++num_maybe_urgent_messages_received_;
2021*6777b538SAndroid Build Coastguard Worker     if (!is_urgent) {
2022*6777b538SAndroid Build Coastguard Worker       return;
2023*6777b538SAndroid Build Coastguard Worker     }
2024*6777b538SAndroid Build Coastguard Worker     ++num_urgent_messages_received_;
2025*6777b538SAndroid Build Coastguard Worker     uint32_t received =
2026*6777b538SAndroid Build Coastguard Worker         num_observer_urgent_messages_received_.load(std::memory_order_relaxed);
2027*6777b538SAndroid Build Coastguard Worker     uint32_t processed =
2028*6777b538SAndroid Build Coastguard Worker         num_observer_urgent_messages_processed_.load(std::memory_order_relaxed);
2029*6777b538SAndroid Build Coastguard Worker     // The "processed" observer callback should run after the IPC is dispatched,
2030*6777b538SAndroid Build Coastguard Worker     // so there should always be at least one less processed callback here.
2031*6777b538SAndroid Build Coastguard Worker     was_process_callback_pending_during_ipc_dispatch_ =
2032*6777b538SAndroid Build Coastguard Worker         was_process_callback_pending_during_ipc_dispatch_ &&
2033*6777b538SAndroid Build Coastguard Worker         (processed < received);
2034*6777b538SAndroid Build Coastguard Worker   }
2035*6777b538SAndroid Build Coastguard Worker 
NonUrgentMessage()2036*6777b538SAndroid Build Coastguard Worker   void NonUrgentMessage() override { ++num_non_urgent_messages_received_; }
2037*6777b538SAndroid Build Coastguard Worker 
RequestQuit(RequestQuitCallback callback)2038*6777b538SAndroid Build Coastguard Worker   void RequestQuit(RequestQuitCallback callback) override {
2039*6777b538SAndroid Build Coastguard Worker     std::move(quit_closure_).Run();
2040*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run();
2041*6777b538SAndroid Build Coastguard Worker   }
2042*6777b538SAndroid Build Coastguard Worker 
2043*6777b538SAndroid Build Coastguard Worker   // IPC::Listener:
OnMessageReceived(const IPC::Message & message)2044*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const IPC::Message& message) override { return true; }
2045*6777b538SAndroid Build Coastguard Worker 
OnAssociatedInterfaceRequest(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle handle)2046*6777b538SAndroid Build Coastguard Worker   void OnAssociatedInterfaceRequest(
2047*6777b538SAndroid Build Coastguard Worker       const std::string& interface_name,
2048*6777b538SAndroid Build Coastguard Worker       mojo::ScopedInterfaceEndpointHandle handle) override {
2049*6777b538SAndroid Build Coastguard Worker     CHECK(!receiver_.is_bound());
2050*6777b538SAndroid Build Coastguard Worker     CHECK_EQ(interface_name, IPC::mojom::InterfaceWithUrgentMethod::Name_);
2051*6777b538SAndroid Build Coastguard Worker     receiver_.Bind(
2052*6777b538SAndroid Build Coastguard Worker         mojo::PendingAssociatedReceiver<IPC::mojom::InterfaceWithUrgentMethod>(
2053*6777b538SAndroid Build Coastguard Worker             std::move(handle)));
2054*6777b538SAndroid Build Coastguard Worker   }
2055*6777b538SAndroid Build Coastguard Worker 
2056*6777b538SAndroid Build Coastguard Worker   // IPC::UrgentMessageObserver:
OnUrgentMessageReceived()2057*6777b538SAndroid Build Coastguard Worker   void OnUrgentMessageReceived() override {
2058*6777b538SAndroid Build Coastguard Worker     std::atomic_fetch_add_explicit(&num_observer_urgent_messages_received_,
2059*6777b538SAndroid Build Coastguard Worker                                    uint32_t(1), std::memory_order_relaxed);
2060*6777b538SAndroid Build Coastguard Worker   }
2061*6777b538SAndroid Build Coastguard Worker 
OnUrgentMessageProcessed()2062*6777b538SAndroid Build Coastguard Worker   void OnUrgentMessageProcessed() override {
2063*6777b538SAndroid Build Coastguard Worker     std::atomic_fetch_add_explicit(&num_observer_urgent_messages_processed_,
2064*6777b538SAndroid Build Coastguard Worker                                    uint32_t(1), std::memory_order_relaxed);
2065*6777b538SAndroid Build Coastguard Worker   }
2066*6777b538SAndroid Build Coastguard Worker 
2067*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
2068*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedReceiver<IPC::mojom::InterfaceWithUrgentMethod> receiver_{
2069*6777b538SAndroid Build Coastguard Worker       this};
2070*6777b538SAndroid Build Coastguard Worker   uint32_t num_maybe_urgent_messages_received_{0};
2071*6777b538SAndroid Build Coastguard Worker   uint32_t num_urgent_messages_received_{0};
2072*6777b538SAndroid Build Coastguard Worker   uint32_t num_non_urgent_messages_received_{0};
2073*6777b538SAndroid Build Coastguard Worker   std::atomic<uint32_t> num_observer_urgent_messages_received_{0};
2074*6777b538SAndroid Build Coastguard Worker   std::atomic<uint32_t> num_observer_urgent_messages_processed_{0};
2075*6777b538SAndroid Build Coastguard Worker   bool was_process_callback_pending_during_ipc_dispatch_{true};
2076*6777b538SAndroid Build Coastguard Worker };
2077*6777b538SAndroid Build Coastguard Worker 
TEST_F(IPCChannelProxyMojoTest,UrgentMessageObserver)2078*6777b538SAndroid Build Coastguard Worker TEST_F(IPCChannelProxyMojoTest, UrgentMessageObserver) {
2079*6777b538SAndroid Build Coastguard Worker   Init("UrgentMessageObserverClient");
2080*6777b538SAndroid Build Coastguard Worker 
2081*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
2082*6777b538SAndroid Build Coastguard Worker   ListenerWithUrgentMessageAssociatedInterface listener(run_loop.QuitClosure());
2083*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener, /*urgent_message_observer=*/&listener);
2084*6777b538SAndroid Build Coastguard Worker   RunProxy();
2085*6777b538SAndroid Build Coastguard Worker 
2086*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
2087*6777b538SAndroid Build Coastguard Worker 
2088*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(WaitForClientShutdown());
2089*6777b538SAndroid Build Coastguard Worker 
2090*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(listener.num_maybe_urgent_messages_received(), 5u);
2091*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(listener.num_urgent_messages_received(), 3u);
2092*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(listener.num_non_urgent_messages_received(), 2u);
2093*6777b538SAndroid Build Coastguard Worker 
2094*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(listener.num_observer_urgent_messages_received(), 3u);
2095*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(listener.num_observer_urgent_messages_processed(), 3u);
2096*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(listener.was_process_callback_pending_during_ipc_dispatch());
2097*6777b538SAndroid Build Coastguard Worker 
2098*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
2099*6777b538SAndroid Build Coastguard Worker }
2100*6777b538SAndroid Build Coastguard Worker 
DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(UrgentMessageObserverClient,ChannelProxyClient)2101*6777b538SAndroid Build Coastguard Worker DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
2102*6777b538SAndroid Build Coastguard Worker     UrgentMessageObserverClient,
2103*6777b538SAndroid Build Coastguard Worker     ChannelProxyClient) {
2104*6777b538SAndroid Build Coastguard Worker   DummyListener listener;
2105*6777b538SAndroid Build Coastguard Worker   CreateProxy(&listener);
2106*6777b538SAndroid Build Coastguard Worker   RunProxy();
2107*6777b538SAndroid Build Coastguard Worker 
2108*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedRemote<IPC::mojom::InterfaceWithUrgentMethod> remote;
2109*6777b538SAndroid Build Coastguard Worker   proxy()->GetRemoteAssociatedInterface(
2110*6777b538SAndroid Build Coastguard Worker       remote.BindNewEndpointAndPassReceiver());
2111*6777b538SAndroid Build Coastguard Worker 
2112*6777b538SAndroid Build Coastguard Worker   {
2113*6777b538SAndroid Build Coastguard Worker     mojo::UrgentMessageScope scope;
2114*6777b538SAndroid Build Coastguard Worker     remote->MaybeUrgentMessage(/*is_urgent=*/true);
2115*6777b538SAndroid Build Coastguard Worker   }
2116*6777b538SAndroid Build Coastguard Worker   remote->NonUrgentMessage();
2117*6777b538SAndroid Build Coastguard Worker   remote->MaybeUrgentMessage(/*is_urgent=*/false);
2118*6777b538SAndroid Build Coastguard Worker   {
2119*6777b538SAndroid Build Coastguard Worker     mojo::UrgentMessageScope scope;
2120*6777b538SAndroid Build Coastguard Worker     remote->MaybeUrgentMessage(/*is_urgent=*/true);
2121*6777b538SAndroid Build Coastguard Worker   }
2122*6777b538SAndroid Build Coastguard Worker   remote->NonUrgentMessage();
2123*6777b538SAndroid Build Coastguard Worker   remote->MaybeUrgentMessage(/*is_urgent=*/false);
2124*6777b538SAndroid Build Coastguard Worker   {
2125*6777b538SAndroid Build Coastguard Worker     mojo::UrgentMessageScope scope;
2126*6777b538SAndroid Build Coastguard Worker     remote->MaybeUrgentMessage(/*is_urgent=*/true);
2127*6777b538SAndroid Build Coastguard Worker   }
2128*6777b538SAndroid Build Coastguard Worker 
2129*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
2130*6777b538SAndroid Build Coastguard Worker   remote->RequestQuit(run_loop.QuitClosure());
2131*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
2132*6777b538SAndroid Build Coastguard Worker 
2133*6777b538SAndroid Build Coastguard Worker   DestroyProxy();
2134*6777b538SAndroid Build Coastguard Worker }
2135*6777b538SAndroid Build Coastguard Worker 
2136*6777b538SAndroid Build Coastguard Worker }  // namespace
2137*6777b538SAndroid Build Coastguard Worker }  // namespace ipc_channel_mojo_unittest
2138