blob: 7f30d677ab205ecd0b6ffccdf35696b449c50271 [file] [log] [blame]
Avi Drissmanea1be232022-09-14 23:29:061// Copyright 2014 The Chromium Authors
[email protected]64860882014-08-04 23:44:172// 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_message_pipe_reader.h"
[email protected]64860882014-08-04 23:44:176
tfarina10a5c062015-09-04 18:47:577#include <stdint.h>
rockot506f92fa22016-03-23 01:32:188
dchenge48600452015-12-28 02:24:509#include <utility>
tfarina10a5c062015-09-04 18:47:5710
Ken Rockot85bd7c82021-03-04 23:38:1311#include "base/containers/span.h"
Avi Drissmancac43f22023-01-12 00:58:4112#include "base/functional/bind.h"
13#include "base/functional/callback_helpers.h"
[email protected]64860882014-08-04 23:44:1714#include "base/location.h"
15#include "base/logging.h"
Ali Hijazi55179192022-11-09 16:28:5116#include "base/memory/raw_ref.h"
Sean Mahere672a662023-01-09 21:42:2817#include "base/task/sequenced_task_runner.h"
Patrick Monette643cdf62021-10-15 19:13:4218#include "base/task/single_thread_task_runner.h"
Hans Wennborg5f62968b2021-04-22 18:44:0519#include "base/trace_event/trace_event.h"
amistryd4aa70d2016-06-23 07:52:3720#include "ipc/ipc_channel_mojo.h"
rockot506f92fa22016-03-23 01:32:1821#include "mojo/public/cpp/bindings/message.h"
Ken Rockotfbbd4442021-06-04 01:19:1422#include "mojo/public/cpp/bindings/thread_safe_proxy.h"
[email protected]64860882014-08-04 23:44:1723
24namespace IPC {
25namespace internal {
26
Ken Rockotfbbd4442021-06-04 01:19:1427namespace {
28
29class ThreadSafeProxy : public mojo::ThreadSafeProxy {
30 public:
31 using Forwarder = base::RepeatingCallback<void(mojo::Message)>;
32
33 ThreadSafeProxy(scoped_refptr<base::SequencedTaskRunner> task_runner,
34 Forwarder forwarder,
35 mojo::AssociatedGroupController& group_controller)
36 : task_runner_(std::move(task_runner)),
37 forwarder_(std::move(forwarder)),
38 group_controller_(group_controller) {}
39
40 // mojo::ThreadSafeProxy:
41 void SendMessage(mojo::Message& message) override {
Ali Hijazi55179192022-11-09 16:28:5142 message.SerializeHandles(&*group_controller_);
Ken Rockotfbbd4442021-06-04 01:19:1443 task_runner_->PostTask(FROM_HERE,
44 base::BindOnce(forwarder_, std::move(message)));
45 }
46
47 void SendMessageWithResponder(
48 mojo::Message& message,
49 std::unique_ptr<mojo::MessageReceiver> responder) override {
50 // We don't bother supporting this because it's not used in practice.
51 NOTREACHED();
52 }
53
54 private:
55 ~ThreadSafeProxy() override = default;
56
57 const scoped_refptr<base::SequencedTaskRunner> task_runner_;
58 const Forwarder forwarder_;
Ali Hijazi55179192022-11-09 16:28:5159 const raw_ref<mojo::AssociatedGroupController> group_controller_;
Ken Rockotfbbd4442021-06-04 01:19:1460};
61
62} // namespace
63
sammce4d0abd2016-03-07 22:38:0464MessagePipeReader::MessagePipeReader(
rockot506f92fa22016-03-23 01:32:1865 mojo::MessagePipeHandle pipe,
Ken Rockotfbbd4442021-06-04 01:19:1466 mojo::PendingAssociatedRemote<mojom::Channel> sender,
Julie Jeongeun Kim903b34b2019-09-25 11:11:5467 mojo::PendingAssociatedReceiver<mojom::Channel> receiver,
Ken Rockotfbbd4442021-06-04 01:19:1468 scoped_refptr<base::SequencedTaskRunner> task_runner,
sammce4d0abd2016-03-07 22:38:0469 MessagePipeReader::Delegate* delegate)
70 : delegate_(delegate),
Ken Rockotfbbd4442021-06-04 01:19:1471 sender_(std::move(sender), task_runner),
72 receiver_(this, std::move(receiver), task_runner) {
73 thread_safe_sender_ =
74 std::make_unique<mojo::ThreadSafeForwarder<mojom::Channel>>(
75 base::MakeRefCounted<ThreadSafeProxy>(
76 task_runner,
77 base::BindRepeating(&MessagePipeReader::ForwardMessage,
78 weak_ptr_factory_.GetWeakPtr()),
79 *sender_.internal_state()->associated_group()->GetController()));
80
81 thread_checker_.DetachFromThread();
82}
83
84MessagePipeReader::~MessagePipeReader() {
85 DCHECK(thread_checker_.CalledOnValidThread());
86 // The pipe should be closed before deletion.
87}
88
89void MessagePipeReader::FinishInitializationOnIOThread(
90 base::ProcessId self_pid) {
Jan Wilken Dörrie0825fc3e2020-04-21 20:24:3491 sender_.set_disconnect_handler(
92 base::BindOnce(&MessagePipeReader::OnPipeError, base::Unretained(this),
93 MOJO_RESULT_FAILED_PRECONDITION));
94 receiver_.set_disconnect_handler(
95 base::BindOnce(&MessagePipeReader::OnPipeError, base::Unretained(this),
96 MOJO_RESULT_FAILED_PRECONDITION));
[email protected]64860882014-08-04 23:44:1797
Ken Rockotfbbd4442021-06-04 01:19:1498 sender_->SetPeerPid(self_pid);
[email protected]64860882014-08-04 23:44:1799}
100
101void MessagePipeReader::Close() {
amistry0b0e7482015-09-02 18:04:22102 DCHECK(thread_checker_.CalledOnValidThread());
sammce4d0abd2016-03-07 22:38:04103 sender_.reset();
Julie Jeongeun Kim903b34b2019-09-25 11:11:54104 if (receiver_.is_bound())
105 receiver_.reset();
morritab4472142015-04-20 21:20:12106}
107
danakj03de39b22016-04-23 04:21:09108bool MessagePipeReader::Send(std::unique_ptr<Message> message) {
Roman Karaseva43d5b4e2017-12-21 03:06:02109 CHECK(message->IsValid());
Alexander Timin2432c7312020-05-20 13:28:03110 TRACE_EVENT_WITH_FLOW0("toplevel.flow", "MessagePipeReader::Send",
111 message->flags(), TRACE_EVENT_FLAG_FLOW_OUT);
Anton Bikineev1f42a452021-05-15 18:02:50112 absl::optional<std::vector<mojo::native::SerializedHandlePtr>> handles;
morritad68bedf42014-11-25 23:35:57113 MojoResult result = MOJO_RESULT_OK;
rockot9691a7b2016-03-18 18:58:15114 result = ChannelMojo::ReadFromMessageAttachmentSet(message.get(), &handles);
rockot506f92fa22016-03-23 01:32:18115 if (result != MOJO_RESULT_OK)
morritad68bedf42014-11-25 23:35:57116 return false;
rockot506f92fa22016-03-23 01:32:18117
rockot401fb2c2016-09-06 18:35:57118 if (!sender_)
119 return false;
rockot506f92fa22016-03-23 01:32:18120
Ken Rockot85bd7c82021-03-04 23:38:13121 base::span<const uint8_t> bytes(static_cast<const uint8_t*>(message->data()),
122 message->size());
123 sender_->Receive(MessageView(bytes, std::move(handles)));
sammce4d0abd2016-03-07 22:38:04124 DVLOG(4) << "Send " << message->type() << ": " << message->size();
rockot401fb2c2016-09-06 18:35:57125 return true;
morritad68bedf42014-11-25 23:35:57126}
127
rockot7c6bf952016-07-14 00:34:11128void MessagePipeReader::GetRemoteInterface(
Ken Rockot493a59f32021-06-04 22:16:50129 mojo::GenericPendingAssociatedReceiver receiver) {
rockot5a908952016-07-28 20:08:17130 if (!sender_.is_bound())
131 return;
Ken Rockot493a59f32021-06-04 22:16:50132 sender_->GetAssociatedInterface(std::move(receiver));
rockot7c6bf952016-07-14 00:34:11133}
134
rockot0e4de5f2016-07-22 21:18:07135void MessagePipeReader::SetPeerPid(int32_t peer_pid) {
sammcf810f07f2016-11-10 22:34:07136 delegate_->OnPeerPidReceived(peer_pid);
rockot0e4de5f2016-07-22 21:18:07137}
138
Ken Rockot4c5bd802018-07-12 01:37:11139void MessagePipeReader::Receive(MessageView message_view) {
Ken Rockot85bd7c82021-03-04 23:38:13140 if (message_view.bytes().empty()) {
Roman Karaseva43d5b4e2017-12-21 03:06:02141 delegate_->OnBrokenDataReceived();
142 return;
143 }
Ken Rockot85bd7c82021-03-04 23:38:13144 Message message(reinterpret_cast<const char*>(message_view.bytes().data()),
145 message_view.bytes().size());
Roman Karaseva43d5b4e2017-12-21 03:06:02146 if (!message.IsValid()) {
147 delegate_->OnBrokenDataReceived();
148 return;
149 }
morritad68bedf42014-11-25 23:35:57150
sammce4d0abd2016-03-07 22:38:04151 DVLOG(4) << "Receive " << message.type() << ": " << message.size();
Ken Rockot4c5bd802018-07-12 01:37:11152 MojoResult write_result = ChannelMojo::WriteToMessageAttachmentSet(
153 message_view.TakeHandles(), &message);
morritad68bedf42014-11-25 23:35:57154 if (write_result != MOJO_RESULT_OK) {
rockot506f92fa22016-03-23 01:32:18155 OnPipeError(write_result);
morritad68bedf42014-11-25 23:35:57156 return;
157 }
morritad68bedf42014-11-25 23:35:57158
Alexander Timin2432c7312020-05-20 13:28:03159 TRACE_EVENT_WITH_FLOW0("toplevel.flow", "MessagePipeReader::Receive",
160 message.flags(), TRACE_EVENT_FLAG_FLOW_IN);
morritad68bedf42014-11-25 23:35:57161 delegate_->OnMessageReceived(message);
[email protected]64860882014-08-04 23:44:17162}
163
rockot7c6bf952016-07-14 00:34:11164void MessagePipeReader::GetAssociatedInterface(
Ken Rockot493a59f32021-06-04 22:16:50165 mojo::GenericPendingAssociatedReceiver receiver) {
rockot7c6bf952016-07-14 00:34:11166 DCHECK(thread_checker_.CalledOnValidThread());
167 if (delegate_)
Ken Rockot493a59f32021-06-04 22:16:50168 delegate_->OnAssociatedInterfaceRequest(std::move(receiver));
rockot7c6bf952016-07-14 00:34:11169}
170
morritad68bedf42014-11-25 23:35:57171void MessagePipeReader::OnPipeError(MojoResult error) {
amistry0b0e7482015-09-02 18:04:22172 DCHECK(thread_checker_.CalledOnValidThread());
rockot0e4de5f2016-07-22 21:18:07173
174 Close();
175
176 // NOTE: The delegate call below may delete |this|.
sammce4d0abd2016-03-07 22:38:04177 if (delegate_)
rockot506f92fa22016-03-23 01:32:18178 delegate_->OnPipeError();
[email protected]64860882014-08-04 23:44:17179}
180
Ken Rockotfbbd4442021-06-04 01:19:14181void MessagePipeReader::ForwardMessage(mojo::Message message) {
182 sender_.internal_state()->ForwardMessage(std::move(message));
183}
184
[email protected]64860882014-08-04 23:44:17185} // namespace internal
186} // namespace IPC