blob: e6f5feb58d566c14f546065b63fc0e6e42f42f89 [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"
rockot8d890f62016-07-14 16:37:1420#include "base/macros.h"
Alexandr Ilind497eee2018-04-19 22:50:5421#include "base/memory/platform_shared_memory_region.h"
Wez831ae412017-08-30 00:29:3622#include "base/memory/shared_memory.h"
Alexandr Ilind497eee2018-04-19 22:50:5423#include "base/memory/shared_memory_mapping.h"
Carlos Caballerodd8bf7b042019-07-30 14:14:1524#include "base/message_loop/message_pump_type.h"
Ken Rockot138153b2018-07-13 23:31:5725#include "base/optional.h"
[email protected]64860882014-08-04 23:44:1726#include "base/path_service.h"
27#include "base/pickle.h"
rockotcbca72f2015-03-03 16:31:0428#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2129#include "base/single_thread_task_runner.h"
rockot7c6bf952016-07-14 00:34:1130#include "base/strings/stringprintf.h"
rockot9abe09b2016-08-02 20:57:3431#include "base/synchronization/waitable_event.h"
Ken Rockot138153b2018-07-13 23:31:5732#include "base/test/bind_test_util.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"
Ken Rockot138153b2018-07-13 23:31:5750#include "mojo/core/embedder/embedder.h"
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:1551#include "mojo/public/cpp/bindings/associated_receiver.h"
52#include "mojo/public/cpp/bindings/associated_remote.h"
Ken Rockot138153b2018-07-13 23:31:5753#include "mojo/public/cpp/bindings/lib/validation_errors.h"
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:1554#include "mojo/public/cpp/bindings/pending_associated_receiver.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"
[email protected]64860882014-08-04 23:44:1757
Fabrice de Gans-Riberi894661c2018-05-24 18:43:2258#if defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]64860882014-08-04 23:44:1759#include "base/file_descriptor_posix.h"
morrita1aa788c2015-01-31 05:45:4260#include "ipc/ipc_platform_file_attachment_posix.h"
[email protected]64860882014-08-04 23:44:1761#endif
62
63namespace {
64
rockot7c6bf952016-07-14 00:34:1165void SendString(IPC::Sender* sender, const std::string& str) {
66 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
67 message->WriteString(str);
68 ASSERT_TRUE(sender->Send(message));
69}
70
rockot9abe09b2016-08-02 20:57:3471void SendValue(IPC::Sender* sender, int32_t value) {
72 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
73 message->WriteInt(value);
74 ASSERT_TRUE(sender->Send(message));
75}
76
[email protected]64860882014-08-04 23:44:1777class ListenerThatExpectsOK : public IPC::Listener {
78 public:
Wezfdb98482018-07-12 01:21:3979 explicit ListenerThatExpectsOK(base::OnceClosure quit_closure)
80 : received_ok_(false), quit_closure_(std::move(quit_closure)) {}
[email protected]64860882014-08-04 23:44:1781
Chris Watkins2d879af2017-11-30 02:11:5982 ~ListenerThatExpectsOK() override = default;
[email protected]64860882014-08-04 23:44:1783
dchengfe61fca2014-10-22 02:29:5284 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:2585 base::PickleIterator iter(message);
[email protected]64860882014-08-04 23:44:1786 std::string should_be_ok;
87 EXPECT_TRUE(iter.ReadString(&should_be_ok));
88 EXPECT_EQ(should_be_ok, "OK");
[email protected]e5c27752014-08-08 21:45:1389 received_ok_ = true;
Wezfdb98482018-07-12 01:21:3990 std::move(quit_closure_).Run();
[email protected]64860882014-08-04 23:44:1791 return true;
92 }
93
dchengfe61fca2014-10-22 02:29:5294 void OnChannelError() override {
[email protected]e5c27752014-08-08 21:45:1395 // The connection should be healthy while the listener is waiting
96 // message. An error can occur after that because the peer
97 // process dies.
Wezd95d48042018-02-26 20:50:4798 CHECK(received_ok_);
[email protected]64860882014-08-04 23:44:1799 }
100
rockot7c6bf952016-07-14 00:34:11101 static void SendOK(IPC::Sender* sender) { SendString(sender, "OK"); }
[email protected]e5c27752014-08-08 21:45:13102
103 private:
104 bool received_ok_;
Wezfdb98482018-07-12 01:21:39105 base::OnceClosure quit_closure_;
Wez831ae412017-08-30 00:29:36106};
107
108class TestListenerBase : public IPC::Listener {
109 public:
Wezfdb98482018-07-12 01:21:39110 explicit TestListenerBase(base::OnceClosure quit_closure)
111 : quit_closure_(std::move(quit_closure)) {}
Wez831ae412017-08-30 00:29:36112
Chris Watkins2d879af2017-11-30 02:11:59113 ~TestListenerBase() override = default;
Wezfdb98482018-07-12 01:21:39114 void OnChannelError() override { RunQuitClosure(); }
Wez831ae412017-08-30 00:29:36115
116 void set_sender(IPC::Sender* sender) { sender_ = sender; }
117 IPC::Sender* sender() const { return sender_; }
Ken Rockot138153b2018-07-13 23:31:57118 void RunQuitClosure() {
119 if (quit_closure_)
120 std::move(quit_closure_).Run();
121 }
Wez831ae412017-08-30 00:29:36122
123 private:
124 IPC::Sender* sender_ = nullptr;
Wezfdb98482018-07-12 01:21:39125 base::OnceClosure quit_closure_;
[email protected]64860882014-08-04 23:44:17126};
127
sammc4bcc4ed62016-10-27 10:13:59128using IPCChannelMojoTest = IPCChannelMojoTestBase;
rockotcbca72f2015-03-03 16:31:04129
[email protected]64860882014-08-04 23:44:17130class TestChannelListenerWithExtraExpectations
131 : public IPC::TestChannelListener {
132 public:
sammc57ed9f982016-03-10 06:28:35133 TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
[email protected]64860882014-08-04 23:44:17134
tfarina10a5c062015-09-04 18:47:57135 void OnChannelConnected(int32_t peer_pid) override {
[email protected]64860882014-08-04 23:44:17136 IPC::TestChannelListener::OnChannelConnected(peer_pid);
137 EXPECT_TRUE(base::kNullProcessId != peer_pid);
138 is_connected_called_ = true;
139 }
140
141 bool is_connected_called() const { return is_connected_called_; }
142
143 private:
144 bool is_connected_called_;
145};
146
amistry0027a0952016-05-03 00:52:47147TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
sammc4bcc4ed62016-10-27 10:13:59148 Init("IPCChannelMojoTestClient");
[email protected]64860882014-08-04 23:44:17149
150 // Set up IPC channel and start client.
151 TestChannelListenerWithExtraExpectations listener;
morrita373af03b2014-09-09 19:35:24152 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:17153 listener.Init(sender());
154 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:17155
sammc57ed9f982016-03-10 06:28:35156 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
[email protected]64860882014-08-04 23:44:17157
fdoray8e32586852016-06-22 19:56:16158 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17159
sammc57ed9f982016-03-10 06:28:35160 channel()->Close();
[email protected]64860882014-08-04 23:44:17161
162 EXPECT_TRUE(WaitForClientShutdown());
163 EXPECT_TRUE(listener.is_connected_called());
164 EXPECT_TRUE(listener.HasSentAll());
165
166 DestroyChannel();
167}
168
169// A long running process that connects to us
sammc4bcc4ed62016-10-27 10:13:59170DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient) {
[email protected]64860882014-08-04 23:44:17171 TestChannelListenerWithExtraExpectations listener;
sammc57ed9f982016-03-10 06:28:35172 Connect(&listener);
173 listener.Init(channel());
[email protected]64860882014-08-04 23:44:17174
sammc57ed9f982016-03-10 06:28:35175 IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
fdoray8e32586852016-06-22 19:56:16176 base::RunLoop().Run();
[email protected]64860882014-08-04 23:44:17177 EXPECT_TRUE(listener.is_connected_called());
178 EXPECT_TRUE(listener.HasSentAll());
179
sammc57ed9f982016-03-10 06:28:35180 Close();
[email protected]64860882014-08-04 23:44:17181}
182
Wez831ae412017-08-30 00:29:36183class ListenerExpectingErrors : public TestListenerBase {
morrita0a24cfc92014-09-16 03:20:48184 public:
Wezfdb98482018-07-12 01:21:39185 ListenerExpectingErrors(base::OnceClosure quit_closure)
186 : TestListenerBase(std::move(quit_closure)), has_error_(false) {}
morrita0a24cfc92014-09-16 03:20:48187
dchengfe61fca2014-10-22 02:29:52188 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48189
dchengfe61fca2014-10-22 02:29:52190 void OnChannelError() override {
morrita0a24cfc92014-09-16 03:20:48191 has_error_ = true;
Wez831ae412017-08-30 00:29:36192 TestListenerBase::OnChannelError();
morrita0a24cfc92014-09-16 03:20:48193 }
194
195 bool has_error() const { return has_error_; }
196
197 private:
198 bool has_error_;
199};
200
morrita0a24cfc92014-09-16 03:20:48201class ListenerThatQuits : public IPC::Listener {
202 public:
Wezfdb98482018-07-12 01:21:39203 explicit ListenerThatQuits(base::OnceClosure quit_closure)
204 : quit_closure_(std::move(quit_closure)) {}
morrita0a24cfc92014-09-16 03:20:48205
sammc57ed9f982016-03-10 06:28:35206 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita0a24cfc92014-09-16 03:20:48207
Wezfdb98482018-07-12 01:21:39208 void OnChannelConnected(int32_t peer_pid) override {
209 std::move(quit_closure_).Run();
210 }
Wez831ae412017-08-30 00:29:36211
212 private:
Wezfdb98482018-07-12 01:21:39213 base::OnceClosure quit_closure_;
morrita0a24cfc92014-09-16 03:20:48214};
215
216// A long running process that connects to us.
sammc4bcc4ed62016-10-27 10:13:59217DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient) {
Wez831ae412017-08-30 00:29:36218 base::RunLoop run_loop;
219 ListenerThatQuits listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35220 Connect(&listener);
morrita0a24cfc92014-09-16 03:20:48221
Wez831ae412017-08-30 00:29:36222 run_loop.Run();
morrita0a24cfc92014-09-16 03:20:48223
sammc57ed9f982016-03-10 06:28:35224 Close();
morrita0a24cfc92014-09-16 03:20:48225}
226
rockot8c23d462016-07-25 17:33:04227TEST_F(IPCChannelMojoTest, SendFailWithPendingMessages) {
sammc4bcc4ed62016-10-27 10:13:59228 Init("IPCChannelMojoErraticTestClient");
morrita0a24cfc92014-09-16 03:20:48229
230 // Set up IPC channel and start client.
Wez831ae412017-08-30 00:29:36231 base::RunLoop run_loop;
232 ListenerExpectingErrors listener(run_loop.QuitClosure());
morrita0a24cfc92014-09-16 03:20:48233 CreateChannel(&listener);
234 ASSERT_TRUE(ConnectChannel());
235
jamesra03ae492014-10-03 04:26:48236 // This matches a value in mojo/edk/system/constants.h
morritabe6c4cc2014-09-24 23:38:44237 const int kMaxMessageNumBytes = 4 * 1024 * 1024;
238 std::string overly_large_data(kMaxMessageNumBytes, '*');
morrita0a24cfc92014-09-16 03:20:48239 // This messages are queued as pending.
morritabe6c4cc2014-09-24 23:38:44240 for (size_t i = 0; i < 10; ++i) {
sammc57ed9f982016-03-10 06:28:35241 IPC::TestChannelListener::SendOneMessage(sender(),
242 overly_large_data.c_str());
morrita0a24cfc92014-09-16 03:20:48243 }
244
Wez831ae412017-08-30 00:29:36245 run_loop.Run();
morrita0a24cfc92014-09-16 03:20:48246
sammc57ed9f982016-03-10 06:28:35247 channel()->Close();
morrita0a24cfc92014-09-16 03:20:48248
249 EXPECT_TRUE(WaitForClientShutdown());
250 EXPECT_TRUE(listener.has_error());
251
252 DestroyChannel();
253}
254
Ken Rockot138153b2018-07-13 23:31:57255class ListenerThatBindsATestStructPasser : public IPC::Listener,
256 public IPC::mojom::TestStructPasser {
257 public:
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54258 ListenerThatBindsATestStructPasser() = default;
259 ~ListenerThatBindsATestStructPasser() override = default;
Ken Rockot138153b2018-07-13 23:31:57260
261 bool OnMessageReceived(const IPC::Message& message) override { return true; }
262
263 void OnChannelConnected(int32_t peer_pid) override {}
264
265 void OnChannelError() override { NOTREACHED(); }
266
267 void OnAssociatedInterfaceRequest(
268 const std::string& interface_name,
269 mojo::ScopedInterfaceEndpointHandle handle) override {
270 CHECK_EQ(interface_name, IPC::mojom::TestStructPasser::Name_);
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54271 receiver_.Bind(
272 mojo::PendingAssociatedReceiver<IPC::mojom::TestStructPasser>(
273 std::move(handle)));
Ken Rockot138153b2018-07-13 23:31:57274 }
275
276 private:
277 // IPC::mojom::TestStructPasser:
278 void Pass(IPC::mojom::TestStructPtr) override { NOTREACHED(); }
279
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54280 mojo::AssociatedReceiver<IPC::mojom::TestStructPasser> receiver_{this};
Ken Rockot138153b2018-07-13 23:31:57281};
282
283class ListenerThatExpectsNoError : public IPC::Listener {
284 public:
285 ListenerThatExpectsNoError(base::OnceClosure connect_closure,
286 base::OnceClosure quit_closure)
287 : connect_closure_(std::move(connect_closure)),
288 quit_closure_(std::move(quit_closure)) {}
289
290 bool OnMessageReceived(const IPC::Message& message) override {
291 base::PickleIterator iter(message);
292 std::string should_be_ok;
293 EXPECT_TRUE(iter.ReadString(&should_be_ok));
294 EXPECT_EQ(should_be_ok, "OK");
295 std::move(quit_closure_).Run();
296 return true;
297 }
298
299 void OnChannelConnected(int32_t peer_pid) override {
300 std::move(connect_closure_).Run();
301 }
302
303 void OnChannelError() override { NOTREACHED(); }
304
305 private:
306 base::OnceClosure connect_closure_;
307 base::OnceClosure quit_closure_;
308};
309
310DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
311 IPCChannelMojoNoImplicitChanelClosureClient) {
312 base::RunLoop wait_to_connect_loop;
313 base::RunLoop wait_to_quit_loop;
314 ListenerThatExpectsNoError listener(wait_to_connect_loop.QuitClosure(),
315 wait_to_quit_loop.QuitClosure());
316 Connect(&listener);
317 wait_to_connect_loop.Run();
318
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54319 mojo::AssociatedRemote<IPC::mojom::TestStructPasser> passer;
Ken Rockot138153b2018-07-13 23:31:57320 channel()->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54321 passer.BindNewEndpointAndPassReceiver());
Ken Rockot138153b2018-07-13 23:31:57322
323 // This avoids hitting DCHECKs in the serialization code meant to stop us from
324 // making such "mistakes" as the one we're about to make below.
325 mojo::internal::SerializationWarningObserverForTesting suppress_those_dchecks;
326
327 // Send an invalid message. The TestStruct argument is not allowed to be null.
328 // This will elicit a validation error in the parent process, but should not
329 // actually disconnect the channel.
330 passer->Pass(nullptr);
331
332 // Wait until the parent says it's OK to quit, so it has time to verify its
333 // expected behavior.
334 wait_to_quit_loop.Run();
335
336 Close();
337}
338
339TEST_F(IPCChannelMojoTest, NoImplicitChannelClosure) {
340 // Verifies that OnChannelError is not invoked due to conditions other than
341 // peer closure (e.g. a malformed inbound message). Instead we should always
342 // be able to handle validation errors via Mojo bad message reporting.
343
344 // NOTE: We can't create a RunLoop before Init() is called, but we have to set
345 // the default ProcessErrorCallback (which we want to reference the RunLoop)
346 // before Init() launches a child process. Hence the base::Optional here.
347 base::Optional<base::RunLoop> wait_for_error_loop;
348 bool process_error_received = false;
349 mojo::core::SetDefaultProcessErrorCallback(
350 base::BindLambdaForTesting([&](const std::string&) {
351 process_error_received = true;
352 wait_for_error_loop->Quit();
353 }));
354
355 Init("IPCChannelMojoNoImplicitChanelClosureClient");
356
357 wait_for_error_loop.emplace();
358 ListenerThatBindsATestStructPasser listener;
359 CreateChannel(&listener);
360 ASSERT_TRUE(ConnectChannel());
361
362 wait_for_error_loop->Run();
363 EXPECT_TRUE(process_error_received);
364
365 // Tell the child it can quit and wait for it to shut down.
366 ListenerThatExpectsOK::SendOK(channel());
367 EXPECT_TRUE(WaitForClientShutdown());
368 DestroyChannel();
369}
370
morrita81b17e02015-02-06 00:58:30371struct TestingMessagePipe {
372 TestingMessagePipe() {
373 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer));
374 }
375
376 mojo::ScopedMessagePipeHandle self;
377 mojo::ScopedMessagePipeHandle peer;
378};
379
380class HandleSendingHelper {
381 public:
382 static std::string GetSendingFileContent() { return "Hello"; }
383
384 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) {
385 std::string content = HandleSendingHelper::GetSendingFileContent();
386 EXPECT_EQ(MOJO_RESULT_OK,
387 mojo::WriteMessageRaw(pipe->self.get(), &content[0],
388 static_cast<uint32_t>(content.size()),
389 nullptr, 0, 0));
dchenge48600452015-12-28 02:24:50390 EXPECT_TRUE(IPC::MojoMessageHelper::WriteMessagePipeTo(
391 message, std::move(pipe->peer)));
morrita81b17e02015-02-06 00:58:30392 }
393
394 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) {
395 IPC::Message* message =
396 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
397 WritePipe(message, pipe);
398 ASSERT_TRUE(sender->Send(message));
399 }
400
401 static void ReadReceivedPipe(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25402 base::PickleIterator* iter) {
morrita81b17e02015-02-06 00:58:30403 mojo::ScopedMessagePipeHandle pipe;
404 EXPECT_TRUE(
405 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
Ken Rockotfada7d282017-06-12 21:25:13406 std::vector<uint8_t> content;
morrita81b17e02015-02-06 00:58:30407
sammc57ed9f982016-03-10 06:28:35408 ASSERT_EQ(MOJO_RESULT_OK,
rockota9d566a2017-03-17 19:36:15409 mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE));
morrita81b17e02015-02-06 00:58:30410 EXPECT_EQ(MOJO_RESULT_OK,
Ken Rockotfada7d282017-06-12 21:25:13411 mojo::ReadMessageRaw(pipe.get(), &content, nullptr, 0));
412 EXPECT_EQ(std::string(content.begin(), content.end()),
413 GetSendingFileContent());
morrita81b17e02015-02-06 00:58:30414 }
415
Fabrice de Gans-Riberi894661c2018-05-24 18:43:22416#if defined(OS_POSIX) || defined(OS_FUCHSIA)
amistry20e2b1d62016-06-23 06:12:35417 static base::FilePath GetSendingFilePath(const base::FilePath& dir_path) {
418 return dir_path.Append("ListenerThatExpectsFile.txt");
morrita81b17e02015-02-06 00:58:30419 }
420
421 static void WriteFile(IPC::Message* message, base::File& file) {
422 std::string content = GetSendingFileContent();
423 file.WriteAtCurrentPos(content.data(), content.size());
424 file.Flush();
425 message->WriteAttachment(new IPC::internal::PlatformFileAttachment(
426 base::ScopedFD(file.TakePlatformFile())));
427 }
428
429 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) {
430 IPC::Message* message =
431 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
432 WriteFile(message, file);
433 ASSERT_TRUE(sender->Send(message));
434 }
435
436 static void WriteFileAndPipeThenSend(IPC::Sender* sender,
437 base::File& file,
438 TestingMessagePipe* pipe) {
439 IPC::Message* message =
440 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
441 WriteFile(message, file);
442 WritePipe(message, pipe);
443 ASSERT_TRUE(sender->Send(message));
444 }
445
446 static void ReadReceivedFile(const IPC::Message& message,
brettwbd4d7112015-06-03 04:29:25447 base::PickleIterator* iter) {
rockot502c94f2016-02-03 20:20:16448 scoped_refptr<base::Pickle::Attachment> attachment;
morrita81b17e02015-02-06 00:58:30449 EXPECT_TRUE(message.ReadAttachment(iter, &attachment));
sammc6ed3efb2016-11-23 03:17:35450 EXPECT_EQ(
451 IPC::MessageAttachment::Type::PLATFORM_FILE,
452 static_cast<IPC::MessageAttachment*>(attachment.get())->GetType());
453 base::File file(
454 static_cast<IPC::internal::PlatformFileAttachment*>(attachment.get())
455 ->TakePlatformFile());
morrita81b17e02015-02-06 00:58:30456 std::string content(GetSendingFileContent().size(), ' ');
457 file.Read(0, &content[0], content.size());
458 EXPECT_EQ(content, GetSendingFileContent());
459 }
460#endif
461};
462
Wez831ae412017-08-30 00:29:36463class ListenerThatExpectsMessagePipe : public TestListenerBase {
morrita81b17e02015-02-06 00:58:30464 public:
Wezfdb98482018-07-12 01:21:39465 ListenerThatExpectsMessagePipe(base::OnceClosure quit_closure)
466 : TestListenerBase(std::move(quit_closure)) {}
morrita81b17e02015-02-06 00:58:30467
Chris Watkins2d879af2017-11-30 02:11:59468 ~ListenerThatExpectsMessagePipe() override = default;
morrita81b17e02015-02-06 00:58:30469
470 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25471 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:30472 HandleSendingHelper::ReadReceivedPipe(message, &iter);
Wez831ae412017-08-30 00:29:36473 ListenerThatExpectsOK::SendOK(sender());
morrita81b17e02015-02-06 00:58:30474 return true;
475 }
morrita81b17e02015-02-06 00:58:30476};
477
amistry0027a0952016-05-03 00:52:47478TEST_F(IPCChannelMojoTest, SendMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59479 Init("IPCChannelMojoTestSendMessagePipeClient");
morrita81b17e02015-02-06 00:58:30480
Wez831ae412017-08-30 00:29:36481 base::RunLoop run_loop;
482 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita81b17e02015-02-06 00:58:30483 CreateChannel(&listener);
484 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:30485
486 TestingMessagePipe pipe;
487 HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
488
Wez831ae412017-08-30 00:29:36489 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35490 channel()->Close();
morrita81b17e02015-02-06 00:58:30491
492 EXPECT_TRUE(WaitForClientShutdown());
493 DestroyChannel();
494}
495
sammc4bcc4ed62016-10-27 10:13:59496DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient) {
Wez831ae412017-08-30 00:29:36497 base::RunLoop run_loop;
498 ListenerThatExpectsMessagePipe listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35499 Connect(&listener);
500 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:30501
Wez831ae412017-08-30 00:29:36502 run_loop.Run();
morrita81b17e02015-02-06 00:58:30503
sammc57ed9f982016-03-10 06:28:35504 Close();
morrita81b17e02015-02-06 00:58:30505}
506
morrita438a2ee2015-04-03 05:28:21507void ReadOK(mojo::MessagePipeHandle pipe) {
Ken Rockotfada7d282017-06-12 21:25:13508 std::vector<uint8_t> should_be_ok;
rockota9d566a2017-03-17 19:36:15509 CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE));
morrita438a2ee2015-04-03 05:28:21510 CHECK_EQ(MOJO_RESULT_OK,
Ken Rockotfada7d282017-06-12 21:25:13511 mojo::ReadMessageRaw(pipe, &should_be_ok, nullptr, 0));
512 EXPECT_EQ("OK", std::string(should_be_ok.begin(), should_be_ok.end()));
morrita438a2ee2015-04-03 05:28:21513}
514
515void WriteOK(mojo::MessagePipeHandle pipe) {
516 std::string ok("OK");
517 CHECK_EQ(MOJO_RESULT_OK,
518 mojo::WriteMessageRaw(pipe, &ok[0], static_cast<uint32_t>(ok.size()),
519 nullptr, 0, 0));
520}
521
Wez831ae412017-08-30 00:29:36522class ListenerThatExpectsMessagePipeUsingParamTrait : public TestListenerBase {
morrita438a2ee2015-04-03 05:28:21523 public:
Wez831ae412017-08-30 00:29:36524 explicit ListenerThatExpectsMessagePipeUsingParamTrait(
Wezfdb98482018-07-12 01:21:39525 base::OnceClosure quit_closure,
Wez831ae412017-08-30 00:29:36526 bool receiving_valid)
Wezfdb98482018-07-12 01:21:39527 : TestListenerBase(std::move(quit_closure)),
528 receiving_valid_(receiving_valid) {}
morrita438a2ee2015-04-03 05:28:21529
Chris Watkins2d879af2017-11-30 02:11:59530 ~ListenerThatExpectsMessagePipeUsingParamTrait() override = default;
morrita438a2ee2015-04-03 05:28:21531
532 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:25533 base::PickleIterator iter(message);
morrita438a2ee2015-04-03 05:28:21534 mojo::MessagePipeHandle handle;
535 EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter,
536 &handle));
537 EXPECT_EQ(handle.is_valid(), receiving_valid_);
538 if (receiving_valid_) {
539 ReadOK(handle);
540 MojoClose(handle.value());
541 }
542
Wez831ae412017-08-30 00:29:36543 ListenerThatExpectsOK::SendOK(sender());
morrita438a2ee2015-04-03 05:28:21544 return true;
545 }
546
morrita438a2ee2015-04-03 05:28:21547 private:
morrita438a2ee2015-04-03 05:28:21548 bool receiving_valid_;
549};
550
sammc4bcc4ed62016-10-27 10:13:59551class ParamTraitMessagePipeClient : public IpcChannelMojoTestClient {
sammc57ed9f982016-03-10 06:28:35552 public:
553 void RunTest(bool receiving_valid_handle) {
Wez831ae412017-08-30 00:29:36554 base::RunLoop run_loop;
sammc57ed9f982016-03-10 06:28:35555 ListenerThatExpectsMessagePipeUsingParamTrait listener(
Wez831ae412017-08-30 00:29:36556 run_loop.QuitClosure(), receiving_valid_handle);
sammc57ed9f982016-03-10 06:28:35557 Connect(&listener);
558 listener.set_sender(channel());
morrita438a2ee2015-04-03 05:28:21559
Wez831ae412017-08-30 00:29:36560 run_loop.Run();
morrita438a2ee2015-04-03 05:28:21561
sammc57ed9f982016-03-10 06:28:35562 Close();
563 }
564};
morrita438a2ee2015-04-03 05:28:21565
amistry0027a0952016-05-03 00:52:47566TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59567 Init("ParamTraitValidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21568
Wez831ae412017-08-30 00:29:36569 base::RunLoop run_loop;
570 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita438a2ee2015-04-03 05:28:21571 CreateChannel(&listener);
572 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21573
574 TestingMessagePipe pipe;
575
danakj03de39b22016-04-23 04:21:09576 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21577 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
578 pipe.peer.release());
579 WriteOK(pipe.self.get());
580
sammc57ed9f982016-03-10 06:28:35581 channel()->Send(message.release());
Wez831ae412017-08-30 00:29:36582 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35583 channel()->Close();
morrita438a2ee2015-04-03 05:28:21584
585 EXPECT_TRUE(WaitForClientShutdown());
586 DestroyChannel();
587}
588
sammc4bcc4ed62016-10-27 10:13:59589DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
590 ParamTraitValidMessagePipeClient,
591 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35592 RunTest(true);
morrita438a2ee2015-04-03 05:28:21593}
594
amistry0027a0952016-05-03 00:52:47595TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) {
sammc4bcc4ed62016-10-27 10:13:59596 Init("ParamTraitInvalidMessagePipeClient");
morrita438a2ee2015-04-03 05:28:21597
Wez831ae412017-08-30 00:29:36598 base::RunLoop run_loop;
599 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita438a2ee2015-04-03 05:28:21600 CreateChannel(&listener);
601 ASSERT_TRUE(ConnectChannel());
morrita438a2ee2015-04-03 05:28:21602
603 mojo::MessagePipeHandle invalid_handle;
danakj03de39b22016-04-23 04:21:09604 std::unique_ptr<IPC::Message> message(new IPC::Message());
morrita438a2ee2015-04-03 05:28:21605 IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
606 invalid_handle);
607
sammc57ed9f982016-03-10 06:28:35608 channel()->Send(message.release());
Wez831ae412017-08-30 00:29:36609 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35610 channel()->Close();
morrita438a2ee2015-04-03 05:28:21611
612 EXPECT_TRUE(WaitForClientShutdown());
613 DestroyChannel();
614}
615
sammc4bcc4ed62016-10-27 10:13:59616DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
617 ParamTraitInvalidMessagePipeClient,
618 ParamTraitMessagePipeClient) {
sammc57ed9f982016-03-10 06:28:35619 RunTest(false);
morrita438a2ee2015-04-03 05:28:21620}
621
amistry0027a0952016-05-03 00:52:47622TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
sammc4bcc4ed62016-10-27 10:13:59623 Init("IPCChannelMojoTestSendOkClient");
morrita17137e62015-06-23 22:29:36624
Wez831ae412017-08-30 00:29:36625 base::RunLoop run_loop;
626 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita17137e62015-06-23 22:29:36627 CreateChannel(&listener);
628 ASSERT_TRUE(ConnectChannel());
morrita17137e62015-06-23 22:29:36629
Wez831ae412017-08-30 00:29:36630 run_loop.Run();
sammc57ed9f982016-03-10 06:28:35631 channel()->Close();
632 ASSERT_FALSE(channel()->Send(new IPC::Message()));
morrita17137e62015-06-23 22:29:36633
634 EXPECT_TRUE(WaitForClientShutdown());
635 DestroyChannel();
636}
637
Wez831ae412017-08-30 00:29:36638class ListenerSendingOneOk : public TestListenerBase {
morrita17137e62015-06-23 22:29:36639 public:
Wezfdb98482018-07-12 01:21:39640 ListenerSendingOneOk(base::OnceClosure quit_closure)
641 : TestListenerBase(std::move(quit_closure)) {}
morrita17137e62015-06-23 22:29:36642
sammc57ed9f982016-03-10 06:28:35643 bool OnMessageReceived(const IPC::Message& message) override { return true; }
morrita17137e62015-06-23 22:29:36644
tfarina10a5c062015-09-04 18:47:57645 void OnChannelConnected(int32_t peer_pid) override {
Wez831ae412017-08-30 00:29:36646 ListenerThatExpectsOK::SendOK(sender());
Wezfdb98482018-07-12 01:21:39647 RunQuitClosure();
morrita17137e62015-06-23 22:29:36648 }
morrita17137e62015-06-23 22:29:36649};
650
sammc4bcc4ed62016-10-27 10:13:59651DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient) {
Wez831ae412017-08-30 00:29:36652 base::RunLoop run_loop;
653 ListenerSendingOneOk listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:35654 Connect(&listener);
655 listener.set_sender(channel());
morrita17137e62015-06-23 22:29:36656
Wez831ae412017-08-30 00:29:36657 run_loop.Run();
morrita17137e62015-06-23 22:29:36658
sammc57ed9f982016-03-10 06:28:35659 Close();
morrita17137e62015-06-23 22:29:36660}
661
rockot7c6bf952016-07-14 00:34:11662class ListenerWithSimpleAssociatedInterface
663 : public IPC::Listener,
664 public IPC::mojom::SimpleTestDriver {
665 public:
666 static const int kNumMessages;
667
Wezfdb98482018-07-12 01:21:39668 explicit ListenerWithSimpleAssociatedInterface(base::OnceClosure quit_closure)
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15669 : quit_closure_(std::move(quit_closure)) {}
rockot7c6bf952016-07-14 00:34:11670
Chris Watkins2d879af2017-11-30 02:11:59671 ~ListenerWithSimpleAssociatedInterface() override = default;
rockot7c6bf952016-07-14 00:34:11672
673 bool OnMessageReceived(const IPC::Message& message) override {
674 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34675 int32_t should_be_expected;
676 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
677 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot7c6bf952016-07-14 00:34:11678 num_messages_received_++;
679 return true;
680 }
681
Wezfdb98482018-07-12 01:21:39682 void OnChannelError() override { CHECK(!quit_closure_); }
rockot7c6bf952016-07-14 00:34:11683
684 void RegisterInterfaceFactory(IPC::Channel* channel) {
685 channel->GetAssociatedInterfaceSupport()->AddAssociatedInterface(
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15686 base::BindRepeating(
687 &ListenerWithSimpleAssociatedInterface::BindReceiver,
688 base::Unretained(this)));
rockot7c6bf952016-07-14 00:34:11689 }
690
691 private:
692 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34693 void ExpectValue(int32_t value) override {
694 next_expected_value_ = value;
695 }
696
tzikdd76ce712017-06-08 05:27:04697 void GetExpectedValue(GetExpectedValueCallback callback) override {
rockot9abe09b2016-08-02 20:57:34698 NOTREACHED();
699 }
700
tzikdd76ce712017-06-08 05:27:04701 void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
rockot7c6bf952016-07-14 00:34:11702
tzikdd76ce712017-06-08 05:27:04703 void RequestQuit(RequestQuitCallback callback) override {
rockot7c6bf952016-07-14 00:34:11704 EXPECT_EQ(kNumMessages, num_messages_received_);
tzikdd76ce712017-06-08 05:27:04705 std::move(callback).Run();
Wezfdb98482018-07-12 01:21:39706 std::move(quit_closure_).Run();
rockot7c6bf952016-07-14 00:34:11707 }
708
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15709 void BindReceiver(
710 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
711 DCHECK(!receiver_.is_bound());
712 receiver_.Bind(std::move(receiver));
rockot7c6bf952016-07-14 00:34:11713 }
714
rockot9abe09b2016-08-02 20:57:34715 int32_t next_expected_value_ = 0;
rockot7c6bf952016-07-14 00:34:11716 int num_messages_received_ = 0;
Wezfdb98482018-07-12 01:21:39717 base::OnceClosure quit_closure_;
rockot7c6bf952016-07-14 00:34:11718
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15719 mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
rockot7c6bf952016-07-14 00:34:11720};
721
722const int ListenerWithSimpleAssociatedInterface::kNumMessages = 1000;
723
724class ListenerSendingAssociatedMessages : public IPC::Listener {
725 public:
Wezfdb98482018-07-12 01:21:39726 explicit ListenerSendingAssociatedMessages(base::OnceClosure quit_closure)
727 : quit_closure_(std::move(quit_closure)) {}
rockot7c6bf952016-07-14 00:34:11728
729 bool OnMessageReceived(const IPC::Message& message) override { return true; }
730
731 void OnChannelConnected(int32_t peer_pid) override {
732 DCHECK(channel_);
733 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15734 driver_.BindNewEndpointAndPassReceiver());
rockot7c6bf952016-07-14 00:34:11735
736 // Send a bunch of interleaved messages, alternating between the associated
737 // interface and a legacy IPC::Message.
738 for (int i = 0; i < ListenerWithSimpleAssociatedInterface::kNumMessages;
739 ++i) {
rockot9abe09b2016-08-02 20:57:34740 driver_->ExpectValue(i);
741 SendValue(channel_, i);
rockot7c6bf952016-07-14 00:34:11742 }
Wezfdb98482018-07-12 01:21:39743 driver_->RequestQuit(base::BindOnce(
744 &ListenerSendingAssociatedMessages::OnQuitAck, base::Unretained(this)));
rockot7c6bf952016-07-14 00:34:11745 }
746
747 void set_channel(IPC::Channel* channel) { channel_ = channel; }
748
749 private:
Wezfdb98482018-07-12 01:21:39750 void OnQuitAck() { std::move(quit_closure_).Run(); }
rockot7c6bf952016-07-14 00:34:11751
752 IPC::Channel* channel_ = nullptr;
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15753 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver_;
Wezfdb98482018-07-12 01:21:39754 base::OnceClosure quit_closure_;
rockot7c6bf952016-07-14 00:34:11755};
756
757TEST_F(IPCChannelMojoTest, SimpleAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59758 Init("SimpleAssociatedInterfaceClient");
rockot7c6bf952016-07-14 00:34:11759
Wezfdb98482018-07-12 01:21:39760 base::RunLoop run_loop;
761 ListenerWithSimpleAssociatedInterface listener(run_loop.QuitClosure());
rockot7c6bf952016-07-14 00:34:11762 CreateChannel(&listener);
763 ASSERT_TRUE(ConnectChannel());
764
765 listener.RegisterInterfaceFactory(channel());
766
Wezfdb98482018-07-12 01:21:39767 run_loop.Run();
rockot7c6bf952016-07-14 00:34:11768 channel()->Close();
769
770 EXPECT_TRUE(WaitForClientShutdown());
771 DestroyChannel();
772}
773
sammc4bcc4ed62016-10-27 10:13:59774DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(SimpleAssociatedInterfaceClient) {
Wezfdb98482018-07-12 01:21:39775 base::RunLoop run_loop;
776 ListenerSendingAssociatedMessages listener(run_loop.QuitClosure());
rockot7c6bf952016-07-14 00:34:11777 Connect(&listener);
778 listener.set_channel(channel());
779
Wezfdb98482018-07-12 01:21:39780 run_loop.Run();
rockot7c6bf952016-07-14 00:34:11781
782 Close();
783}
784
rockot8d890f62016-07-14 16:37:14785class ChannelProxyRunner {
786 public:
rockota34707ca2016-07-20 04:28:32787 ChannelProxyRunner(mojo::ScopedMessagePipeHandle handle,
788 bool for_server)
789 : for_server_(for_server),
790 handle_(std::move(handle)),
rockot9abe09b2016-08-02 20:57:34791 io_thread_("ChannelProxyRunner IO thread"),
792 never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
793 base::WaitableEvent::InitialState::NOT_SIGNALED) {
rockot8d890f62016-07-14 16:37:14794 }
795
796 void CreateProxy(IPC::Listener* listener) {
797 io_thread_.StartWithOptions(
Carlos Caballerodd8bf7b042019-07-30 14:14:15798 base::Thread::Options(base::MessagePumpType::IO, 0));
Hajime Hoshiff15e972017-11-09 06:37:09799 proxy_ = IPC::SyncChannel::Create(listener, io_thread_.task_runner(),
800 base::ThreadTaskRunnerHandle::Get(),
801 &never_signaled_);
rockot8d890f62016-07-14 16:37:14802 }
rockota34707ca2016-07-20 04:28:32803
rockot10188752016-09-08 18:24:56804 void RunProxy() {
rockota34707ca2016-07-20 04:28:32805 std::unique_ptr<IPC::ChannelFactory> factory;
806 if (for_server_) {
807 factory = IPC::ChannelMojo::CreateServerFactory(
Hajime Hoshia98f1102017-11-20 06:34:35808 std::move(handle_), io_thread_.task_runner(),
809 base::ThreadTaskRunnerHandle::Get());
rockota34707ca2016-07-20 04:28:32810 } else {
811 factory = IPC::ChannelMojo::CreateClientFactory(
Hajime Hoshia98f1102017-11-20 06:34:35812 std::move(handle_), io_thread_.task_runner(),
813 base::ThreadTaskRunnerHandle::Get());
rockota34707ca2016-07-20 04:28:32814 }
rockot10188752016-09-08 18:24:56815 proxy_->Init(std::move(factory), true);
rockota34707ca2016-07-20 04:28:32816 }
rockot8d890f62016-07-14 16:37:14817
818 IPC::ChannelProxy* proxy() { return proxy_.get(); }
819
820 private:
rockota34707ca2016-07-20 04:28:32821 const bool for_server_;
rockot8d890f62016-07-14 16:37:14822
rockota34707ca2016-07-20 04:28:32823 mojo::ScopedMessagePipeHandle handle_;
rockot8d890f62016-07-14 16:37:14824 base::Thread io_thread_;
rockot9abe09b2016-08-02 20:57:34825 base::WaitableEvent never_signaled_;
rockotb62e2e32017-03-24 18:36:44826 std::unique_ptr<IPC::ChannelProxy> proxy_;
rockot8d890f62016-07-14 16:37:14827
828 DISALLOW_COPY_AND_ASSIGN(ChannelProxyRunner);
829};
830
831class IPCChannelProxyMojoTest : public IPCChannelMojoTestBase {
832 public:
sammc4bcc4ed62016-10-27 10:13:59833 void Init(const std::string& client_name) {
834 IPCChannelMojoTestBase::Init(client_name);
rockota34707ca2016-07-20 04:28:32835 runner_.reset(new ChannelProxyRunner(TakeHandle(), true));
rockot8d890f62016-07-14 16:37:14836 }
837 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot10188752016-09-08 18:24:56838 void RunProxy() {
839 runner_->RunProxy();
rockot401fb2c2016-09-06 18:35:57840 }
rockot0e4de5f2016-07-22 21:18:07841 void DestroyProxy() {
842 runner_.reset();
843 base::RunLoop().RunUntilIdle();
844 }
rockot8d890f62016-07-14 16:37:14845
846 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
847
848 private:
rockot8d890f62016-07-14 16:37:14849 std::unique_ptr<ChannelProxyRunner> runner_;
850};
851
852class ListenerWithSimpleProxyAssociatedInterface
853 : public IPC::Listener,
854 public IPC::mojom::SimpleTestDriver {
855 public:
856 static const int kNumMessages;
857
Wezfdb98482018-07-12 01:21:39858 explicit ListenerWithSimpleProxyAssociatedInterface(
859 base::OnceClosure quit_closure)
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15860 : quit_closure_(std::move(quit_closure)) {}
rockot8d890f62016-07-14 16:37:14861
Chris Watkins2d879af2017-11-30 02:11:59862 ~ListenerWithSimpleProxyAssociatedInterface() override = default;
rockot8d890f62016-07-14 16:37:14863
864 bool OnMessageReceived(const IPC::Message& message) override {
865 base::PickleIterator iter(message);
rockot9abe09b2016-08-02 20:57:34866 int32_t should_be_expected;
867 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
868 EXPECT_EQ(should_be_expected, next_expected_value_);
rockot8d890f62016-07-14 16:37:14869 num_messages_received_++;
870 return true;
871 }
872
Wezfdb98482018-07-12 01:21:39873 void OnChannelError() override { CHECK(!quit_closure_); }
rockot8d890f62016-07-14 16:37:14874
rockotf62002a2016-09-15 00:08:59875 void OnAssociatedInterfaceRequest(
876 const std::string& interface_name,
877 mojo::ScopedInterfaceEndpointHandle handle) override {
878 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15879 receiver_.Bind(
880 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver>(
881 std::move(handle)));
rockot8d890f62016-07-14 16:37:14882 }
883
884 bool received_all_messages() const {
Wezfdb98482018-07-12 01:21:39885 return num_messages_received_ == kNumMessages && !quit_closure_;
rockot8d890f62016-07-14 16:37:14886 }
887
888 private:
889 // IPC::mojom::SimpleTestDriver:
rockot9abe09b2016-08-02 20:57:34890 void ExpectValue(int32_t value) override {
891 next_expected_value_ = value;
892 }
893
tzikdd76ce712017-06-08 05:27:04894 void GetExpectedValue(GetExpectedValueCallback callback) override {
895 std::move(callback).Run(next_expected_value_);
rockot9abe09b2016-08-02 20:57:34896 }
897
tzikdd76ce712017-06-08 05:27:04898 void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
rockot8d890f62016-07-14 16:37:14899
tzikdd76ce712017-06-08 05:27:04900 void RequestQuit(RequestQuitCallback callback) override {
tzikdd76ce712017-06-08 05:27:04901 std::move(callback).Run();
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15902 receiver_.reset();
Wezfdb98482018-07-12 01:21:39903 std::move(quit_closure_).Run();
rockot8d890f62016-07-14 16:37:14904 }
905
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15906 void BindReceiver(
907 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
908 DCHECK(!receiver_.is_bound());
909 receiver_.Bind(std::move(receiver));
rockot8d890f62016-07-14 16:37:14910 }
911
rockot9abe09b2016-08-02 20:57:34912 int32_t next_expected_value_ = 0;
rockot8d890f62016-07-14 16:37:14913 int num_messages_received_ = 0;
Wezfdb98482018-07-12 01:21:39914 base::OnceClosure quit_closure_;
rockot8d890f62016-07-14 16:37:14915
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15916 mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
rockot8d890f62016-07-14 16:37:14917};
918
919const int ListenerWithSimpleProxyAssociatedInterface::kNumMessages = 1000;
920
921TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:59922 Init("ProxyThreadAssociatedInterfaceClient");
rockot8d890f62016-07-14 16:37:14923
Wezfdb98482018-07-12 01:21:39924 base::RunLoop run_loop;
925 ListenerWithSimpleProxyAssociatedInterface listener(run_loop.QuitClosure());
rockot8d890f62016-07-14 16:37:14926 CreateProxy(&listener);
rockot8d890f62016-07-14 16:37:14927 RunProxy();
928
Wezfdb98482018-07-12 01:21:39929 run_loop.Run();
rockot8d890f62016-07-14 16:37:14930
931 EXPECT_TRUE(WaitForClientShutdown());
932 EXPECT_TRUE(listener.received_all_messages());
933
rockot0e4de5f2016-07-22 21:18:07934 DestroyProxy();
rockot8d890f62016-07-14 16:37:14935}
936
937class ChannelProxyClient {
938 public:
939 void Init(mojo::ScopedMessagePipeHandle handle) {
rockota34707ca2016-07-20 04:28:32940 runner_.reset(new ChannelProxyRunner(std::move(handle), false));
rockot8d890f62016-07-14 16:37:14941 }
rockot9abe09b2016-08-02 20:57:34942
rockot8d890f62016-07-14 16:37:14943 void CreateProxy(IPC::Listener* listener) { runner_->CreateProxy(listener); }
rockot9abe09b2016-08-02 20:57:34944
rockot10188752016-09-08 18:24:56945 void RunProxy() { runner_->RunProxy(); }
rockot9abe09b2016-08-02 20:57:34946
rockot0e4de5f2016-07-22 21:18:07947 void DestroyProxy() {
948 runner_.reset();
949 base::RunLoop().RunUntilIdle();
950 }
rockot8d890f62016-07-14 16:37:14951
rockot9abe09b2016-08-02 20:57:34952 void RequestQuitAndWaitForAck(IPC::mojom::SimpleTestDriver* driver) {
953 base::RunLoop loop;
954 driver->RequestQuit(loop.QuitClosure());
955 loop.Run();
956 }
957
rockot8d890f62016-07-14 16:37:14958 IPC::ChannelProxy* proxy() { return runner_->proxy(); }
959
960 private:
Gabriel Charettec523fa62019-09-09 23:03:32961 base::test::SingleThreadTaskEnvironment task_environment_;
rockot8d890f62016-07-14 16:37:14962 std::unique_ptr<ChannelProxyRunner> runner_;
963};
964
rockot0e4de5f2016-07-22 21:18:07965class DummyListener : public IPC::Listener {
rockot8d890f62016-07-14 16:37:14966 public:
rockot8d890f62016-07-14 16:37:14967 // IPC::Listener
968 bool OnMessageReceived(const IPC::Message& message) override { return true; }
rockot8d890f62016-07-14 16:37:14969};
970
sammc4bcc4ed62016-10-27 10:13:59971DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
972 ProxyThreadAssociatedInterfaceClient,
973 ChannelProxyClient) {
rockot0e4de5f2016-07-22 21:18:07974 DummyListener listener;
rockot8d890f62016-07-14 16:37:14975 CreateProxy(&listener);
976 RunProxy();
rockot8d890f62016-07-14 16:37:14977
978 // Send a bunch of interleaved messages, alternating between the associated
979 // interface and a legacy IPC::Message.
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:15980 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver;
rockot8d890f62016-07-14 16:37:14981 proxy()->GetRemoteAssociatedInterface(&driver);
982 for (int i = 0; i < ListenerWithSimpleProxyAssociatedInterface::kNumMessages;
983 ++i) {
rockot9abe09b2016-08-02 20:57:34984 driver->ExpectValue(i);
985 SendValue(proxy(), i);
rockot8d890f62016-07-14 16:37:14986 }
Wezfdb98482018-07-12 01:21:39987 base::RunLoop run_loop;
988 driver->RequestQuit(run_loop.QuitClosure());
989 run_loop.Run();
rockot0e4de5f2016-07-22 21:18:07990
991 DestroyProxy();
rockot8d890f62016-07-14 16:37:14992}
993
rockot401fb2c2016-09-06 18:35:57994class ListenerWithIndirectProxyAssociatedInterface
995 : public IPC::Listener,
996 public IPC::mojom::IndirectTestDriver,
997 public IPC::mojom::PingReceiver {
998 public:
Julie Jeongeun Kimac82819f2019-11-20 00:01:27999 ListenerWithIndirectProxyAssociatedInterface() = default;
Chris Watkins2d879af2017-11-30 02:11:591000 ~ListenerWithIndirectProxyAssociatedInterface() override = default;
rockot401fb2c2016-09-06 18:35:571001
rockot70bbb59492017-01-25 00:56:511002 // IPC::Listener:
rockot401fb2c2016-09-06 18:35:571003 bool OnMessageReceived(const IPC::Message& message) override { return true; }
1004
rockot70bbb59492017-01-25 00:56:511005 void OnAssociatedInterfaceRequest(
1006 const std::string& interface_name,
1007 mojo::ScopedInterfaceEndpointHandle handle) override {
Julie Jeongeun Kimac82819f2019-11-20 00:01:271008 DCHECK(!driver_receiver_.is_bound());
rockot70bbb59492017-01-25 00:56:511009 DCHECK_EQ(interface_name, IPC::mojom::IndirectTestDriver::Name_);
Julie Jeongeun Kimac82819f2019-11-20 00:01:271010 driver_receiver_.Bind(
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:541011 mojo::PendingAssociatedReceiver<IPC::mojom::IndirectTestDriver>(
1012 std::move(handle)));
rockot401fb2c2016-09-06 18:35:571013 }
1014
Wezfdb98482018-07-12 01:21:391015 void set_ping_handler(const base::RepeatingClosure& handler) {
rockot401fb2c2016-09-06 18:35:571016 ping_handler_ = handler;
1017 }
1018
1019 private:
1020 // IPC::mojom::IndirectTestDriver:
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491021 void GetPingReceiver(mojo::PendingAssociatedReceiver<IPC::mojom::PingReceiver>
1022 receiver) override {
1023 ping_receiver_receiver_.Bind(std::move(receiver));
rockot401fb2c2016-09-06 18:35:571024 }
1025
1026 // IPC::mojom::PingReceiver:
tzikdd76ce712017-06-08 05:27:041027 void Ping(PingCallback callback) override {
1028 std::move(callback).Run();
rockot401fb2c2016-09-06 18:35:571029 ping_handler_.Run();
1030 }
1031
Julie Jeongeun Kimac82819f2019-11-20 00:01:271032 mojo::AssociatedReceiver<IPC::mojom::IndirectTestDriver> driver_receiver_{
1033 this};
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491034 mojo::AssociatedReceiver<IPC::mojom::PingReceiver> ping_receiver_receiver_{
1035 this};
rockot401fb2c2016-09-06 18:35:571036
Wezfdb98482018-07-12 01:21:391037 base::RepeatingClosure ping_handler_;
rockot401fb2c2016-09-06 18:35:571038};
1039
1040TEST_F(IPCChannelProxyMojoTest, ProxyThreadAssociatedInterfaceIndirect) {
1041 // Tests that we can pipeline interface requests and subsequent messages
1042 // targeting proxy thread bindings, and the channel will still dispatch
1043 // messages appropriately.
1044
sammc4bcc4ed62016-10-27 10:13:591045 Init("ProxyThreadAssociatedInterfaceIndirectClient");
rockot401fb2c2016-09-06 18:35:571046
1047 ListenerWithIndirectProxyAssociatedInterface listener;
1048 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:571049 RunProxy();
1050
1051 base::RunLoop loop;
1052 listener.set_ping_handler(loop.QuitClosure());
1053 loop.Run();
1054
1055 EXPECT_TRUE(WaitForClientShutdown());
1056
1057 DestroyProxy();
1058}
1059
sammc4bcc4ed62016-10-27 10:13:591060DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
rockot401fb2c2016-09-06 18:35:571061 ProxyThreadAssociatedInterfaceIndirectClient,
1062 ChannelProxyClient) {
1063 DummyListener listener;
1064 CreateProxy(&listener);
1065 RunProxy();
1066
1067 // Use an interface requested via another interface. On the remote end both
1068 // interfaces are bound on the proxy thread. This ensures that the Ping
1069 // message we send will still be dispatched properly even though the remote
1070 // endpoint may not have been bound yet by the time the message is initially
1071 // processed on the IO thread.
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:541072 mojo::AssociatedRemote<IPC::mojom::IndirectTestDriver> driver;
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491073 mojo::AssociatedRemote<IPC::mojom::PingReceiver> ping_receiver;
rockot401fb2c2016-09-06 18:35:571074 proxy()->GetRemoteAssociatedInterface(&driver);
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491075 driver->GetPingReceiver(ping_receiver.BindNewEndpointAndPassReceiver());
rockot401fb2c2016-09-06 18:35:571076
1077 base::RunLoop loop;
1078 ping_receiver->Ping(loop.QuitClosure());
1079 loop.Run();
1080
1081 DestroyProxy();
1082}
1083
rockot9abe09b2016-08-02 20:57:341084class ListenerWithSyncAssociatedInterface
1085 : public IPC::Listener,
1086 public IPC::mojom::SimpleTestDriver {
1087 public:
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151088 ListenerWithSyncAssociatedInterface() = default;
Chris Watkins2d879af2017-11-30 02:11:591089 ~ListenerWithSyncAssociatedInterface() override = default;
rockot9abe09b2016-08-02 20:57:341090
1091 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1092
rockot9abe09b2016-08-02 20:57:341093 void RunUntilQuitRequested() {
1094 base::RunLoop loop;
1095 quit_closure_ = loop.QuitClosure();
1096 loop.Run();
1097 }
1098
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151099 void CloseBinding() { receiver_.reset(); }
rockot9abe09b2016-08-02 20:57:341100
1101 void set_response_value(int32_t response) {
1102 response_value_ = response;
1103 }
1104
1105 private:
1106 // IPC::mojom::SimpleTestDriver:
1107 void ExpectValue(int32_t value) override {
1108 next_expected_value_ = value;
1109 }
1110
tzikdd76ce712017-06-08 05:27:041111 void GetExpectedValue(GetExpectedValueCallback callback) override {
1112 std::move(callback).Run(next_expected_value_);
rockot9abe09b2016-08-02 20:57:341113 }
1114
tzikdd76ce712017-06-08 05:27:041115 void RequestValue(RequestValueCallback callback) override {
1116 std::move(callback).Run(response_value_);
rockot9abe09b2016-08-02 20:57:341117 }
1118
tzikdd76ce712017-06-08 05:27:041119 void RequestQuit(RequestQuitCallback callback) override {
Wezfdb98482018-07-12 01:21:391120 std::move(quit_closure_).Run();
tzikdd76ce712017-06-08 05:27:041121 std::move(callback).Run();
rockot9abe09b2016-08-02 20:57:341122 }
1123
1124 // IPC::Listener:
1125 bool OnMessageReceived(const IPC::Message& message) override {
1126 EXPECT_EQ(0u, message.type());
1127 EXPECT_TRUE(message.is_sync());
1128 EXPECT_TRUE(message.should_unblock());
1129 std::unique_ptr<IPC::Message> reply(
1130 IPC::SyncMessage::GenerateReply(&message));
1131 reply->WriteInt(response_value_);
1132 DCHECK(sync_sender_);
1133 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1134 return true;
1135 }
1136
rockot70bbb59492017-01-25 00:56:511137 void OnAssociatedInterfaceRequest(
1138 const std::string& interface_name,
1139 mojo::ScopedInterfaceEndpointHandle handle) override {
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151140 DCHECK(!receiver_.is_bound());
rockot70bbb59492017-01-25 00:56:511141 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_);
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151142 receiver_.Bind(
1143 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver>(
1144 std::move(handle)));
rockot70bbb59492017-01-25 00:56:511145 }
1146
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151147 void BindReceiver(
1148 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver) {
1149 DCHECK(!receiver_.is_bound());
1150 receiver_.Bind(std::move(receiver));
rockot9abe09b2016-08-02 20:57:341151 }
1152
1153 IPC::Sender* sync_sender_ = nullptr;
1154 int32_t next_expected_value_ = 0;
1155 int32_t response_value_ = 0;
Wezfdb98482018-07-12 01:21:391156 base::OnceClosure quit_closure_;
rockot9abe09b2016-08-02 20:57:341157
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151158 mojo::AssociatedReceiver<IPC::mojom::SimpleTestDriver> receiver_{this};
rockot9abe09b2016-08-02 20:57:341159};
1160
1161class SyncReplyReader : public IPC::MessageReplyDeserializer {
1162 public:
1163 explicit SyncReplyReader(int32_t* storage) : storage_(storage) {}
Chris Watkins2d879af2017-11-30 02:11:591164 ~SyncReplyReader() override = default;
rockot9abe09b2016-08-02 20:57:341165
1166 private:
1167 // IPC::MessageReplyDeserializer:
1168 bool SerializeOutputParameters(const IPC::Message& message,
1169 base::PickleIterator iter) override {
1170 if (!iter.ReadInt(storage_))
1171 return false;
1172 return true;
1173 }
1174
1175 int32_t* storage_;
1176
1177 DISALLOW_COPY_AND_ASSIGN(SyncReplyReader);
1178};
1179
1180TEST_F(IPCChannelProxyMojoTest, SyncAssociatedInterface) {
sammc4bcc4ed62016-10-27 10:13:591181 Init("SyncAssociatedInterface");
rockot9abe09b2016-08-02 20:57:341182
1183 ListenerWithSyncAssociatedInterface listener;
1184 CreateProxy(&listener);
1185 listener.set_sync_sender(proxy());
rockot9abe09b2016-08-02 20:57:341186 RunProxy();
1187
1188 // Run the client's simple sanity check to completion.
1189 listener.RunUntilQuitRequested();
1190
1191 // Verify that we can send a sync IPC and service an incoming sync request
1192 // while waiting on it
1193 listener.set_response_value(42);
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151194 mojo::AssociatedRemote<IPC::mojom::SimpleTestClient> client;
rockot9abe09b2016-08-02 20:57:341195 proxy()->GetRemoteAssociatedInterface(&client);
1196 int32_t received_value;
1197 EXPECT_TRUE(client->RequestValue(&received_value));
1198 EXPECT_EQ(42, received_value);
1199
1200 // Do it again. This time the client will send a classical sync IPC to us
1201 // while we wait.
1202 received_value = 0;
1203 EXPECT_TRUE(client->RequestValue(&received_value));
1204 EXPECT_EQ(42, received_value);
1205
1206 // Now make a classical sync IPC request to the client. It will send a
1207 // sync associated interface message to us while we wait.
1208 received_value = 0;
1209 std::unique_ptr<IPC::SyncMessage> request(
1210 new IPC::SyncMessage(0, 0, IPC::Message::PRIORITY_NORMAL,
1211 new SyncReplyReader(&received_value)));
1212 EXPECT_TRUE(proxy()->Send(request.release()));
1213 EXPECT_EQ(42, received_value);
1214
1215 listener.CloseBinding();
1216 EXPECT_TRUE(WaitForClientShutdown());
1217
1218 DestroyProxy();
1219}
1220
1221class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
1222 public IPC::Listener {
1223 public:
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151224 SimpleTestClientImpl() = default;
1225 ~SimpleTestClientImpl() override = default;
rockot9abe09b2016-08-02 20:57:341226
1227 void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; }
1228 void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; }
1229
rockot9abe09b2016-08-02 20:57:341230 void WaitForValueRequest() {
1231 run_loop_.reset(new base::RunLoop);
1232 run_loop_->Run();
1233 }
1234
1235 void UseSyncSenderForRequest(bool use_sync_sender) {
1236 use_sync_sender_ = use_sync_sender;
1237 }
1238
1239 private:
1240 // IPC::mojom::SimpleTestClient:
tzikdd76ce712017-06-08 05:27:041241 void RequestValue(RequestValueCallback callback) override {
rockot9abe09b2016-08-02 20:57:341242 int32_t response = 0;
1243 if (use_sync_sender_) {
1244 std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage(
1245 0, 0, IPC::Message::PRIORITY_NORMAL, new SyncReplyReader(&response)));
1246 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1247 } else {
1248 DCHECK(driver_);
1249 EXPECT_TRUE(driver_->RequestValue(&response));
1250 }
1251
tzikdd76ce712017-06-08 05:27:041252 std::move(callback).Run(response);
rockot9abe09b2016-08-02 20:57:341253
1254 DCHECK(run_loop_);
1255 run_loop_->Quit();
1256 }
1257
1258 // IPC::Listener:
1259 bool OnMessageReceived(const IPC::Message& message) override {
1260 int32_t response;
1261 DCHECK(driver_);
1262 EXPECT_TRUE(driver_->RequestValue(&response));
1263 std::unique_ptr<IPC::Message> reply(
1264 IPC::SyncMessage::GenerateReply(&message));
1265 reply->WriteInt(response);
1266 EXPECT_TRUE(sync_sender_->Send(reply.release()));
1267
1268 DCHECK(run_loop_);
1269 run_loop_->Quit();
1270 return true;
1271 }
1272
rockot70bbb59492017-01-25 00:56:511273 void OnAssociatedInterfaceRequest(
1274 const std::string& interface_name,
1275 mojo::ScopedInterfaceEndpointHandle handle) override {
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151276 DCHECK(!receiver_.is_bound());
rockot70bbb59492017-01-25 00:56:511277 DCHECK_EQ(interface_name, IPC::mojom::SimpleTestClient::Name_);
1278
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151279 receiver_.Bind(
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491280 mojo::PendingAssociatedReceiver<IPC::mojom::SimpleTestClient>(
1281 std::move(handle)));
rockot70bbb59492017-01-25 00:56:511282 }
1283
rockot9abe09b2016-08-02 20:57:341284 bool use_sync_sender_ = false;
Julie Jeongeun Kim761a8ff2019-09-27 01:56:491285 mojo::AssociatedReceiver<IPC::mojom::SimpleTestClient> receiver_{this};
rockot9abe09b2016-08-02 20:57:341286 IPC::Sender* sync_sender_ = nullptr;
1287 IPC::mojom::SimpleTestDriver* driver_ = nullptr;
1288 std::unique_ptr<base::RunLoop> run_loop_;
1289
1290 DISALLOW_COPY_AND_ASSIGN(SimpleTestClientImpl);
1291};
1292
sammc4bcc4ed62016-10-27 10:13:591293DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(SyncAssociatedInterface,
1294 ChannelProxyClient) {
rockot9abe09b2016-08-02 20:57:341295 SimpleTestClientImpl client_impl;
1296 CreateProxy(&client_impl);
1297 client_impl.set_sync_sender(proxy());
rockot9abe09b2016-08-02 20:57:341298 RunProxy();
1299
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151300 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> driver;
rockot9abe09b2016-08-02 20:57:341301 proxy()->GetRemoteAssociatedInterface(&driver);
1302 client_impl.set_driver(driver.get());
1303
1304 // Simple sync message sanity check.
1305 driver->ExpectValue(42);
1306 int32_t expected_value = 0;
1307 EXPECT_TRUE(driver->GetExpectedValue(&expected_value));
1308 EXPECT_EQ(42, expected_value);
1309 RequestQuitAndWaitForAck(driver.get());
1310
1311 // Wait for the test driver to perform a sync call test with our own sync
1312 // associated interface message nested inside.
1313 client_impl.UseSyncSenderForRequest(false);
1314 client_impl.WaitForValueRequest();
1315
1316 // Wait for the test driver to perform a sync call test with our own classical
1317 // sync IPC nested inside.
1318 client_impl.UseSyncSenderForRequest(true);
1319 client_impl.WaitForValueRequest();
1320
1321 // Wait for the test driver to perform a classical sync IPC request, with our
1322 // own sync associated interface message nested inside.
1323 client_impl.UseSyncSenderForRequest(false);
1324 client_impl.WaitForValueRequest();
1325
1326 DestroyProxy();
1327}
1328
rockot10188752016-09-08 18:24:561329TEST_F(IPCChannelProxyMojoTest, Pause) {
1330 // Ensures that pausing a channel elicits the expected behavior when sending
1331 // messages, unpausing, sending more messages, and then manually flushing.
1332 // Specifically a sequence like:
rockot401fb2c2016-09-06 18:35:571333 //
1334 // Connect()
1335 // Send(A)
rockot10188752016-09-08 18:24:561336 // Pause()
rockot401fb2c2016-09-06 18:35:571337 // Send(B)
rockot401fb2c2016-09-06 18:35:571338 // Send(C)
rockot10188752016-09-08 18:24:561339 // Unpause(false)
1340 // Send(D)
1341 // Send(E)
rockot401fb2c2016-09-06 18:35:571342 // Flush()
1343 //
rockot10188752016-09-08 18:24:561344 // must result in the other end receiving messages A, D, E, B, D; in that
rockot401fb2c2016-09-06 18:35:571345 // order.
1346 //
1347 // This behavior is required by some consumers of IPC::Channel, and it is not
1348 // sufficient to leave this up to the consumer to implement since associated
1349 // interface requests and messages also need to be queued according to the
1350 // same policy.
sammc4bcc4ed62016-10-27 10:13:591351 Init("CreatePausedClient");
rockot401fb2c2016-09-06 18:35:571352
1353 DummyListener listener;
1354 CreateProxy(&listener);
rockot10188752016-09-08 18:24:561355 RunProxy();
1356
1357 // This message must be sent immediately since the channel is unpaused.
1358 SendValue(proxy(), 1);
1359
1360 proxy()->Pause();
rockot401fb2c2016-09-06 18:35:571361
1362 // These messages must be queued internally since the channel is paused.
rockot401fb2c2016-09-06 18:35:571363 SendValue(proxy(), 2);
rockot10188752016-09-08 18:24:561364 SendValue(proxy(), 3);
rockot401fb2c2016-09-06 18:35:571365
1366 proxy()->Unpause(false /* flush */);
1367
1368 // These messages must be sent immediately since the channel is unpaused.
rockot401fb2c2016-09-06 18:35:571369 SendValue(proxy(), 4);
rockot10188752016-09-08 18:24:561370 SendValue(proxy(), 5);
rockot401fb2c2016-09-06 18:35:571371
1372 // Now we flush the previously queued messages.
1373 proxy()->Flush();
1374
1375 EXPECT_TRUE(WaitForClientShutdown());
1376 DestroyProxy();
1377}
1378
1379class ExpectValueSequenceListener : public IPC::Listener {
1380 public:
Wezfdb98482018-07-12 01:21:391381 ExpectValueSequenceListener(base::queue<int32_t>* expected_values,
1382 base::OnceClosure quit_closure)
1383 : expected_values_(expected_values),
1384 quit_closure_(std::move(quit_closure)) {}
Chris Watkins2d879af2017-11-30 02:11:591385 ~ExpectValueSequenceListener() override = default;
rockot401fb2c2016-09-06 18:35:571386
1387 // IPC::Listener:
1388 bool OnMessageReceived(const IPC::Message& message) override {
1389 DCHECK(!expected_values_->empty());
1390 base::PickleIterator iter(message);
1391 int32_t should_be_expected;
1392 EXPECT_TRUE(iter.ReadInt(&should_be_expected));
1393 EXPECT_EQ(expected_values_->front(), should_be_expected);
1394 expected_values_->pop();
1395 if (expected_values_->empty())
Wezfdb98482018-07-12 01:21:391396 std::move(quit_closure_).Run();
rockot401fb2c2016-09-06 18:35:571397 return true;
1398 }
1399
1400 private:
Brett Wilsona62d9c02017-09-20 20:53:201401 base::queue<int32_t>* expected_values_;
Wezfdb98482018-07-12 01:21:391402 base::OnceClosure quit_closure_;
rockot401fb2c2016-09-06 18:35:571403
1404 DISALLOW_COPY_AND_ASSIGN(ExpectValueSequenceListener);
1405};
1406
sammc4bcc4ed62016-10-27 10:13:591407DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(CreatePausedClient,
1408 ChannelProxyClient) {
Brett Wilsona62d9c02017-09-20 20:53:201409 base::queue<int32_t> expected_values;
Wezfdb98482018-07-12 01:21:391410 base::RunLoop run_loop;
1411 ExpectValueSequenceListener listener(&expected_values,
1412 run_loop.QuitClosure());
rockot401fb2c2016-09-06 18:35:571413 CreateProxy(&listener);
rockot401fb2c2016-09-06 18:35:571414 expected_values.push(1);
rockot10188752016-09-08 18:24:561415 expected_values.push(4);
1416 expected_values.push(5);
rockot401fb2c2016-09-06 18:35:571417 expected_values.push(2);
rockot10188752016-09-08 18:24:561418 expected_values.push(3);
rockot401fb2c2016-09-06 18:35:571419 RunProxy();
Wezfdb98482018-07-12 01:21:391420 run_loop.Run();
rockot401fb2c2016-09-06 18:35:571421 EXPECT_TRUE(expected_values.empty());
1422 DestroyProxy();
1423}
1424
sammc5c8a6c62017-02-04 01:33:381425TEST_F(IPCChannelProxyMojoTest, AssociatedRequestClose) {
1426 Init("DropAssociatedRequest");
1427
1428 DummyListener listener;
1429 CreateProxy(&listener);
1430 RunProxy();
1431
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:541432 mojo::AssociatedRemote<IPC::mojom::AssociatedInterfaceVendor> vendor;
sammc5c8a6c62017-02-04 01:33:381433 proxy()->GetRemoteAssociatedInterface(&vendor);
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151434 mojo::AssociatedRemote<IPC::mojom::SimpleTestDriver> tester;
1435 vendor->GetTestInterface(tester.BindNewEndpointAndPassReceiver());
sammc5c8a6c62017-02-04 01:33:381436 base::RunLoop run_loop;
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151437 tester.set_disconnect_handler(run_loop.QuitClosure());
sammc5c8a6c62017-02-04 01:33:381438 run_loop.Run();
1439
Julie Jeongeun Kim3f9e09e2019-09-26 04:56:151440 tester.reset();
sammc5c8a6c62017-02-04 01:33:381441 proxy()->GetRemoteAssociatedInterface(&tester);
1442 EXPECT_TRUE(WaitForClientShutdown());
1443 DestroyProxy();
1444}
1445
1446class AssociatedInterfaceDroppingListener : public IPC::Listener {
1447 public:
Wezfdb98482018-07-12 01:21:391448 AssociatedInterfaceDroppingListener(base::OnceClosure callback)
1449 : callback_(std::move(callback)) {}
sammc5c8a6c62017-02-04 01:33:381450 bool OnMessageReceived(const IPC::Message& message) override { return false; }
1451
1452 void OnAssociatedInterfaceRequest(
1453 const std::string& interface_name,
1454 mojo::ScopedInterfaceEndpointHandle handle) override {
1455 if (interface_name == IPC::mojom::SimpleTestDriver::Name_)
Wezfdb98482018-07-12 01:21:391456 std::move(callback_).Run();
sammc5c8a6c62017-02-04 01:33:381457 }
1458
1459 private:
Wezfdb98482018-07-12 01:21:391460 base::OnceClosure callback_;
sammc5c8a6c62017-02-04 01:33:381461};
1462
1463DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(DropAssociatedRequest,
1464 ChannelProxyClient) {
1465 base::RunLoop run_loop;
1466 AssociatedInterfaceDroppingListener listener(run_loop.QuitClosure());
1467 CreateProxy(&listener);
1468 RunProxy();
1469 run_loop.Run();
1470 DestroyProxy();
1471}
1472
Wez831ae412017-08-30 00:29:361473#if !defined(OS_MACOSX)
1474// TODO(wez): On Mac we need to set up a MachPortBroker before we can transfer
1475// Mach ports (which underpin Sharedmemory on Mac) across IPC.
1476
1477class ListenerThatExpectsSharedMemory : public TestListenerBase {
1478 public:
Wezfdb98482018-07-12 01:21:391479 ListenerThatExpectsSharedMemory(base::OnceClosure quit_closure)
1480 : TestListenerBase(std::move(quit_closure)) {}
Wez831ae412017-08-30 00:29:361481
1482 bool OnMessageReceived(const IPC::Message& message) override {
1483 base::PickleIterator iter(message);
1484
1485 base::SharedMemoryHandle shared_memory;
1486 EXPECT_TRUE(IPC::ReadParam(&message, &iter, &shared_memory));
1487 EXPECT_TRUE(shared_memory.IsValid());
1488 shared_memory.Close();
1489
1490 ListenerThatExpectsOK::SendOK(sender());
1491 return true;
1492 }
1493};
1494
1495TEST_F(IPCChannelMojoTest, SendSharedMemory) {
1496 Init("IPCChannelMojoTestSendSharedMemoryClient");
1497
1498 // Create some shared-memory to share.
1499 base::SharedMemoryCreateOptions options;
1500 options.size = 1004;
1501
1502 base::SharedMemory shmem;
1503 ASSERT_TRUE(shmem.Create(options));
1504
1505 // Create a success listener, and launch the child process.
1506 base::RunLoop run_loop;
1507 ListenerThatExpectsOK listener(run_loop.QuitClosure());
1508 CreateChannel(&listener);
1509 ASSERT_TRUE(ConnectChannel());
1510
1511 // Send the child process an IPC with |shmem| attached, to verify
1512 // that is is correctly wrapped, transferred and unwrapped.
1513 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
1514 IPC::WriteParam(message, shmem.handle());
1515 ASSERT_TRUE(channel()->Send(message));
1516
1517 run_loop.Run();
1518
1519 channel()->Close();
1520
1521 EXPECT_TRUE(WaitForClientShutdown());
1522 DestroyChannel();
1523}
1524
1525DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendSharedMemoryClient) {
1526 base::RunLoop run_loop;
1527 ListenerThatExpectsSharedMemory listener(run_loop.QuitClosure());
1528 Connect(&listener);
1529 listener.set_sender(channel());
1530
1531 run_loop.Run();
1532
1533 Close();
1534}
1535
Alexandr Ilind497eee2018-04-19 22:50:541536template <class SharedMemoryRegionType>
1537class IPCChannelMojoSharedMemoryRegionTypedTest : public IPCChannelMojoTest {};
1538
1539struct WritableRegionTraits {
1540 using RegionType = base::WritableSharedMemoryRegion;
1541 static const char kClientName[];
1542};
1543const char WritableRegionTraits::kClientName[] =
1544 "IPCChannelMojoTestSendWritableSharedMemoryRegionClient";
1545struct UnsafeRegionTraits {
1546 using RegionType = base::UnsafeSharedMemoryRegion;
1547 static const char kClientName[];
1548};
1549const char UnsafeRegionTraits::kClientName[] =
1550 "IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient";
1551struct ReadOnlyRegionTraits {
1552 using RegionType = base::ReadOnlySharedMemoryRegion;
1553 static const char kClientName[];
1554};
1555const char ReadOnlyRegionTraits::kClientName[] =
1556 "IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient";
1557
1558typedef ::testing::
1559 Types<WritableRegionTraits, UnsafeRegionTraits, ReadOnlyRegionTraits>
1560 AllSharedMemoryRegionTraits;
Victor Costanebc52732019-02-15 02:39:471561TYPED_TEST_SUITE(IPCChannelMojoSharedMemoryRegionTypedTest,
1562 AllSharedMemoryRegionTraits);
Alexandr Ilind497eee2018-04-19 22:50:541563
1564template <class SharedMemoryRegionType>
1565class ListenerThatExpectsSharedMemoryRegion : public TestListenerBase {
1566 public:
Wezfdb98482018-07-12 01:21:391567 explicit ListenerThatExpectsSharedMemoryRegion(base::OnceClosure quit_closure)
Alexandr Ilind497eee2018-04-19 22:50:541568 : TestListenerBase(std::move(quit_closure)) {}
1569
1570 bool OnMessageReceived(const IPC::Message& message) override {
1571 base::PickleIterator iter(message);
1572
1573 SharedMemoryRegionType region;
1574 EXPECT_TRUE(IPC::ReadParam(&message, &iter, &region));
1575 EXPECT_TRUE(region.IsValid());
1576
1577 // Verify the shared memory region has expected content.
1578 typename SharedMemoryRegionType::MappingType mapping = region.Map();
1579 std::string content = HandleSendingHelper::GetSendingFileContent();
1580 EXPECT_EQ(0, memcmp(mapping.memory(), content.data(), content.size()));
1581
1582 ListenerThatExpectsOK::SendOK(sender());
1583 return true;
1584 }
1585};
1586
1587TYPED_TEST(IPCChannelMojoSharedMemoryRegionTypedTest, Send) {
1588 this->Init(TypeParam::kClientName);
1589
1590 const size_t size = 1004;
1591 typename TypeParam::RegionType region;
1592 base::WritableSharedMemoryMapping mapping;
1593 std::tie(region, mapping) =
1594 base::CreateMappedRegion<typename TypeParam::RegionType>(size);
1595
1596 std::string content = HandleSendingHelper::GetSendingFileContent();
1597 memcpy(mapping.memory(), content.data(), content.size());
1598
1599 // Create a success listener, and launch the child process.
1600 base::RunLoop run_loop;
1601 ListenerThatExpectsOK listener(run_loop.QuitClosure());
1602 this->CreateChannel(&listener);
1603 ASSERT_TRUE(this->ConnectChannel());
1604
1605 // Send the child process an IPC with |shmem| attached, to verify
1606 // that is is correctly wrapped, transferred and unwrapped.
1607 IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
1608 IPC::WriteParam(message, region);
1609 ASSERT_TRUE(this->channel()->Send(message));
1610
1611 run_loop.Run();
1612
1613 this->channel()->Close();
1614
1615 EXPECT_TRUE(this->WaitForClientShutdown());
1616 EXPECT_FALSE(region.IsValid());
1617 this->DestroyChannel();
1618}
1619
1620DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1621 IPCChannelMojoTestSendWritableSharedMemoryRegionClient) {
1622 base::RunLoop run_loop;
1623 ListenerThatExpectsSharedMemoryRegion<base::WritableSharedMemoryRegion>
1624 listener(run_loop.QuitClosure());
1625 Connect(&listener);
1626 listener.set_sender(channel());
1627
1628 run_loop.Run();
1629
1630 Close();
1631}
1632DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1633 IPCChannelMojoTestSendUnsafeSharedMemoryRegionClient) {
1634 base::RunLoop run_loop;
1635 ListenerThatExpectsSharedMemoryRegion<base::UnsafeSharedMemoryRegion>
1636 listener(run_loop.QuitClosure());
1637 Connect(&listener);
1638 listener.set_sender(channel());
1639
1640 run_loop.Run();
1641
1642 Close();
1643}
1644DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
1645 IPCChannelMojoTestSendReadOnlySharedMemoryRegionClient) {
1646 base::RunLoop run_loop;
1647 ListenerThatExpectsSharedMemoryRegion<base::ReadOnlySharedMemoryRegion>
1648 listener(run_loop.QuitClosure());
1649 Connect(&listener);
1650 listener.set_sender(channel());
1651
1652 run_loop.Run();
1653
1654 Close();
1655}
Wez831ae412017-08-30 00:29:361656#endif // !defined(OS_MACOSX)
1657
Fabrice de Gans-Riberi894661c2018-05-24 18:43:221658#if defined(OS_POSIX) || defined(OS_FUCHSIA)
rockot8d890f62016-07-14 16:37:141659
Wez831ae412017-08-30 00:29:361660class ListenerThatExpectsFile : public TestListenerBase {
[email protected]64860882014-08-04 23:44:171661 public:
Wezfdb98482018-07-12 01:21:391662 explicit ListenerThatExpectsFile(base::OnceClosure quit_closure)
1663 : TestListenerBase(std::move(quit_closure)) {}
[email protected]64860882014-08-04 23:44:171664
dchengfe61fca2014-10-22 02:29:521665 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251666 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301667 HandleSendingHelper::ReadReceivedFile(message, &iter);
Wez831ae412017-08-30 00:29:361668 ListenerThatExpectsOK::SendOK(sender());
[email protected]64860882014-08-04 23:44:171669 return true;
1670 }
[email protected]64860882014-08-04 23:44:171671};
1672
Wez831ae412017-08-30 00:29:361673TEST_F(IPCChannelMojoTest, SendPlatformFile) {
1674 Init("IPCChannelMojoTestSendPlatformFileClient");
[email protected]64860882014-08-04 23:44:171675
Wez831ae412017-08-30 00:29:361676 base::RunLoop run_loop;
1677 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita373af03b2014-09-09 19:35:241678 CreateChannel(&listener);
[email protected]64860882014-08-04 23:44:171679 ASSERT_TRUE(ConnectChannel());
[email protected]64860882014-08-04 23:44:171680
amistry20e2b1d62016-06-23 06:12:351681 base::ScopedTempDir temp_dir;
1682 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001683 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
[email protected]64860882014-08-04 23:44:171684 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
morrita81b17e02015-02-06 00:58:301685 base::File::FLAG_READ);
1686 HandleSendingHelper::WriteFileThenSend(channel(), file);
Wez831ae412017-08-30 00:29:361687 run_loop.Run();
[email protected]64860882014-08-04 23:44:171688
sammc57ed9f982016-03-10 06:28:351689 channel()->Close();
[email protected]64860882014-08-04 23:44:171690
1691 EXPECT_TRUE(WaitForClientShutdown());
1692 DestroyChannel();
1693}
1694
Wez831ae412017-08-30 00:29:361695DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformFileClient) {
1696 base::RunLoop run_loop;
1697 ListenerThatExpectsFile listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351698 Connect(&listener);
1699 listener.set_sender(channel());
[email protected]64860882014-08-04 23:44:171700
Wez831ae412017-08-30 00:29:361701 run_loop.Run();
[email protected]64860882014-08-04 23:44:171702
sammc57ed9f982016-03-10 06:28:351703 Close();
[email protected]64860882014-08-04 23:44:171704}
morrita81b17e02015-02-06 00:58:301705
Wez831ae412017-08-30 00:29:361706class ListenerThatExpectsFileAndMessagePipe : public TestListenerBase {
morrita81b17e02015-02-06 00:58:301707 public:
Wezfdb98482018-07-12 01:21:391708 explicit ListenerThatExpectsFileAndMessagePipe(base::OnceClosure quit_closure)
1709 : TestListenerBase(std::move(quit_closure)) {}
morrita81b17e02015-02-06 00:58:301710
Chris Watkins2d879af2017-11-30 02:11:591711 ~ListenerThatExpectsFileAndMessagePipe() override = default;
morrita81b17e02015-02-06 00:58:301712
1713 bool OnMessageReceived(const IPC::Message& message) override {
brettwbd4d7112015-06-03 04:29:251714 base::PickleIterator iter(message);
morrita81b17e02015-02-06 00:58:301715 HandleSendingHelper::ReadReceivedFile(message, &iter);
1716 HandleSendingHelper::ReadReceivedPipe(message, &iter);
Wez831ae412017-08-30 00:29:361717 ListenerThatExpectsOK::SendOK(sender());
morrita81b17e02015-02-06 00:58:301718 return true;
1719 }
morrita81b17e02015-02-06 00:58:301720};
1721
Wez831ae412017-08-30 00:29:361722TEST_F(IPCChannelMojoTest, SendPlatformFileAndMessagePipe) {
1723 Init("IPCChannelMojoTestSendPlatformFileAndMessagePipeClient");
morrita81b17e02015-02-06 00:58:301724
Wez831ae412017-08-30 00:29:361725 base::RunLoop run_loop;
1726 ListenerThatExpectsOK listener(run_loop.QuitClosure());
morrita81b17e02015-02-06 00:58:301727 CreateChannel(&listener);
1728 ASSERT_TRUE(ConnectChannel());
morrita81b17e02015-02-06 00:58:301729
amistry20e2b1d62016-06-23 06:12:351730 base::ScopedTempDir temp_dir;
1731 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
vabr16e5f602016-09-15 18:14:001732 base::File file(HandleSendingHelper::GetSendingFilePath(temp_dir.GetPath()),
morrita81b17e02015-02-06 00:58:301733 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
1734 base::File::FLAG_READ);
1735 TestingMessagePipe pipe;
1736 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
1737
Wez831ae412017-08-30 00:29:361738 run_loop.Run();
sammc57ed9f982016-03-10 06:28:351739 channel()->Close();
morrita81b17e02015-02-06 00:58:301740
1741 EXPECT_TRUE(WaitForClientShutdown());
1742 DestroyChannel();
1743}
1744
sammc57ed9f982016-03-10 06:28:351745DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
Wez831ae412017-08-30 00:29:361746 IPCChannelMojoTestSendPlatformFileAndMessagePipeClient) {
1747 base::RunLoop run_loop;
1748 ListenerThatExpectsFileAndMessagePipe listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351749 Connect(&listener);
1750 listener.set_sender(channel());
morrita81b17e02015-02-06 00:58:301751
Wez831ae412017-08-30 00:29:361752 run_loop.Run();
morrita81b17e02015-02-06 00:58:301753
sammc57ed9f982016-03-10 06:28:351754 Close();
morrita81b17e02015-02-06 00:58:301755}
1756
Fabrice de Gans-Riberi894661c2018-05-24 18:43:221757#endif // defined(OS_POSIX) || defined(OS_FUCHSIA)
[email protected]64860882014-08-04 23:44:171758
morrita0bd20bd2015-02-25 20:11:271759#if defined(OS_LINUX)
1760
1761const base::ProcessId kMagicChildId = 54321;
1762
Wez831ae412017-08-30 00:29:361763class ListenerThatVerifiesPeerPid : public TestListenerBase {
morrita0bd20bd2015-02-25 20:11:271764 public:
Wezfdb98482018-07-12 01:21:391765 explicit ListenerThatVerifiesPeerPid(base::OnceClosure quit_closure)
1766 : TestListenerBase(std::move(quit_closure)) {}
Wez831ae412017-08-30 00:29:361767
tfarina10a5c062015-09-04 18:47:571768 void OnChannelConnected(int32_t peer_pid) override {
morrita0bd20bd2015-02-25 20:11:271769 EXPECT_EQ(peer_pid, kMagicChildId);
Wezfdb98482018-07-12 01:21:391770 RunQuitClosure();
morrita0bd20bd2015-02-25 20:11:271771 }
1772
1773 bool OnMessageReceived(const IPC::Message& message) override {
1774 NOTREACHED();
1775 return true;
1776 }
1777};
1778
sammc57ed9f982016-03-10 06:28:351779TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
sammc4bcc4ed62016-10-27 10:13:591780 Init("IPCChannelMojoTestVerifyGlobalPidClient");
morrita0bd20bd2015-02-25 20:11:271781
Wez831ae412017-08-30 00:29:361782 base::RunLoop run_loop;
1783 ListenerThatVerifiesPeerPid listener(run_loop.QuitClosure());
morrita0bd20bd2015-02-25 20:11:271784 CreateChannel(&listener);
1785 ASSERT_TRUE(ConnectChannel());
morrita0bd20bd2015-02-25 20:11:271786
Wez831ae412017-08-30 00:29:361787 run_loop.Run();
rockotcbca72f2015-03-03 16:31:041788 channel()->Close();
morrita0bd20bd2015-02-25 20:11:271789
1790 EXPECT_TRUE(WaitForClientShutdown());
1791 DestroyChannel();
1792}
1793
sammc4bcc4ed62016-10-27 10:13:591794DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient) {
morrita0bd20bd2015-02-25 20:11:271795 IPC::Channel::SetGlobalPid(kMagicChildId);
Wez831ae412017-08-30 00:29:361796
1797 base::RunLoop run_loop;
1798 ListenerThatQuits listener(run_loop.QuitClosure());
sammc57ed9f982016-03-10 06:28:351799 Connect(&listener);
morrita0bd20bd2015-02-25 20:11:271800
Wez831ae412017-08-30 00:29:361801 run_loop.Run();
morrita0bd20bd2015-02-25 20:11:271802
sammc57ed9f982016-03-10 06:28:351803 Close();
morrita0bd20bd2015-02-25 20:11:271804}
1805
sammc57ed9f982016-03-10 06:28:351806#endif // OS_LINUX
morrita0bd20bd2015-02-25 20:11:271807
[email protected]64860882014-08-04 23:44:171808} // namespace