blob: 595a4ffac7d93499c7a226e33fba80244b46c690 [file] [log] [blame]
[email protected]64860882014-08-04 23:44:171// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
amistryd4aa70d2016-06-23 07:52:375#include "ipc/ipc_channel_mojo.h"
[email protected]64860882014-08-04 23:44:176
avi246998d82015-12-22 02:39:047#include <stddef.h>
tfarina10a5c062015-09-04 18:47:578#include <stdint.h>
rockot7c6bf952016-07-14 00:34:119
danakj03de39b22016-04-23 04:21:0910#include <memory>
dchenge48600452015-12-28 02:24:5011#include <utility>
tfarina10a5c062015-09-04 18:47:5712
[email protected]64860882014-08-04 23:44:1713#include "base/base_paths.h"
rockot8d890f62016-07-14 16:37:1414#include "base/bind.h"
sammc5c8a6c62017-02-04 01:33:3815#include "base/callback_helpers.h"
Brett Wilsona62d9c02017-09-20 20:53:2016#include "base/containers/queue.h"
[email protected]64860882014-08-04 23:44:1717#include "base/files/file.h"
amistry20e2b1d62016-06-23 06:12:3518#include "base/files/scoped_temp_dir.h"
skyostile687bdff2015-05-12 11:29:2119#include "base/location.h"
Alexandr Ilind497eee2018-04-19 22:50:5420#include "base/memory/platform_shared_memory_region.h"
Keishi Hattori0e45c022021-11-27 09:25:5221#include "base/memory/raw_ptr.h"
Alex Ilinf2c7fa232019-11-20 14:09:5822#include "base/memory/read_only_shared_memory_region.h"
Alexandr Ilind497eee2018-04-19 22:50:5423#include "base/memory/shared_memory_mapping.h"
Alex Ilinf2c7fa232019-11-20 14:09:5824#include "base/memory/unsafe_shared_memory_region.h"
25#include "base/memory/writable_shared_memory_region.h"
Carlos Caballerodd8bf7b042019-07-30 14:14:1526#include "base/message_loop/message_pump_type.h"
[email protected]64860882014-08-04 23:44:1727#include "base/path_service.h"
28#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0429#include "base/run_loop.h"
rockot9abe09b2016-08-02 20:57:3430#include "base/synchronization/waitable_event.h"
Patrick Monette643cdf62021-10-15 19:13:4231#include "base/task/single_thread_task_runner.h"
Guido Urdanetaef4e91942020-11-09 15:06:2432#include "base/test/bind.h"
Gabriel Charettec7108742019-08-23 03:31:4033#include "base/test/task_environment.h"
sammc57ed9f982016-03-10 06:28:3534#include "base/test/test_io_thread.h"
Alexandr Ilind497eee2018-04-19 22:50:5435#include "base/test/test_shared_memory_util.h"
morrita0bd20bd2015-02-25 20:11:2736#include "base/test/test_timeouts.h"
[email protected]64860882014-08-04 23:44:1737#include "base/threading/thread.h"
gabf08ccc02016-05-11 18:51:1138#include "base/threading/thread_task_runner_handle.h"
avi246998d82015-12-22 02:39:0439#include "build/build_config.h"
[email protected]64860882014-08-04 23:44:1740#include "ipc/ipc_message.h"
Wez831ae412017-08-30 00:29:3641#include "ipc/ipc_message_utils.h"
amistryd4aa70d2016-06-23 07:52:3742#include "ipc/ipc_mojo_handle_attachment.h"
43#include "ipc/ipc_mojo_message_helper.h"
44#include "ipc/ipc_mojo_param_traits.h"
rockot9abe09b2016-08-02 20:57:3445#include "ipc/ipc_sync_channel.h"
46#include "ipc/ipc_sync_message.h"
rockot7c6bf952016-07-14 00:34:1147#include "ipc/ipc_test.mojom.h"
[email protected]64860882014-08-04 23:44:1748#include "ipc/ipc_test_base.h"
49#include "ipc/ipc_test_channel_listener.h"
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:1550#include "mojo/public/cpp/bindings/associated_receiver.h"
51#include "mojo/public/cpp/bindings/associated_remote.h"
Ken Rockot138153b2018-07-13 23:31:5752#include "mojo/public/cpp/bindings/lib/validation_errors.h"
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:1553#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
Ken Rockot942af102020-06-04 05:48:4654#include "mojo/public/cpp/system/functions.h"
rockota9d566a2017-03-17 19:36:1555#include "mojo/public/cpp/system/wait.h"
sammc57ed9f982016-03-10 06:28:3556#include "testing/gtest/include/gtest/gtest.h"
Anton Bikineev1f42a452021-05-15 18:02:5057#include "third_party/abseil-cpp/absl/types/optional.h"
[email protected]64860882014-08-04 23:44:1758
Xiaohan Wangab909b32022-01-12 17:57:3959#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
[email protected]64860882014-08-04 23:44:1760#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4261#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1762#endif
63
64namespace {
65
rockot7c6bf952016-07-14 00:34:1166void SendString(IPC::Sender* sender, const std::string& str) {
67 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
68 message->WriteString(str);
69 ASSERT_TRUE(sender->Send(message));
70}
71
rockot9abe09b2016-08-02 20:57:3472void SendValue(IPC::Sender* sender, int32_t value) {
73 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
74 message->WriteInt(value);
75 ASSERT_TRUE(sender->Send(message));
76}
77
[email protected]64860882014-08-04 23:44:1778class ListenerThatExpectsOK : public IPC::Listener {
79 public:
Wezfdb98482018-07-12 01:21:3980 explicit ListenerThatExpectsOK(base::OnceClosure quit_closure)
81 : received_ok_(false), quit_closure_(std::move(quit_closure)) {}
[email protected]64860882014-08-04 23:44:1782
Chris Watkins2d879af2017-11-30 02:11:5983 ~ListenerThatExpectsOK() override = default;
[email protected]64860882014-08-04 23:44:1784
dchengfe61fca2014-10-22 02:29:5285 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2586 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1787 std::string should_be_ok;
88 EXPECT_TRUE(iter.ReadString(&should_be_ok));
89 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1390 received_ok_ = true;
Wezfdb98482018-07-12 01:21:3991 std::move(quit_closure_).Run();
[email protected]64860882014-08-04 23:44:1792 return true;
93 }
94
dchengfe61fca2014-10-22 02:29:5295 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1396 // The connection should be healthy while the listener is waiting
97 // message. An error can occur after that because the peer
98 // process dies.
Wezd95d48042018-02-26 20:50:4799 CHECK(received_ok_);
[email protected]64860882014-08-04 23:44:17100 }
101
rockot7c6bf952016-07-14 00:34:11102 static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
[email protected]e5c27752014-08-08 21:45:13103
104 private:
105 bool received_ok_;
Wezfdb98482018-07-12 01:21:39106 base::OnceClosure quit_closure_;
Wez831ae412017-08-30 00:29:36107};
108
109class TestListenerBase : public IPC::Listener {
110 public:
Wezfdb98482018-07-12 01:21:39111 explicit TestListenerBase(base::OnceClosure quit_closure)
112 : quit_closure_(std::move(quit_closure)) {}
Wez831ae412017-08-30 00:29:36113
Chris Watkins2d879af2017-11-30 02:11:59114 ~TestListenerBase() override = default;
Wezfdb98482018-07-12 01:21:39115 void OnChannelError() override { RunQuitClosure(); }
Wez831ae412017-08-30 00:29:36116
117 void set_sender(IPC::Sender* sender) { sender_ = sender; }
118 IPC::Sender* sender() const { return sender_; }
Ken Rockot138153b2018-07-13 23:31:57119 void RunQuitClosure() {
120 if (quit_closure_)
121 std::move(quit_closure_).Run();
122 }
Wez831ae412017-08-30 00:29:36123
124 private:
Keishi Hattori0e45c022021-11-27 09:25:52125 raw_ptr<IPC::Sender> sender_ = nullptr;
Wezfdb98482018-07-12 01:21:39126 base::OnceClosure quit_closure_;
[email protected]64860882014-08-04 23:44:17127};
128
sammc4bcc4ed62016-10-27 10:13:59129using IPCChannelMojoTest = IPCChannelMojoTestBase;
rockotcbca72f2015-03-03 16:31:04130
[email protected]64860882014-08-04 23:44:17131class TestChannelListenerWithExtraExpectations
132 : public IPC::TestChannelListener {
133 public:
sammc57ed9f982016-03-10 06:28:35134 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
[email protected]64860882014-08-04 23:44:17135
tfarina10a5c062015-09-04 18:47:57136 void OnChannelConnected(int32_t peer_pid) override {
[email protected]64860882014-08-04 23:44:17137 IPC::TestChannelListener::OnChannelConnected(peer_pid);
138 EXPECT_TRUE(base::kNullProcessId != peer_pid);
139 is_connected_called_ = true;
140 }
141
142 bool is_connected_called() const { return is_connected_called_; }
143
144 private:
145 bool is_connected_called_;
146};
147
amistry0027a0952016-05-03 00:52:47148TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
sammc4bcc4ed62016-10-27 10:13:59149 Init("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17150
151 // Set up IPC channel and start client.
152 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24153 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17154 listener.Init(sender());
155 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17156
sammc57ed9f982016-03-10 06:28:35157 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
[email protected]64860882014-08-04 23:44:17158
fdoray8e32586852016-06-22 19:56:16159 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17160
sammc57ed9f982016-03-10 06:28:35161 channel()->Close();
[email protected]64860882014-08-04 23:44:17162
163 EXPECT_TRUE(WaitForClientShutdown());
164 EXPECT_TRUE(listener.is_connected_called());
165 EXPECT_TRUE(listener.HasSentAll());
166
167 DestroyChannel();
168}
169
170// A long running process that connects to us
sammc4bcc4ed62016-10-27 10:13:59171DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient) {
[email protected]64860882014-08-04 23:44:17172 TestChannelListenerWithExtraExpectations listener;
sammc57ed9f982016-03-10 06:28:35173 Connect(&listener);
174 listener.Init(channel());
[email protected]64860882014-08-04 23:44:17175
sammc57ed9f982016-03-10 06:28:35176 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
fdoray8e32586852016-06-22 19:56:16177 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17178 EXPECT_TRUE(listener.is_connected_called());
179 EXPECT_TRUE(listener.HasSentAll());
180
sammc57ed9f982016-03-10 06:28:35181 Close();
[email protected]64860882014-08-04 23:44:17182}
183
Wez831ae412017-08-30 00:29:36184class ListenerExpectingErrors : public TestListenerBase {
morrita0a24cfc92014-09-16 03:20:48185 public:
Wezfdb98482018-07-12 01:21:39186 ListenerExpectingErrors(base::OnceClosure quit_closure)
187 : TestListenerBase(std::move(quit_closure)), has_error_(false) {}
morrita0a24cfc92014-09-16 03:20:48188
dchengfe61fca2014-10-22 02:29:52189 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48190
dchengfe61fca2014-10-22 02:29:52191 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48192 has_error_ = true;
Wez831ae412017-08-30 00:29:36193 TestListenerBase::OnChannelError();
morrita0a24cfc92014-09-16 03:20:48194 }
195
196 bool has_error() const { return has_error_; }
197
198 private:
199 bool has_error_;
200};
201
morrita0a24cfc92014-09-16 03:20:48202class ListenerThatQuits : public IPC::Listener {
203 public:
Wezfdb98482018-07-12 01:21:39204 explicit ListenerThatQuits(base::OnceClosure quit_closure)
205 : quit_closure_(std::move(quit_closure)) {}
morrita0a24cfc92014-09-16 03:20:48206
sammc57ed9f982016-03-10 06:28:35207 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48208
Wezfdb98482018-07-12 01:21:39209 void OnChannelConnected(int32_t peer_pid) override {
210 std::move(quit_closure_).Run();
211 }
Wez831ae412017-08-30 00:29:36212
213 private:
Wezfdb98482018-07-12 01:21:39214 base::OnceClosure quit_closure_;
morrita0a24cfc92014-09-16 03:20:48215};
216
217// A long running process that connects to us.
sammc4bcc4ed62016-10-27 10:13:59218DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient) {
Wez831ae412017-08-30 00:29:36219 base::RunLoop run_loop;
220 ListenerThatQuits listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35221 Connect(&listener);
morrita0a24cfc92014-09-16 03:20:48222
Wez831ae412017-08-30 00:29:36223 run_loop.Run();
morrita0a24cfc92014-09-16 03:20:48224
sammc57ed9f982016-03-10 06:28:35225 Close();
morrita0a24cfc92014-09-16 03:20:48226}
227
rockot8c23d462016-07-25 17:33:04228TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
sammc4bcc4ed62016-10-27 10:13:59229 Init("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48230
231 // Set up IPC channel and start client.
Wez831ae412017-08-30 00:29:36232 base::RunLoop run_loop;
233 ListenerExpectingErrors listener(run_loop.QuitClosure());
morrita0a24cfc92014-09-16 03:20:48234 CreateChannel(&listener);
235 ASSERT_TRUE(ConnectChannel());
236
jamesra03ae492014-10-03 04:26:48237 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44238 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
239 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48240 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44241 for (size_t i = 0; i < 10; ++i) {
sammc57ed9f982016-03-10 06:28:35242 IPC::TestChannelListener::SendOneMessage(sender(),
243 overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48244 }
245
Wez831ae412017-08-30 00:29:36246 run_loop.Run();
morrita0a24cfc92014-09-16 03:20:48247
sammc57ed9f982016-03-10 06:28:35248 channel()->Close();
morrita0a24cfc92014-09-16 03:20:48249
250 EXPECT_TRUE(WaitForClientShutdown());
251 EXPECT_TRUE(listener.has_error());
252
253 DestroyChannel();
254}
255
Ken Rockot138153b2018-07-13 23:31:57256class ListenerThatBindsATestStructPasser : public IPC::Listener,
257 public IPC::mojom::TestStructPasser {
258 public:
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54259 ListenerThatBindsATestStructPasser() = default;
260 ~ListenerThatBindsATestStructPasser() override = default;
Ken Rockot138153b2018-07-13 23:31:57261
262 bool OnMessageReceived(const IPC::Message& message) override { return true; }
263
264 void OnChannelConnected(int32_t peer_pid) override {}
265
266 void OnChannelError() override { NOTREACHED(); }
267
268 void OnAssociatedInterfaceRequest(
269 const std::string& interface_name,
270 mojo::ScopedInterfaceEndpointHandle handle) override {
271 CHECK_EQ(interface_name, IPC::mojom::TestStructPasser::Name_);
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54272 receiver_.Bind(
273 mojo::PendingAssociatedReceiver<IPC::mojom::TestStructPasser>(
274 std::move(handle)));
Ken Rockot138153b2018-07-13 23:31:57275 }
276
277 private:
278 // IPC::mojom::TestStructPasser:
279 void Pass(IPC::mojom::TestStructPtr) override { NOTREACHED(); }
280
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54281 mojo::AssociatedReceiver<IPC::mojom::TestStructPasser> receiver_{this};
Ken Rockot138153b2018-07-13 23:31:57282};
283
284class ListenerThatExpectsNoError : public IPC::Listener {
285 public:
286 ListenerThatExpectsNoError(base::OnceClosure connect_closure,
287 base::OnceClosure quit_closure)
288 : connect_closure_(std::move(connect_closure)),
289 quit_closure_(std::move(quit_closure)) {}
290
291 bool OnMessageReceived(const IPC::Message& message) override {
292 base::PickleIterator iter(message);
293 std::string should_be_ok;
294 EXPECT_TRUE(iter.ReadString(&should_be_ok));
295 EXPECT_EQ(should_be_ok, "OK");
296 std::move(quit_closure_).Run();
297 return true;
298 }
299
300 void OnChannelConnected(int32_t peer_pid) override {
301 std::move(connect_closure_).Run();
302 }
303
304 void OnChannelError() override { NOTREACHED(); }
305
306 private:
307 base::OnceClosure connect_closure_;
308 base::OnceClosure quit_closure_;
309};
310
311DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
312 IPCChannelMojoNoImplicitChanelClosureClient) {
313 base::RunLoop wait_to_connect_loop;
314 base::RunLoop wait_to_quit_loop;
315 ListenerThatExpectsNoError listener(wait_to_connect_loop.QuitClosure(),
316 wait_to_quit_loop.QuitClosure());
317 Connect(&listener);
318 wait_to_connect_loop.Run();
319
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54320 mojo::AssociatedRemote<IPC::mojom::TestStructPasser> passer;
Ken Rockot138153b2018-07-13 23:31:57321 channel()->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54322 passer.BindNewEndpointAndPassReceiver());
Ken Rockot138153b2018-07-13 23:31:57323
324 // This avoids hitting DCHECKs in the serialization code meant to stop us from
325 // making such "mistakes" as the one we're about to make below.
326 mojo::internal::SerializationWarningObserverForTesting suppress_those_dchecks;
327
328 // Send an invalid message. The TestStruct argument is not allowed to be null.
329 // This will elicit a validation error in the parent process, but should not
330 // actually disconnect the channel.
331 passer->Pass(nullptr);
332
333 // Wait until the parent says it's OK to quit, so it has time to verify its
334 // expected behavior.
335 wait_to_quit_loop.Run();
336
337 Close();
338}
339
340TEST_F(IPCChannelMojoTest, NoImplicitChannelClosure) {
341 // Verifies that OnChannelError is not invoked due to conditions other than
342 // peer closure (e.g. a malformed inbound message). Instead we should always
343 // be able to handle validation errors via Mojo bad message reporting.
344
345 // NOTE: We can't create a RunLoop before Init() is called, but we have to set
346 // the default ProcessErrorCallback (which we want to reference the RunLoop)
Anton Bikineev1f42a452021-05-15 18:02:50347 // before Init() launches a child process. Hence the absl::optional here.
348 absl::optional<base::RunLoop> wait_for_error_loop;
Ken Rockot138153b2018-07-13 23:31:57349 bool process_error_received = false;
Ken Rockot942af102020-06-04 05:48:46350 mojo::SetDefaultProcessErrorHandler(
Ken Rockot138153b2018-07-13 23:31:57351 base::BindLambdaForTesting([&](const std::string&) {
352 process_error_received = true;
353 wait_for_error_loop->Quit();
354 }));
355
356 Init("IPCChannelMojoNoImplicitChanelClosureClient");
357
358 wait_for_error_loop.emplace();
359 ListenerThatBindsATestStructPasser listener;
360 CreateChannel(&listener);
361 ASSERT_TRUE(ConnectChannel());
362
363 wait_for_error_loop->Run();
364 EXPECT_TRUE(process_error_received);
Ken Rockot942af102020-06-04 05:48:46365 mojo::SetDefaultProcessErrorHandler(base::NullCallback());
Ken Rockot138153b2018-07-13 23:31:57366
367 // Tell the child it can quit and wait for it to shut down.
368 ListenerThatExpectsOK::SendOK(channel());
369 EXPECT_TRUE(WaitForClientShutdown());
370 DestroyChannel();
371}
372
morrita81b17e02015-02-06 00:58:30373struct TestingMessagePipe {
374 TestingMessagePipe() {
375 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
376 }
377
378 mojo::ScopedMessagePipeHandle self;
379 mojo::ScopedMessagePipeHandle peer;
380};
381
382class HandleSendingHelper {
383 public:
384 static std::string GetSendingFileContent() { return "Hello"; }
385
386 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
387 std::string content = HandleSendingHelper::GetSendingFileContent();
388 EXPECT_EQ(MOJO_RESULT_OK,
389 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
390 static_cast<uint32_t>(content.size()),
391 nullptr, 0, 0));
dchenge48600452015-12-28 02:24:50392 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
393 message, std::move(pipe->peer)));
morrita81b17e02015-02-06 00:58:30394 }
395
396 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
397 IPC::Message* message =
398 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
399 WritePipe(message, pipe);
400 ASSERT_TRUE(sender->Send(message));
401 }
402
403 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25404 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30405 mojo::ScopedMessagePipeHandle pipe;
406 EXPECT_TRUE(
407 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
Ken Rockotfada7d282017-06-12 21:25:13408 std::vector<uint8_t> content;
morrita81b17e02015-02-06 00:58:30409
sammc57ed9f982016-03-10 06:28:35410 ASSERT_EQ(MOJO_RESULT_OK,
rockota9d566a2017-03-17 19:36:15411 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE));
morrita81b17e02015-02-06 00:58:30412 EXPECT_EQ(MOJO_RESULT_OK,
Ken Rockotfada7d282017-06-12 21:25:13413 mojo::ReadMessageRaw(pipe.get(), &content, nullptr, 0));
414 EXPECT_EQ(std::string(content.begin(), content.end()),
415 GetSendingFileContent());
morrita81b17e02015-02-06 00:58:30416 }
417
Xiaohan Wangab909b32022-01-12 17:57:39418#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
amistry20e2b1d62016-06-23 06:12:35419 static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
420 return dir_path.Append("ListenerThatExpectsFile.txt");
morrita81b17e02015-02-06 00:58:30421 }
422
423 static void WriteFile(IPC::Message* message, base::File& file) {
424 std::string content = GetSendingFileContent();
425 file.WriteAtCurrentPos(content.data(), content.size());
426 file.Flush();
427 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
428 base::ScopedFD(file.TakePlatformFile())));
429 }
430
431 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
432 IPC::Message* message =
433 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
434 WriteFile(message, file);
435 ASSERT_TRUE(sender->Send(message));
436 }
437
438 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
439 base::File& file,
440 TestingMessagePipe* pipe) {
441 IPC::Message* message =
442 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
443 WriteFile(message, file);
444 WritePipe(message, pipe);
445 ASSERT_TRUE(sender->Send(message));
446 }
447
448 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25449 base::PickleIterator* iter) {
rockot502c94f2016-02-03 20:20:16450 scoped_refptr<base::Pickle::Attachment> attachment;
morrita81b17e02015-02-06 00:58:30451 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
sammc6ed3efb2016-11-23 03:17:35452 EXPECT_EQ(
453 IPC::MessageAttachment::Type::PLATFORM_FILE,
454 static_cast<IPC::MessageAttachment*>(attachment.get())->GetType());
455 base::File file(
456 static_cast<IPC::internal::PlatformFileAttachment*>(attachment.get())
457 ->TakePlatformFile());
morrita81b17e02015-02-06 00:58:30458 std::string content(GetSendingFileContent().size(), ' ');
459 file.Read(0, &content[0], content.size());
460 EXPECT_EQ(content, GetSendingFileContent());
461 }
462#endif
463};
464
Wez831ae412017-08-30 00:29:36465class ListenerThatExpectsMessagePipe : public TestListenerBase {
morrita81b17e02015-02-06 00:58:30466 public:
Wezfdb98482018-07-12 01:21:39467 ListenerThatExpectsMessagePipe(base::OnceClosure quit_closure)
468 : TestListenerBase(std::move(quit_closure)) {}
morrita81b17e02015-02-06 00:58:30469
Chris Watkins2d879af2017-11-30 02:11:59470 ~ListenerThatExpectsMessagePipe() override = default;
morrita81b17e02015-02-06 00:58:30471
472 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25473 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30474 HandleSendingHelper::ReadReceivedPipe(message, &iter);
Wez831ae412017-08-30 00:29:36475 ListenerThatExpectsOK::SendOK(sender());
morrita81b17e02015-02-06 00:58:30476 return true;
477 }
morrita81b17e02015-02-06 00:58:30478};
479
amistry0027a0952016-05-03 00:52:47480TEST_F(IPCChannelMojoTest, SendMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59481 Init("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30482
Wez831ae412017-08-30 00:29:36483 base::RunLoop run_loop;
484 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita81b17e02015-02-06 00:58:30485 CreateChannel(&listener);
486 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30487
488 TestingMessagePipe pipe;
489 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
490
Wez831ae412017-08-30 00:29:36491 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35492 channel()->Close();
morrita81b17e02015-02-06 00:58:30493
494 EXPECT_TRUE(WaitForClientShutdown());
495 DestroyChannel();
496}
497
sammc4bcc4ed62016-10-27 10:13:59498DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient) {
Wez831ae412017-08-30 00:29:36499 base::RunLoop run_loop;
500 ListenerThatExpectsMessagePipe listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35501 Connect(&listener);
502 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30503
Wez831ae412017-08-30 00:29:36504 run_loop.Run();
morrita81b17e02015-02-06 00:58:30505
sammc57ed9f982016-03-10 06:28:35506 Close();
morrita81b17e02015-02-06 00:58:30507}
508
morrita438a2ee2015-04-03 05:28:21509void ReadOK(mojo::MessagePipeHandle pipe) {
Ken Rockotfada7d282017-06-12 21:25:13510 std::vector<uint8_t> should_be_ok;
rockota9d566a2017-03-17 19:36:15511 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE));
morrita438a2ee2015-04-03 05:28:21512 CHECK_EQ(MOJO_RESULT_OK,
Ken Rockotfada7d282017-06-12 21:25:13513 mojo::ReadMessageRaw(pipe, &should_be_ok, nullptr, 0));
514 EXPECT_EQ("OK", std::string(should_be_ok.begin(), should_be_ok.end()));
morrita438a2ee2015-04-03 05:28:21515}
516
517void WriteOK(mojo::MessagePipeHandle pipe) {
518 std::string ok("OK");
519 CHECK_EQ(MOJO_RESULT_OK,
520 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
521 nullptr, 0, 0));
522}
523
Wez831ae412017-08-30 00:29:36524class ListenerThatExpectsMessagePipeUsingParamTrait : public TestListenerBase {
morrita438a2ee2015-04-03 05:28:21525 public:
Wez831ae412017-08-30 00:29:36526 explicit ListenerThatExpectsMessagePipeUsingParamTrait(
Wezfdb98482018-07-12 01:21:39527 base::OnceClosure quit_closure,
Wez831ae412017-08-30 00:29:36528 bool receiving_valid)
Wezfdb98482018-07-12 01:21:39529 : TestListenerBase(std::move(quit_closure)),
530 receiving_valid_(receiving_valid) {}
morrita438a2ee2015-04-03 05:28:21531
Chris Watkins2d879af2017-11-30 02:11:59532 ~ListenerThatExpectsMessagePipeUsingParamTrait() override = default;
morrita438a2ee2015-04-03 05:28:21533
534 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25535 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21536 mojo::MessagePipeHandle handle;
537 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
538 &handle));
539 EXPECT_EQ(handle.is_valid(), receiving_valid_);
540 if (receiving_valid_) {
541 ReadOK(handle);
542 MojoClose(handle.value());
543 }
544
Wez831ae412017-08-30 00:29:36545 ListenerThatExpectsOK::SendOK(sender());
morrita438a2ee2015-04-03 05:28:21546 return true;
547 }
548
morrita438a2ee2015-04-03 05:28:21549 private:
morrita438a2ee2015-04-03 05:28:21550 bool receiving_valid_;
551};
552
sammc4bcc4ed62016-10-27 10:13:59553class ParamTraitMessagePipeClient : public IpcChannelMojoTestClient {
sammc57ed9f982016-03-10 06:28:35554 public:
555 void RunTest(bool receiving_valid_handle) {
Wez831ae412017-08-30 00:29:36556 base::RunLoop run_loop;
sammc57ed9f982016-03-10 06:28:35557 ListenerThatExpectsMessagePipeUsingParamTrait listener(
Wez831ae412017-08-30 00:29:36558 run_loop.QuitClosure(), receiving_valid_handle);
sammc57ed9f982016-03-10 06:28:35559 Connect(&listener);
560 listener.set_sender(channel());
morrita438a2ee2015-04-03 05:28:21561
Wez831ae412017-08-30 00:29:36562 run_loop.Run();
morrita438a2ee2015-04-03 05:28:21563
sammc57ed9f982016-03-10 06:28:35564 Close();
565 }
566};
morrita438a2ee2015-04-03 05:28:21567
amistry0027a0952016-05-03 00:52:47568TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59569 Init("ParamTraitValidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21570
Wez831ae412017-08-30 00:29:36571 base::RunLoop run_loop;
572 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita438a2ee2015-04-03 05:28:21573 CreateChannel(&listener);
574 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21575
576 TestingMessagePipe pipe;
577
danakj03de39b22016-04-23 04:21:09578 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21579 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
580 pipe.peer.release());
581 WriteOK(pipe.self.get());
582
sammc57ed9f982016-03-10 06:28:35583 channel()->Send(message.release());
Wez831ae412017-08-30 00:29:36584 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35585 channel()->Close();
morrita438a2ee2015-04-03 05:28:21586
587 EXPECT_TRUE(WaitForClientShutdown());
588 DestroyChannel();
589}
590
sammc4bcc4ed62016-10-27 10:13:59591DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
592 ParamTraitValidMessagePipeClient,
593 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35594 RunTest(true);
morrita438a2ee2015-04-03 05:28:21595}
596
amistry0027a0952016-05-03 00:52:47597TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59598 Init("ParamTraitInvalidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21599
Wez831ae412017-08-30 00:29:36600 base::RunLoop run_loop;
601 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita438a2ee2015-04-03 05:28:21602 CreateChannel(&listener);
603 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21604
605 mojo::MessagePipeHandle invalid_handle;
danakj03de39b22016-04-23 04:21:09606 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21607 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
608 invalid_handle);
609
sammc57ed9f982016-03-10 06:28:35610 channel()->Send(message.release());
Wez831ae412017-08-30 00:29:36611 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35612 channel()->Close();
morrita438a2ee2015-04-03 05:28:21613
614 EXPECT_TRUE(WaitForClientShutdown());
615 DestroyChannel();
616}
617
sammc4bcc4ed62016-10-27 10:13:59618DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
619 ParamTraitInvalidMessagePipeClient,
620 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35621 RunTest(false);
morrita438a2ee2015-04-03 05:28:21622}
623
amistry0027a0952016-05-03 00:52:47624TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
sammc4bcc4ed62016-10-27 10:13:59625 Init("IPCChannelMojoTestSendOkClient");
morrita17137e62015-06-23 22:29:36626
Wez831ae412017-08-30 00:29:36627 base::RunLoop run_loop;
628 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita17137e62015-06-23 22:29:36629 CreateChannel(&listener);
630 ASSERT_TRUE(ConnectChannel());
morrita17137e62015-06-23 22:29:36631
Wez831ae412017-08-30 00:29:36632 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35633 channel()->Close();
634 ASSERT_FALSE(channel()->Send(new IPC::Message()));
morrita17137e62015-06-23 22:29:36635
636 EXPECT_TRUE(WaitForClientShutdown());
637 DestroyChannel();
638}
639
Wez831ae412017-08-30 00:29:36640class ListenerSendingOneOk : public TestListenerBase {
morrita17137e62015-06-23 22:29:36641 public:
Wezfdb98482018-07-12 01:21:39642 ListenerSendingOneOk(base::OnceClosure quit_closure)
643 : TestListenerBase(std::move(quit_closure)) {}
morrita17137e62015-06-23 22:29:36644
sammc57ed9f982016-03-10 06:28:35645 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita17137e62015-06-23 22:29:36646
tfarina10a5c062015-09-04 18:47:57647 void OnChannelConnected(int32_t peer_pid) override {
Wez831ae412017-08-30 00:29:36648 ListenerThatExpectsOK::SendOK(sender());
Wezfdb98482018-07-12 01:21:39649 RunQuitClosure();
morrita17137e62015-06-23 22:29:36650 }
morrita17137e62015-06-23 22:29:36651};
652
sammc4bcc4ed62016-10-27 10:13:59653DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient) {
Wez831ae412017-08-30 00:29:36654 base::RunLoop run_loop;
655 ListenerSendingOneOk listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35656 Connect(&listener);
657 listener.set_sender(channel());
morrita17137e62015-06-23 22:29:36658
Wez831ae412017-08-30 00:29:36659 run_loop.Run();
morrita17137e62015-06-23 22:29:36660
sammc57ed9f982016-03-10 06:28:35661 Close();
morrita17137e62015-06-23 22:29:36662}
663
rockot7c6bf952016-07-14 00:34:11664class ListenerWithSimpleAssociatedInterface
665 : public IPC::Listener,
666 public IPC::mojom::SimpleTestDriver {
667 public:
668 static const int kNumMessages;
669
Wezfdb98482018-07-12 01:21:39670 explicit ListenerWithSimpleAssociatedInterface(base::OnceClosure quit_closure)
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15671 : quit_closure_(std::move(quit_closure)) {}
rockot7c6bf952016-07-14 00:34:11672
Chris Watkins2d879af2017-11-30 02:11:59673 ~ListenerWithSimpleAssociatedInterface() override = default;
rockot7c6bf952016-07-14 00:34:11674
675 bool OnMessageReceived(const IPC::Message& message) override {
676 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34677 int32_t should_be_expected;
678 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
679 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot7c6bf952016-07-14 00:34:11680 num_messages_received_++;
681 return true;
682 }
683
Wezfdb98482018-07-12 01:21:39684 void OnChannelError() override { CHECK(!quit_closure_); }
rockot7c6bf952016-07-14 00:34:11685
686 void RegisterInterfaceFactory(IPC::Channel* channel) {
687 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15688 base::BindRepeating(
689 &ListenerWithSimpleAssociatedInterface::BindReceiver,
690 base::Unretained(this)));
rockot7c6bf952016-07-14 00:34:11691 }
692
693 private:
694 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34695 void ExpectValue(int32_t value) override {
696 next_expected_value_ = value;
697 }
698
tzikdd76ce712017-06-08 05:27:04699 void GetExpectedValue(GetExpectedValueCallback callback) override {
rockot9abe09b2016-08-02 20:57:34700 NOTREACHED();
701 }
702
tzikdd76ce712017-06-08 05:27:04703 void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
rockot7c6bf952016-07-14 00:34:11704
tzikdd76ce712017-06-08 05:27:04705 void RequestQuit(RequestQuitCallback callback) override {
rockot7c6bf952016-07-14 00:34:11706 EXPECT_EQ(kNumMessages, num_messages_received_);
tzikdd76ce712017-06-08 05:27:04707 std::move(callback).Run();
Wezfdb98482018-07-12 01:21:39708 std::move(quit_closure_).Run();
rockot7c6bf952016-07-14 00:34:11709 }
710
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15711 void BindReceiver(
712 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
713 DCHECK(!receiver_.is_bound());
714 receiver_.Bind(std::move(receiver));
rockot7c6bf952016-07-14 00:34:11715 }
716
rockot9abe09b2016-08-02 20:57:34717 int32_t next_expected_value_ = 0;
rockot7c6bf952016-07-14 00:34:11718 int num_messages_received_ = 0;
Wezfdb98482018-07-12 01:21:39719 base::OnceClosure quit_closure_;
rockot7c6bf952016-07-14 00:34:11720
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15721 mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
rockot7c6bf952016-07-14 00:34:11722};
723
724const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
725
726class ListenerSendingAssociatedMessages : public IPC::Listener {
727 public:
Wezfdb98482018-07-12 01:21:39728 explicit ListenerSendingAssociatedMessages(base::OnceClosure quit_closure)
729 : quit_closure_(std::move(quit_closure)) {}
rockot7c6bf952016-07-14 00:34:11730
731 bool OnMessageReceived(const IPC::Message& message) override { return true; }
732
733 void OnChannelConnected(int32_t peer_pid) override {
734 DCHECK(channel_);
735 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15736 driver_.BindNewEndpointAndPassReceiver());
rockot7c6bf952016-07-14 00:34:11737
738 // Send a bunch of interleaved messages, alternating between the associated
739 // interface and a legacy IPC::Message.
740 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
741 ++i) {
rockot9abe09b2016-08-02 20:57:34742 driver_->ExpectValue(i);
743 SendValue(channel_, i);
rockot7c6bf952016-07-14 00:34:11744 }
Wezfdb98482018-07-12 01:21:39745 driver_->RequestQuit(base::BindOnce(
746 &ListenerSendingAssociatedMessages::OnQuitAck, base::Unretained(this)));
rockot7c6bf952016-07-14 00:34:11747 }
748
749 void set_channel(IPC::Channel* channel) { channel_ = channel; }
750
751 private:
Wezfdb98482018-07-12 01:21:39752 void OnQuitAck() { std::move(quit_closure_).Run(); }
rockot7c6bf952016-07-14 00:34:11753
Keishi Hattori0e45c022021-11-27 09:25:52754 raw_ptr<IPC::Channel> channel_ = nullptr;
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15755 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver_;
Wezfdb98482018-07-12 01:21:39756 base::OnceClosure quit_closure_;
rockot7c6bf952016-07-14 00:34:11757};
758
759TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59760 Init("SimpleAssociatedInterfaceClient");
rockot7c6bf952016-07-14 00:34:11761
Wezfdb98482018-07-12 01:21:39762 base::RunLoop run_loop;
763 ListenerWithSimpleAssociatedInterface listener(run_loop.QuitClosure());
rockot7c6bf952016-07-14 00:34:11764 CreateChannel(&listener);
765 ASSERT_TRUE(ConnectChannel());
766
767 listener.RegisterInterfaceFactory(channel());
768
Wezfdb98482018-07-12 01:21:39769 run_loop.Run();
rockot7c6bf952016-07-14 00:34:11770 channel()->Close();
771
772 EXPECT_TRUE(WaitForClientShutdown());
773 DestroyChannel();
774}
775
sammc4bcc4ed62016-10-27 10:13:59776DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient) {
Wezfdb98482018-07-12 01:21:39777 base::RunLoop run_loop;
778 ListenerSendingAssociatedMessages listener(run_loop.QuitClosure());
rockot7c6bf952016-07-14 00:34:11779 Connect(&listener);
780 listener.set_channel(channel());
781
Wezfdb98482018-07-12 01:21:39782 run_loop.Run();
rockot7c6bf952016-07-14 00:34:11783
784 Close();
785}
786
rockot8d890f62016-07-14 16:37:14787class ChannelProxyRunner {
788 public:
rockota34707ca2016-07-20 04:28:32789 ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,
790 bool for_server)
791 : for_server_(for_server),
792 handle_(std::move(handle)),
rockot9abe09b2016-08-02 20:57:34793 io_thread_("ChannelProxyRunner IO thread"),
794 never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
795 base::WaitableEvent::InitialState::NOT_SIGNALED) {
rockot8d890f62016-07-14 16:37:14796 }
797
Peter Boström896f1372021-11-05 01:12:30798 ChannelProxyRunner(const ChannelProxyRunner&) = delete;
799 ChannelProxyRunner& operator=(const ChannelProxyRunner&) = delete;
800
rockot8d890f62016-07-14 16:37:14801 void CreateProxy(IPC::Listener* listener) {
802 io_thread_.StartWithOptions(
Carlos Caballerodd8bf7b042019-07-30 14:14:15803 base::Thread::Options(base::MessagePumpType::IO, 0));
Hajime Hoshiff15e972017-11-09 06:37:09804 proxy_ = IPC::SyncChannel::Create(listener, io_thread_.task_runner(),
805 base::ThreadTaskRunnerHandle::Get(),
806 &never_signaled_);
rockot8d890f62016-07-14 16:37:14807 }
rockota34707ca2016-07-20 04:28:32808
rockot10188752016-09-08 18:24:56809 void RunProxy() {
rockota34707ca2016-07-20 04:28:32810 std::unique_ptr<IPC::ChannelFactory> factory;
811 if (for_server_) {
812 factory = IPC::ChannelMojo::CreateServerFactory(
Hajime Hoshia98f1102017-11-20 06:34:35813 std::move(handle_), io_thread_.task_runner(),
814 base::ThreadTaskRunnerHandle::Get());
rockota34707ca2016-07-20 04:28:32815 } else {
816 factory = IPC::ChannelMojo::CreateClientFactory(
Hajime Hoshia98f1102017-11-20 06:34:35817 std::move(handle_), io_thread_.task_runner(),
818 base::ThreadTaskRunnerHandle::Get());
rockota34707ca2016-07-20 04:28:32819 }
rockot10188752016-09-08 18:24:56820 proxy_->Init(std::move(factory), true);
rockota34707ca2016-07-20 04:28:32821 }
rockot8d890f62016-07-14 16:37:14822
823 IPC::ChannelProxy* proxy() { return proxy_.get(); }
824
825 private:
rockota34707ca2016-07-20 04:28:32826 const bool for_server_;
rockot8d890f62016-07-14 16:37:14827
rockota34707ca2016-07-20 04:28:32828 mojo::ScopedMessagePipeHandle handle_;
rockot8d890f62016-07-14 16:37:14829 base::Thread io_thread_;
rockot9abe09b2016-08-02 20:57:34830 base::WaitableEvent never_signaled_;
rockotb62e2e32017-03-24 18:36:44831 std::unique_ptr<IPC::ChannelProxy> proxy_;
rockot8d890f62016-07-14 16:37:14832};
833
834class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase {
835 public:
sammc4bcc4ed62016-10-27 10:13:59836 void Init(const std::string& client_name) {
837 IPCChannelMojoTestBase::Init(client_name);
Peter Boströmfb60ea02021-04-05 21:06:12838 runner_ = std::make_unique<ChannelProxyRunner>(TakeHandle(), true);
rockot8d890f62016-07-14 16:37:14839 }
840 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot10188752016-09-08 18:24:56841 void RunProxy() {
842 runner_->RunProxy();
rockot401fb2c2016-09-06 18:35:57843 }
rockot0e4de5f2016-07-22 21:18:07844 void DestroyProxy() {
845 runner_.reset();
846 base::RunLoop().RunUntilIdle();
847 }
rockot8d890f62016-07-14 16:37:14848
849 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
850
851 private:
rockot8d890f62016-07-14 16:37:14852 std::unique_ptr<ChannelProxyRunner> runner_;
853};
854
855class ListenerWithSimpleProxyAssociatedInterface
856 : public IPC::Listener,
857 public IPC::mojom::SimpleTestDriver {
858 public:
859 static const int kNumMessages;
860
Wezfdb98482018-07-12 01:21:39861 explicit ListenerWithSimpleProxyAssociatedInterface(
862 base::OnceClosure quit_closure)
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15863 : quit_closure_(std::move(quit_closure)) {}
rockot8d890f62016-07-14 16:37:14864
Chris Watkins2d879af2017-11-30 02:11:59865 ~ListenerWithSimpleProxyAssociatedInterface() override = default;
rockot8d890f62016-07-14 16:37:14866
867 bool OnMessageReceived(const IPC::Message& message) override {
868 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34869 int32_t should_be_expected;
870 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
871 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot8d890f62016-07-14 16:37:14872 num_messages_received_++;
873 return true;
874 }
875
Wezfdb98482018-07-12 01:21:39876 void OnChannelError() override { CHECK(!quit_closure_); }
rockot8d890f62016-07-14 16:37:14877
rockotf62002a2016-09-15 00:08:59878 void OnAssociatedInterfaceRequest(
879 const std::string& interface_name,
880 mojo::ScopedInterfaceEndpointHandle handle) override {
881 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15882 receiver_.Bind(
883 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver>(
884 std::move(handle)));
rockot8d890f62016-07-14 16:37:14885 }
886
887 bool received_all_messages() const {
Wezfdb98482018-07-12 01:21:39888 return num_messages_received_ == kNumMessages && !quit_closure_;
rockot8d890f62016-07-14 16:37:14889 }
890
891 private:
892 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34893 void ExpectValue(int32_t value) override {
894 next_expected_value_ = value;
895 }
896
tzikdd76ce712017-06-08 05:27:04897 void GetExpectedValue(GetExpectedValueCallback callback) override {
898 std::move(callback).Run(next_expected_value_);
rockot9abe09b2016-08-02 20:57:34899 }
900
tzikdd76ce712017-06-08 05:27:04901 void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
rockot8d890f62016-07-14 16:37:14902
tzikdd76ce712017-06-08 05:27:04903 void RequestQuit(RequestQuitCallback callback) override {
tzikdd76ce712017-06-08 05:27:04904 std::move(callback).Run();
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15905 receiver_.reset();
Wezfdb98482018-07-12 01:21:39906 std::move(quit_closure_).Run();
rockot8d890f62016-07-14 16:37:14907 }
908
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15909 void BindReceiver(
910 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
911 DCHECK(!receiver_.is_bound());
912 receiver_.Bind(std::move(receiver));
rockot8d890f62016-07-14 16:37:14913 }
914
rockot9abe09b2016-08-02 20:57:34915 int32_t next_expected_value_ = 0;
rockot8d890f62016-07-14 16:37:14916 int num_messages_received_ = 0;
Wezfdb98482018-07-12 01:21:39917 base::OnceClosure quit_closure_;
rockot8d890f62016-07-14 16:37:14918
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15919 mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
rockot8d890f62016-07-14 16:37:14920};
921
922const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000;
923
924TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59925 Init("ProxyThreadAssociatedInterfaceClient");
rockot8d890f62016-07-14 16:37:14926
Wezfdb98482018-07-12 01:21:39927 base::RunLoop run_loop;
928 ListenerWithSimpleProxyAssociatedInterface listener(run_loop.QuitClosure());
rockot8d890f62016-07-14 16:37:14929 CreateProxy(&listener);
rockot8d890f62016-07-14 16:37:14930 RunProxy();
931
Wezfdb98482018-07-12 01:21:39932 run_loop.Run();
rockot8d890f62016-07-14 16:37:14933
934 EXPECT_TRUE(WaitForClientShutdown());
935 EXPECT_TRUE(listener.received_all_messages());
936
rockot0e4de5f2016-07-22 21:18:07937 DestroyProxy();
rockot8d890f62016-07-14 16:37:14938}
939
940class ChannelProxyClient {
941 public:
942 void Init(mojo::ScopedMessagePipeHandle handle) {
Peter Boströmfb60ea02021-04-05 21:06:12943 runner_ = std::make_unique<ChannelProxyRunner>(std::move(handle), false);
rockot8d890f62016-07-14 16:37:14944 }
rockot9abe09b2016-08-02 20:57:34945
rockot8d890f62016-07-14 16:37:14946 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot9abe09b2016-08-02 20:57:34947
rockot10188752016-09-08 18:24:56948 void RunProxy() { runner_->RunProxy(); }
rockot9abe09b2016-08-02 20:57:34949
rockot0e4de5f2016-07-22 21:18:07950 void DestroyProxy() {
951 runner_.reset();
952 base::RunLoop().RunUntilIdle();
953 }
rockot8d890f62016-07-14 16:37:14954
rockot9abe09b2016-08-02 20:57:34955 void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) {
956 base::RunLoop loop;
957 driver->RequestQuit(loop.QuitClosure());
958 loop.Run();
959 }
960
rockot8d890f62016-07-14 16:37:14961 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
962
963 private:
Gabriel Charettec523fa62019-09-09 23:03:32964 base::test::SingleThreadTaskEnvironment task_environment_;
rockot8d890f62016-07-14 16:37:14965 std::unique_ptr<ChannelProxyRunner> runner_;
966};
967
rockot0e4de5f2016-07-22 21:18:07968class DummyListener : public IPC::Listener {
rockot8d890f62016-07-14 16:37:14969 public:
rockot8d890f62016-07-14 16:37:14970 // IPC::Listener
971 bool OnMessageReceived(const IPC::Message& message) override { return true; }
rockot8d890f62016-07-14 16:37:14972};
973
sammc4bcc4ed62016-10-27 10:13:59974DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
975 ProxyThreadAssociatedInterfaceClient,
976 ChannelProxyClient) {
rockot0e4de5f2016-07-22 21:18:07977 DummyListener listener;
rockot8d890f62016-07-14 16:37:14978 CreateProxy(&listener);
979 RunProxy();
rockot8d890f62016-07-14 16:37:14980
981 // Send a bunch of interleaved messages, alternating between the associated
982 // interface and a legacy IPC::Message.
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15983 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver;
Ken Rockot493a59f32021-06-04 22:16:50984 proxy()->GetRemoteAssociatedInterface(
985 driver.BindNewEndpointAndPassReceiver());
rockot8d890f62016-07-14 16:37:14986 for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages;
987 ++i) {
rockot9abe09b2016-08-02 20:57:34988 driver->ExpectValue(i);
989 SendValue(proxy(), i);
rockot8d890f62016-07-14 16:37:14990 }
Wezfdb98482018-07-12 01:21:39991 base::RunLoop run_loop;
992 driver->RequestQuit(run_loop.QuitClosure());
993 run_loop.Run();
rockot0e4de5f2016-07-22 21:18:07994
995 DestroyProxy();
rockot8d890f62016-07-14 16:37:14996}
997
rockot401fb2c2016-09-06 18:35:57998class ListenerWithIndirectProxyAssociatedInterface
999 : public IPC::Listener,
1000 public IPC::mojom::IndirectTestDriver,
1001 public IPC::mojom::PingReceiver {
1002 public:
Julie Jeongeun Kimac82819f2019-11-20 00:01:271003 ListenerWithIndirectProxyAssociatedInterface() = default;
Chris Watkins2d879af2017-11-30 02:11:591004 ~ListenerWithIndirectProxyAssociatedInterface() override = default;
rockot401fb2c2016-09-06 18:35:571005
rockot70bbb59492017-01-25 00:56:511006 // IPC::Listener:
rockot401fb2c2016-09-06 18:35:571007 bool OnMessageReceived(const IPC::Message& message) override { return true; }
1008
rockot70bbb59492017-01-25 00:56:511009 void OnAssociatedInterfaceRequest(
1010 const std::string& interface_name,
1011 mojo::ScopedInterfaceEndpointHandle handle) override {
Julie Jeongeun Kimac82819f2019-11-20 00:01:271012 DCHECK(!driver_receiver_.is_bound());
rockot70bbb59492017-01-25 00:56:511013 DCHECK_EQ(interface_name, IPC::mojom::IndirectTestDriver::Name_);
Julie Jeongeun Kimac82819f2019-11-20 00:01:271014 driver_receiver_.Bind(
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:541015 mojo::PendingAssociatedReceiver<IPC::mojom::IndirectTestDriver>(
1016 std::move(handle)));
rockot401fb2c2016-09-06 18:35:571017 }
1018
Wezfdb98482018-07-12 01:21:391019 void set_ping_handler(const base::RepeatingClosure& handler) {
rockot401fb2c2016-09-06 18:35:571020 ping_handler_ = handler;
1021 }
1022
1023 private:
1024 // IPC::mojom::IndirectTestDriver:
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491025 void GetPingReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::PingReceiver>
1026 receiver) override {
1027 ping_receiver_receiver_.Bind(std::move(receiver));
rockot401fb2c2016-09-06 18:35:571028 }
1029
1030 // IPC::mojom::PingReceiver:
tzikdd76ce712017-06-08 05:27:041031 void Ping(PingCallback callback) override {
1032 std::move(callback).Run();
rockot401fb2c2016-09-06 18:35:571033 ping_handler_.Run();
1034 }
1035
Julie Jeongeun Kimac82819f2019-11-20 00:01:271036 mojo::AssociatedReceiver<IPC::mojom::IndirectTestDriver> driver_receiver_{
1037 this};
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491038 mojo::AssociatedReceiver<IPC::mojom::PingReceiver> ping_receiver_receiver_{
1039 this};
rockot401fb2c2016-09-06 18:35:571040
Wezfdb98482018-07-12 01:21:391041 base::RepeatingClosure ping_handler_;
rockot401fb2c2016-09-06 18:35:571042};
1043
1044TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterfaceIndirect) {
1045 // Tests that we can pipeline interface requests and subsequent messages
1046 // targeting proxy thread bindings, and the channel will still dispatch
1047 // messages appropriately.
1048
sammc4bcc4ed62016-10-27 10:13:591049 Init("ProxyThreadAssociatedInterfaceIndirectClient");
rockot401fb2c2016-09-06 18:35:571050
1051 ListenerWithIndirectProxyAssociatedInterface listener;
1052 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:571053 RunProxy();
1054
1055 base::RunLoop loop;
1056 listener.set_ping_handler(loop.QuitClosure());
1057 loop.Run();
1058
1059 EXPECT_TRUE(WaitForClientShutdown());
1060
1061 DestroyProxy();
1062}
1063
sammc4bcc4ed62016-10-27 10:13:591064DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
rockot401fb2c2016-09-06 18:35:571065 ProxyThreadAssociatedInterfaceIndirectClient,
1066 ChannelProxyClient) {
1067 DummyListener listener;
1068 CreateProxy(&listener);
1069 RunProxy();
1070
1071 // Use an interface requested via another interface. On the remote end both
1072 // interfaces are bound on the proxy thread. This ensures that the Ping
1073 // message we send will still be dispatched properly even though the remote
1074 // endpoint may not have been bound yet by the time the message is initially
1075 // processed on the IO thread.
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:541076 mojo::AssociatedRemote<IPC::mojom::IndirectTestDriver> driver;
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491077 mojo::AssociatedRemote<IPC::mojom::PingReceiver> ping_receiver;
Ken Rockot493a59f32021-06-04 22:16:501078 proxy()->GetRemoteAssociatedInterface(
1079 driver.BindNewEndpointAndPassReceiver());
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491080 driver->GetPingReceiver(ping_receiver.BindNewEndpointAndPassReceiver());
rockot401fb2c2016-09-06 18:35:571081
1082 base::RunLoop loop;
1083 ping_receiver->Ping(loop.QuitClosure());
1084 loop.Run();
1085
1086 DestroyProxy();
1087}
1088
rockot9abe09b2016-08-02 20:57:341089class ListenerWithSyncAssociatedInterface
1090 : public IPC::Listener,
1091 public IPC::mojom::SimpleTestDriver {
1092 public:
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151093 ListenerWithSyncAssociatedInterface() = default;
Chris Watkins2d879af2017-11-30 02:11:591094 ~ListenerWithSyncAssociatedInterface() override = default;
rockot9abe09b2016-08-02 20:57:341095
1096 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1097
rockot9abe09b2016-08-02 20:57:341098 void RunUntilQuitRequested() {
1099 base::RunLoop loop;
1100 quit_closure_ = loop.QuitClosure();
1101 loop.Run();
1102 }
1103
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151104 void CloseBinding() { receiver_.reset(); }
rockot9abe09b2016-08-02 20:57:341105
1106 void set_response_value(int32_t response) {
1107 response_value_ = response;
1108 }
1109
1110 private:
1111 // IPC::mojom::SimpleTestDriver:
1112 void ExpectValue(int32_t value) override {
1113 next_expected_value_ = value;
1114 }
1115
tzikdd76ce712017-06-08 05:27:041116 void GetExpectedValue(GetExpectedValueCallback callback) override {
1117 std::move(callback).Run(next_expected_value_);
rockot9abe09b2016-08-02 20:57:341118 }
1119
tzikdd76ce712017-06-08 05:27:041120 void RequestValue(RequestValueCallback callback) override {
1121 std::move(callback).Run(response_value_);
rockot9abe09b2016-08-02 20:57:341122 }
1123
tzikdd76ce712017-06-08 05:27:041124 void RequestQuit(RequestQuitCallback callback) override {
Wezfdb98482018-07-12 01:21:391125 std::move(quit_closure_).Run();
tzikdd76ce712017-06-08 05:27:041126 std::move(callback).Run();
rockot9abe09b2016-08-02 20:57:341127 }
1128
1129 // IPC::Listener:
1130 bool OnMessageReceived(const IPC::Message& message) override {
1131 EXPECT_EQ(0u, message.type());
1132 EXPECT_TRUE(message.is_sync());
1133 EXPECT_TRUE(message.should_unblock());
1134 std::unique_ptr<IPC::Message> reply(
1135 IPC::SyncMessage::GenerateReply(&message));
1136 reply->WriteInt(response_value_);
1137 DCHECK(sync_sender_);
1138 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1139 return true;
1140 }
1141
rockot70bbb59492017-01-25 00:56:511142 void OnAssociatedInterfaceRequest(
1143 const std::string& interface_name,
1144 mojo::ScopedInterfaceEndpointHandle handle) override {
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151145 DCHECK(!receiver_.is_bound());
rockot70bbb59492017-01-25 00:56:511146 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151147 receiver_.Bind(
1148 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver>(
1149 std::move(handle)));
rockot70bbb59492017-01-25 00:56:511150 }
1151
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151152 void BindReceiver(
1153 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
1154 DCHECK(!receiver_.is_bound());
1155 receiver_.Bind(std::move(receiver));
rockot9abe09b2016-08-02 20:57:341156 }
1157
1158 IPC::Sender* sync_sender_ = nullptr;
1159 int32_t next_expected_value_ = 0;
1160 int32_t response_value_ = 0;
Wezfdb98482018-07-12 01:21:391161 base::OnceClosure quit_closure_;
rockot9abe09b2016-08-02 20:57:341162
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151163 mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
rockot9abe09b2016-08-02 20:57:341164};
1165
1166class SyncReplyReader : public IPC::MessageReplyDeserializer {
1167 public:
1168 explicit SyncReplyReader(int32_t* storage) : storage_(storage) {}
Peter Boströmc68c5aa2021-09-28 00:28:001169
1170 SyncReplyReader(const SyncReplyReader&) = delete;
1171 SyncReplyReader& operator=(const SyncReplyReader&) = delete;
1172
Chris Watkins2d879af2017-11-30 02:11:591173 ~SyncReplyReader() override = default;
rockot9abe09b2016-08-02 20:57:341174
1175 private:
1176 // IPC::MessageReplyDeserializer:
1177 bool SerializeOutputParameters(const IPC::Message& message,
1178 base::PickleIterator iter) override {
1179 if (!iter.ReadInt(storage_))
1180 return false;
1181 return true;
1182 }
1183
Keishi Hattori0e45c022021-11-27 09:25:521184 raw_ptr<int32_t> storage_;
rockot9abe09b2016-08-02 20:57:341185};
1186
1187TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:591188 Init("SyncAssociatedInterface");
rockot9abe09b2016-08-02 20:57:341189
1190 ListenerWithSyncAssociatedInterface listener;
1191 CreateProxy(&listener);
1192 listener.set_sync_sender(proxy());
rockot9abe09b2016-08-02 20:57:341193 RunProxy();
1194
1195 // Run the client's simple sanity check to completion.
1196 listener.RunUntilQuitRequested();
1197
1198 // Verify that we can send a sync IPC and service an incoming sync request
1199 // while waiting on it
1200 listener.set_response_value(42);
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151201 mojo::AssociatedRemote<IPC::mojom::SimpleTestClient> client;
Ken Rockot493a59f32021-06-04 22:16:501202 proxy()->GetRemoteAssociatedInterface(
1203 client.BindNewEndpointAndPassReceiver());
rockot9abe09b2016-08-02 20:57:341204 int32_t received_value;
1205 EXPECT_TRUE(client->RequestValue(&received_value));
1206 EXPECT_EQ(42, received_value);
1207
1208 // Do it again. This time the client will send a classical sync IPC to us
1209 // while we wait.
1210 received_value = 0;
1211 EXPECT_TRUE(client->RequestValue(&received_value));
1212 EXPECT_EQ(42, received_value);
1213
1214 // Now make a classical sync IPC request to the client. It will send a
1215 // sync associated interface message to us while we wait.
1216 received_value = 0;
1217 std::unique_ptr<IPC::SyncMessage> request(
1218 new IPC::SyncMessage(0, 0, IPC::Message::PRIORITY_NORMAL,
1219 new SyncReplyReader(&received_value)));
1220 EXPECT_TRUE(proxy()->Send(request.release()));
1221 EXPECT_EQ(42, received_value);
1222
1223 listener.CloseBinding();
1224 EXPECT_TRUE(WaitForClientShutdown());
1225
1226 DestroyProxy();
1227}
1228
1229class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
1230 public IPC::Listener {
1231 public:
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151232 SimpleTestClientImpl() = default;
Peter Boströmc68c5aa2021-09-28 00:28:001233
1234 SimpleTestClientImpl(const SimpleTestClientImpl&) = delete;
1235 SimpleTestClientImpl& operator=(const SimpleTestClientImpl&) = delete;
1236
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151237 ~SimpleTestClientImpl() override = default;
rockot9abe09b2016-08-02 20:57:341238
1239 void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; }
1240 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1241
rockot9abe09b2016-08-02 20:57:341242 void WaitForValueRequest() {
Peter Boströmfb60ea02021-04-05 21:06:121243 run_loop_ = std::make_unique<base::RunLoop>();
rockot9abe09b2016-08-02 20:57:341244 run_loop_->Run();
1245 }
1246
1247 void UseSyncSenderForRequest(bool use_sync_sender) {
1248 use_sync_sender_ = use_sync_sender;
1249 }
1250
1251 private:
1252 // IPC::mojom::SimpleTestClient:
tzikdd76ce712017-06-08 05:27:041253 void RequestValue(RequestValueCallback callback) override {
rockot9abe09b2016-08-02 20:57:341254 int32_t response = 0;
1255 if (use_sync_sender_) {
1256 std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage(
1257 0, 0, IPC::Message::PRIORITY_NORMAL, new SyncReplyReader(&response)));
1258 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1259 } else {
1260 DCHECK(driver_);
1261 EXPECT_TRUE(driver_->RequestValue(&response));
1262 }
1263
tzikdd76ce712017-06-08 05:27:041264 std::move(callback).Run(response);
rockot9abe09b2016-08-02 20:57:341265
1266 DCHECK(run_loop_);
1267 run_loop_->Quit();
1268 }
1269
1270 // IPC::Listener:
1271 bool OnMessageReceived(const IPC::Message& message) override {
1272 int32_t response;
1273 DCHECK(driver_);
1274 EXPECT_TRUE(driver_->RequestValue(&response));
1275 std::unique_ptr<IPC::Message> reply(
1276 IPC::SyncMessage::GenerateReply(&message));
1277 reply->WriteInt(response);
1278 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1279
1280 DCHECK(run_loop_);
1281 run_loop_->Quit();
1282 return true;
1283 }
1284
rockot70bbb59492017-01-25 00:56:511285 void OnAssociatedInterfaceRequest(
1286 const std::string& interface_name,
1287 mojo::ScopedInterfaceEndpointHandle handle) override {
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151288 DCHECK(!receiver_.is_bound());
rockot70bbb59492017-01-25 00:56:511289 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestClient::Name_);
1290
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151291 receiver_.Bind(
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491292 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestClient>(
1293 std::move(handle)));
rockot70bbb59492017-01-25 00:56:511294 }
1295
rockot9abe09b2016-08-02 20:57:341296 bool use_sync_sender_ = false;
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491297 mojo::AssociatedReceiver<IPC::mojom::SimpleTestClient> receiver_{this};
rockot9abe09b2016-08-02 20:57:341298 IPC::Sender* sync_sender_ = nullptr;
1299 IPC::mojom::SimpleTestDriver* driver_ = nullptr;
1300 std::unique_ptr<base::RunLoop> run_loop_;
rockot9abe09b2016-08-02 20:57:341301};
1302
sammc4bcc4ed62016-10-27 10:13:591303DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,
1304 ChannelProxyClient) {
rockot9abe09b2016-08-02 20:57:341305 SimpleTestClientImpl client_impl;
1306 CreateProxy(&client_impl);
1307 client_impl.set_sync_sender(proxy());
rockot9abe09b2016-08-02 20:57:341308 RunProxy();
1309
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151310 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver;
Ken Rockot493a59f32021-06-04 22:16:501311 proxy()->GetRemoteAssociatedInterface(
1312 driver.BindNewEndpointAndPassReceiver());
rockot9abe09b2016-08-02 20:57:341313 client_impl.set_driver(driver.get());
1314
1315 // Simple sync message sanity check.
1316 driver->ExpectValue(42);
1317 int32_t expected_value = 0;
1318 EXPECT_TRUE(driver->GetExpectedValue(&expected_value));
1319 EXPECT_EQ(42, expected_value);
1320 RequestQuitAndWaitForAck(driver.get());
1321
1322 // Wait for the test driver to perform a sync call test with our own sync
1323 // associated interface message nested inside.
1324 client_impl.UseSyncSenderForRequest(false);
1325 client_impl.WaitForValueRequest();
1326
1327 // Wait for the test driver to perform a sync call test with our own classical
1328 // sync IPC nested inside.
1329 client_impl.UseSyncSenderForRequest(true);
1330 client_impl.WaitForValueRequest();
1331
1332 // Wait for the test driver to perform a classical sync IPC request, with our
1333 // own sync associated interface message nested inside.
1334 client_impl.UseSyncSenderForRequest(false);
1335 client_impl.WaitForValueRequest();
1336
1337 DestroyProxy();
1338}
1339
rockot10188752016-09-08 18:24:561340TEST_F(IPCChannelProxyMojoTest, Pause) {
1341 // Ensures that pausing a channel elicits the expected behavior when sending
1342 // messages, unpausing, sending more messages, and then manually flushing.
1343 // Specifically a sequence like:
rockot401fb2c2016-09-06 18:35:571344 //
1345 // Connect()
1346 // Send(A)
rockot10188752016-09-08 18:24:561347 // Pause()
rockot401fb2c2016-09-06 18:35:571348 // Send(B)
rockot401fb2c2016-09-06 18:35:571349 // Send(C)
rockot10188752016-09-08 18:24:561350 // Unpause(false)
1351 // Send(D)
1352 // Send(E)
rockot401fb2c2016-09-06 18:35:571353 // Flush()
1354 //
rockot10188752016-09-08 18:24:561355 // must result in the other end receiving messages A, D, E, B, D; in that
rockot401fb2c2016-09-06 18:35:571356 // order.
1357 //
1358 // This behavior is required by some consumers of IPC::Channel, and it is not
1359 // sufficient to leave this up to the consumer to implement since associated
1360 // interface requests and messages also need to be queued according to the
1361 // same policy.
sammc4bcc4ed62016-10-27 10:13:591362 Init("CreatePausedClient");
rockot401fb2c2016-09-06 18:35:571363
1364 DummyListener listener;
1365 CreateProxy(&listener);
rockot10188752016-09-08 18:24:561366 RunProxy();
1367
1368 // This message must be sent immediately since the channel is unpaused.
1369 SendValue(proxy(), 1);
1370
1371 proxy()->Pause();
rockot401fb2c2016-09-06 18:35:571372
1373 // These messages must be queued internally since the channel is paused.
rockot401fb2c2016-09-06 18:35:571374 SendValue(proxy(), 2);
rockot10188752016-09-08 18:24:561375 SendValue(proxy(), 3);
rockot401fb2c2016-09-06 18:35:571376
1377 proxy()->Unpause(false /* flush */);
1378
1379 // These messages must be sent immediately since the channel is unpaused.
rockot401fb2c2016-09-06 18:35:571380 SendValue(proxy(), 4);
rockot10188752016-09-08 18:24:561381 SendValue(proxy(), 5);
rockot401fb2c2016-09-06 18:35:571382
1383 // Now we flush the previously queued messages.
1384 proxy()->Flush();
1385
1386 EXPECT_TRUE(WaitForClientShutdown());
1387 DestroyProxy();
1388}
1389
1390class ExpectValueSequenceListener : public IPC::Listener {
1391 public:
Wezfdb98482018-07-12 01:21:391392 ExpectValueSequenceListener(base::queue<int32_t>* expected_values,
1393 base::OnceClosure quit_closure)
1394 : expected_values_(expected_values),
1395 quit_closure_(std::move(quit_closure)) {}
Peter Boströmc68c5aa2021-09-28 00:28:001396
1397 ExpectValueSequenceListener(const ExpectValueSequenceListener&) = delete;
1398 ExpectValueSequenceListener& operator=(const ExpectValueSequenceListener&) =
1399 delete;
1400
Chris Watkins2d879af2017-11-30 02:11:591401 ~ExpectValueSequenceListener() override = default;
rockot401fb2c2016-09-06 18:35:571402
1403 // IPC::Listener:
1404 bool OnMessageReceived(const IPC::Message& message) override {
1405 DCHECK(!expected_values_->empty());
1406 base::PickleIterator iter(message);
1407 int32_t should_be_expected;
1408 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
1409 EXPECT_EQ(expected_values_->front(), should_be_expected);
1410 expected_values_->pop();
1411 if (expected_values_->empty())
Wezfdb98482018-07-12 01:21:391412 std::move(quit_closure_).Run();
rockot401fb2c2016-09-06 18:35:571413 return true;
1414 }
1415
1416 private:
Keishi Hattori0e45c022021-11-27 09:25:521417 raw_ptr<base::queue<int32_t>> expected_values_;
Wezfdb98482018-07-12 01:21:391418 base::OnceClosure quit_closure_;
rockot401fb2c2016-09-06 18:35:571419};
1420
sammc4bcc4ed62016-10-27 10:13:591421DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,
1422 ChannelProxyClient) {
Brett Wilsona62d9c02017-09-20 20:53:201423 base::queue<int32_t> expected_values;
Wezfdb98482018-07-12 01:21:391424 base::RunLoop run_loop;
1425 ExpectValueSequenceListener listener(&expected_values,
1426 run_loop.QuitClosure());
rockot401fb2c2016-09-06 18:35:571427 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:571428 expected_values.push(1);
rockot10188752016-09-08 18:24:561429 expected_values.push(4);
1430 expected_values.push(5);
rockot401fb2c2016-09-06 18:35:571431 expected_values.push(2);
rockot10188752016-09-08 18:24:561432 expected_values.push(3);
rockot401fb2c2016-09-06 18:35:571433 RunProxy();
Wezfdb98482018-07-12 01:21:391434 run_loop.Run();
rockot401fb2c2016-09-06 18:35:571435 EXPECT_TRUE(expected_values.empty());
1436 DestroyProxy();
1437}
1438
sammc5c8a6c62017-02-04 01:33:381439TEST_F(IPCChannelProxyMojoTest, AssociatedRequestClose) {
1440 Init("DropAssociatedRequest");
1441
1442 DummyListener listener;
1443 CreateProxy(&listener);
1444 RunProxy();
1445
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:541446 mojo::AssociatedRemote<IPC::mojom::AssociatedInterfaceVendor> vendor;
Ken Rockot493a59f32021-06-04 22:16:501447 proxy()->GetRemoteAssociatedInterface(
1448 vendor.BindNewEndpointAndPassReceiver());
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151449 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> tester;
1450 vendor->GetTestInterface(tester.BindNewEndpointAndPassReceiver());
sammc5c8a6c62017-02-04 01:33:381451 base::RunLoop run_loop;
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151452 tester.set_disconnect_handler(run_loop.QuitClosure());
sammc5c8a6c62017-02-04 01:33:381453 run_loop.Run();
1454
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151455 tester.reset();
Ken Rockot493a59f32021-06-04 22:16:501456 proxy()->GetRemoteAssociatedInterface(
1457 tester.BindNewEndpointAndPassReceiver());
sammc5c8a6c62017-02-04 01:33:381458 EXPECT_TRUE(WaitForClientShutdown());
1459 DestroyProxy();
1460}
1461
1462class AssociatedInterfaceDroppingListener : public IPC::Listener {
1463 public:
Wezfdb98482018-07-12 01:21:391464 AssociatedInterfaceDroppingListener(base::OnceClosure callback)
1465 : callback_(std::move(callback)) {}
sammc5c8a6c62017-02-04 01:33:381466 bool OnMessageReceived(const IPC::Message& message) override { return false; }
1467
1468 void OnAssociatedInterfaceRequest(
1469 const std::string& interface_name,
1470 mojo::ScopedInterfaceEndpointHandle handle) override {
1471 if (interface_name == IPC::mojom::SimpleTestDriver::Name_)
Wezfdb98482018-07-12 01:21:391472 std::move(callback_).Run();
sammc5c8a6c62017-02-04 01:33:381473 }
1474
1475 private:
Wezfdb98482018-07-12 01:21:391476 base::OnceClosure callback_;
sammc5c8a6c62017-02-04 01:33:381477};
1478
1479DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,
1480 ChannelProxyClient) {
1481 base::RunLoop run_loop;
1482 AssociatedInterfaceDroppingListener listener(run_loop.QuitClosure());
1483 CreateProxy(&listener);
1484 RunProxy();
1485 run_loop.Run();
1486 DestroyProxy();
1487}
1488
Xiaohan Wangab909b32022-01-12 17:57:391489#if !BUILDFLAG(IS_APPLE)
Wez831ae412017-08-30 00:29:361490// TODO(wez): On Mac we need to set up a MachPortBroker before we can transfer
1491// Mach ports (which underpin Sharedmemory on Mac) across IPC.
1492
Alexandr Ilind497eee2018-04-19 22:50:541493template <class SharedMemoryRegionType>
1494class IPCChannelMojoSharedMemoryRegionTypedTest : public IPCChannelMojoTest {};
1495
1496struct WritableRegionTraits {
1497 using RegionType = base::WritableSharedMemoryRegion;
1498 static const char kClientName[];
1499};
1500const char WritableRegionTraits::kClientName[] =
1501 "IPCChannelMojoTestSendWritableSharedMemoryRegionClient";
1502struct UnsafeRegionTraits {
1503 using RegionType = base::UnsafeSharedMemoryRegion;
1504 static const char kClientName[];
1505};
1506const char UnsafeRegionTraits::kClientName[] =
1507 "IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient";
1508struct ReadOnlyRegionTraits {
1509 using RegionType = base::ReadOnlySharedMemoryRegion;
1510 static const char kClientName[];
1511};
1512const char ReadOnlyRegionTraits::kClientName[] =
1513 "IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient";
1514
1515typedef ::testing::
1516 Types<WritableRegionTraits, UnsafeRegionTraits, ReadOnlyRegionTraits>
1517 AllSharedMemoryRegionTraits;
Victor Costanebc52732019-02-15 02:39:471518TYPED_TEST_SUITE(IPCChannelMojoSharedMemoryRegionTypedTest,
1519 AllSharedMemoryRegionTraits);
Alexandr Ilind497eee2018-04-19 22:50:541520
1521template <class SharedMemoryRegionType>
1522class ListenerThatExpectsSharedMemoryRegion : public TestListenerBase {
1523 public:
Wezfdb98482018-07-12 01:21:391524 explicit ListenerThatExpectsSharedMemoryRegion(base::OnceClosure quit_closure)
Alexandr Ilind497eee2018-04-19 22:50:541525 : TestListenerBase(std::move(quit_closure)) {}
1526
1527 bool OnMessageReceived(const IPC::Message& message) override {
1528 base::PickleIterator iter(message);
1529
1530 SharedMemoryRegionType region;
1531 EXPECT_TRUE(IPC::ReadParam(&message, &iter, &region));
1532 EXPECT_TRUE(region.IsValid());
1533
1534 // Verify the shared memory region has expected content.
1535 typename SharedMemoryRegionType::MappingType mapping = region.Map();
1536 std::string content = HandleSendingHelper::GetSendingFileContent();
1537 EXPECT_EQ(0, memcmp(mapping.memory(), content.data(), content.size()));
1538
1539 ListenerThatExpectsOK::SendOK(sender());
1540 return true;
1541 }
1542};
1543
1544TYPED_TEST(IPCChannelMojoSharedMemoryRegionTypedTest, Send) {
1545 this->Init(TypeParam::kClientName);
1546
1547 const size_t size = 1004;
1548 typename TypeParam::RegionType region;
1549 base::WritableSharedMemoryMapping mapping;
1550 std::tie(region, mapping) =
1551 base::CreateMappedRegion<typename TypeParam::RegionType>(size);
1552
1553 std::string content = HandleSendingHelper::GetSendingFileContent();
1554 memcpy(mapping.memory(), content.data(), content.size());
1555
1556 // Create a success listener, and launch the child process.
1557 base::RunLoop run_loop;
1558 ListenerThatExpectsOK listener(run_loop.QuitClosure());
1559 this->CreateChannel(&listener);
1560 ASSERT_TRUE(this->ConnectChannel());
1561
1562 // Send the child process an IPC with |shmem| attached, to verify
1563 // that is is correctly wrapped, transferred and unwrapped.
1564 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
1565 IPC::WriteParam(message, region);
1566 ASSERT_TRUE(this->channel()->Send(message));
1567
1568 run_loop.Run();
1569
1570 this->channel()->Close();
1571
1572 EXPECT_TRUE(this->WaitForClientShutdown());
1573 EXPECT_FALSE(region.IsValid());
1574 this->DestroyChannel();
1575}
1576
1577DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1578 IPCChannelMojoTestSendWritableSharedMemoryRegionClient) {
1579 base::RunLoop run_loop;
1580 ListenerThatExpectsSharedMemoryRegion<base::WritableSharedMemoryRegion>
1581 listener(run_loop.QuitClosure());
1582 Connect(&listener);
1583 listener.set_sender(channel());
1584
1585 run_loop.Run();
1586
1587 Close();
1588}
1589DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1590 IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient) {
1591 base::RunLoop run_loop;
1592 ListenerThatExpectsSharedMemoryRegion<base::UnsafeSharedMemoryRegion>
1593 listener(run_loop.QuitClosure());
1594 Connect(&listener);
1595 listener.set_sender(channel());
1596
1597 run_loop.Run();
1598
1599 Close();
1600}
1601DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1602 IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient) {
1603 base::RunLoop run_loop;
1604 ListenerThatExpectsSharedMemoryRegion<base::ReadOnlySharedMemoryRegion>
1605 listener(run_loop.QuitClosure());
1606 Connect(&listener);
1607 listener.set_sender(channel());
1608
1609 run_loop.Run();
1610
1611 Close();
1612}
Xiaohan Wangab909b32022-01-12 17:57:391613#endif // !BUILDFLAG(IS_APPLE)
Wez831ae412017-08-30 00:29:361614
Xiaohan Wangab909b32022-01-12 17:57:391615#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
rockot8d890f62016-07-14 16:37:141616
Wez831ae412017-08-30 00:29:361617class ListenerThatExpectsFile : public TestListenerBase {
[email protected]64860882014-08-04 23:44:171618 public:
Wezfdb98482018-07-12 01:21:391619 explicit ListenerThatExpectsFile(base::OnceClosure quit_closure)
1620 : TestListenerBase(std::move(quit_closure)) {}
[email protected]64860882014-08-04 23:44:171621
dchengfe61fca2014-10-22 02:29:521622 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251623 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301624 HandleSendingHelper::ReadReceivedFile(message, &iter);
Wez831ae412017-08-30 00:29:361625 ListenerThatExpectsOK::SendOK(sender());
[email protected]64860882014-08-04 23:44:171626 return true;
1627 }
[email protected]64860882014-08-04 23:44:171628};
1629
Wez831ae412017-08-30 00:29:361630TEST_F(IPCChannelMojoTest, SendPlatformFile) {
1631 Init("IPCChannelMojoTestSendPlatformFileClient");
[email protected]64860882014-08-04 23:44:171632
Wez831ae412017-08-30 00:29:361633 base::RunLoop run_loop;
1634 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita373af03b2014-09-09 19:35:241635 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:171636 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:171637
amistry20e2b1d62016-06-23 06:12:351638 base::ScopedTempDir temp_dir;
1639 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001640 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
[email protected]64860882014-08-04 23:44:171641 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:301642 base::File::FLAG_READ);
1643 HandleSendingHelper::WriteFileThenSend(channel(), file);
Wez831ae412017-08-30 00:29:361644 run_loop.Run();
[email protected]64860882014-08-04 23:44:171645
sammc57ed9f982016-03-10 06:28:351646 channel()->Close();
[email protected]64860882014-08-04 23:44:171647
1648 EXPECT_TRUE(WaitForClientShutdown());
1649 DestroyChannel();
1650}
1651
Wez831ae412017-08-30 00:29:361652DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileClient) {
1653 base::RunLoop run_loop;
1654 ListenerThatExpectsFile listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351655 Connect(&listener);
1656 listener.set_sender(channel());
[email protected]64860882014-08-04 23:44:171657
Wez831ae412017-08-30 00:29:361658 run_loop.Run();
[email protected]64860882014-08-04 23:44:171659
sammc57ed9f982016-03-10 06:28:351660 Close();
[email protected]64860882014-08-04 23:44:171661}
morrita81b17e02015-02-06 00:58:301662
Wez831ae412017-08-30 00:29:361663class ListenerThatExpectsFileAndMessagePipe : public TestListenerBase {
morrita81b17e02015-02-06 00:58:301664 public:
Wezfdb98482018-07-12 01:21:391665 explicit ListenerThatExpectsFileAndMessagePipe(base::OnceClosure quit_closure)
1666 : TestListenerBase(std::move(quit_closure)) {}
morrita81b17e02015-02-06 00:58:301667
Chris Watkins2d879af2017-11-30 02:11:591668 ~ListenerThatExpectsFileAndMessagePipe() override = default;
morrita81b17e02015-02-06 00:58:301669
1670 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251671 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301672 HandleSendingHelper::ReadReceivedFile(message, &iter);
1673 HandleSendingHelper::ReadReceivedPipe(message, &iter);
Wez831ae412017-08-30 00:29:361674 ListenerThatExpectsOK::SendOK(sender());
morrita81b17e02015-02-06 00:58:301675 return true;
1676 }
morrita81b17e02015-02-06 00:58:301677};
1678
Wez831ae412017-08-30 00:29:361679TEST_F(IPCChannelMojoTest, SendPlatformFileAndMessagePipe) {
1680 Init("IPCChannelMojoTestSendPlatformFileAndMessagePipeClient");
morrita81b17e02015-02-06 00:58:301681
Wez831ae412017-08-30 00:29:361682 base::RunLoop run_loop;
1683 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita81b17e02015-02-06 00:58:301684 CreateChannel(&listener);
1685 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:301686
amistry20e2b1d62016-06-23 06:12:351687 base::ScopedTempDir temp_dir;
1688 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001689 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
morrita81b17e02015-02-06 00:58:301690 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1691 base::File::FLAG_READ);
1692 TestingMessagePipe pipe;
1693 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
1694
Wez831ae412017-08-30 00:29:361695 run_loop.Run();
sammc57ed9f982016-03-10 06:28:351696 channel()->Close();
morrita81b17e02015-02-06 00:58:301697
1698 EXPECT_TRUE(WaitForClientShutdown());
1699 DestroyChannel();
1700}
1701
sammc57ed9f982016-03-10 06:28:351702DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
Wez831ae412017-08-30 00:29:361703 IPCChannelMojoTestSendPlatformFileAndMessagePipeClient) {
1704 base::RunLoop run_loop;
1705 ListenerThatExpectsFileAndMessagePipe listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351706 Connect(&listener);
1707 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:301708
Wez831ae412017-08-30 00:29:361709 run_loop.Run();
morrita81b17e02015-02-06 00:58:301710
sammc57ed9f982016-03-10 06:28:351711 Close();
morrita81b17e02015-02-06 00:58:301712}
1713
Xiaohan Wangab909b32022-01-12 17:57:391714#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
[email protected]64860882014-08-04 23:44:171715
Xiaohan Wangab909b32022-01-12 17:57:391716#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
morrita0bd20bd2015-02-25 20:11:271717
1718const base::ProcessId kMagicChildId = 54321;
1719
Wez831ae412017-08-30 00:29:361720class ListenerThatVerifiesPeerPid : public TestListenerBase {
morrita0bd20bd2015-02-25 20:11:271721 public:
Wezfdb98482018-07-12 01:21:391722 explicit ListenerThatVerifiesPeerPid(base::OnceClosure quit_closure)
1723 : TestListenerBase(std::move(quit_closure)) {}
Wez831ae412017-08-30 00:29:361724
tfarina10a5c062015-09-04 18:47:571725 void OnChannelConnected(int32_t peer_pid) override {
morrita0bd20bd2015-02-25 20:11:271726 EXPECT_EQ(peer_pid, kMagicChildId);
Wezfdb98482018-07-12 01:21:391727 RunQuitClosure();
morrita0bd20bd2015-02-25 20:11:271728 }
1729
1730 bool OnMessageReceived(const IPC::Message& message) override {
1731 NOTREACHED();
1732 return true;
1733 }
1734};
1735
sammc57ed9f982016-03-10 06:28:351736TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
sammc4bcc4ed62016-10-27 10:13:591737 Init("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:271738
Wez831ae412017-08-30 00:29:361739 base::RunLoop run_loop;
1740 ListenerThatVerifiesPeerPid listener(run_loop.QuitClosure());
morrita0bd20bd2015-02-25 20:11:271741 CreateChannel(&listener);
1742 ASSERT_TRUE(ConnectChannel());
morrita0bd20bd2015-02-25 20:11:271743
Wez831ae412017-08-30 00:29:361744 run_loop.Run();
rockotcbca72f2015-03-03 16:31:041745 channel()->Close();
morrita0bd20bd2015-02-25 20:11:271746
1747 EXPECT_TRUE(WaitForClientShutdown());
1748 DestroyChannel();
1749}
1750
sammc4bcc4ed62016-10-27 10:13:591751DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient) {
morrita0bd20bd2015-02-25 20:11:271752 IPC::Channel::SetGlobalPid(kMagicChildId);
Wez831ae412017-08-30 00:29:361753
1754 base::RunLoop run_loop;
1755 ListenerThatQuits listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351756 Connect(&listener);
morrita0bd20bd2015-02-25 20:11:271757
Wez831ae412017-08-30 00:29:361758 run_loop.Run();
morrita0bd20bd2015-02-25 20:11:271759
sammc57ed9f982016-03-10 06:28:351760 Close();
morrita0bd20bd2015-02-25 20:11:271761}
1762
Xiaohan Wangab909b32022-01-12 17:57:391763#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
morrita0bd20bd2015-02-25 20:11:271764
[email protected]64860882014-08-04 23:44:171765} // namespace