blob: 4a8ca8f34fc938369fb86b8557ad655d461d23bb [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_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
[email protected]64860882014-08-04 23:44:1711#include "base/bind.h"
12#include "base/bind_helpers.h"
13#include "base/location.h"
14#include "base/logging.h"
rockot506f92fa22016-03-23 01:32:1815#include "base/macros.h"
skyostile687bdff2015-05-12 11:29:2116#include "base/single_thread_task_runner.h"
gabf08ccc02016-05-11 18:51:1117#include "base/threading/thread_task_runner_handle.h"
amistryd4aa70d2016-06-23 07:52:3718#include "ipc/ipc_channel_mojo.h"
rockot506f92fa22016-03-23 01:32:1819#include "mojo/public/cpp/bindings/message.h"
[email protected]64860882014-08-04 23:44:1720
21namespace IPC {
22namespace internal {
23
sammce4d0abd2016-03-07 22:38:0424MessagePipeReader::MessagePipeReader(
rockot506f92fa22016-03-23 01:32:1825 mojo::MessagePipeHandle pipe,
sammce4d0abd2016-03-07 22:38:0426 mojom::ChannelAssociatedPtr sender,
27 mojo::AssociatedInterfaceRequest<mojom::Channel> receiver,
28 MessagePipeReader::Delegate* delegate)
29 : delegate_(delegate),
30 sender_(std::move(sender)),
rockot401fb2c2016-09-06 18:35:5731 binding_(this, std::move(receiver)) {
sammce4d0abd2016-03-07 22:38:0432 sender_.set_connection_error_handler(
33 base::Bind(&MessagePipeReader::OnPipeError, base::Unretained(this),
34 MOJO_RESULT_FAILED_PRECONDITION));
35 binding_.set_connection_error_handler(
36 base::Bind(&MessagePipeReader::OnPipeError, base::Unretained(this),
37 MOJO_RESULT_FAILED_PRECONDITION));
38}
[email protected]64860882014-08-04 23:44:1739
40MessagePipeReader::~MessagePipeReader() {
amistry0b0e7482015-09-02 18:04:2241 DCHECK(thread_checker_.CalledOnValidThread());
morritab4472142015-04-20 21:20:1242 // The pipe should be closed before deletion.
[email protected]64860882014-08-04 23:44:1743}
44
45void MessagePipeReader::Close() {
amistry0b0e7482015-09-02 18:04:2246 DCHECK(thread_checker_.CalledOnValidThread());
sammce4d0abd2016-03-07 22:38:0447 sender_.reset();
48 if (binding_.is_bound())
49 binding_.Close();
morritab4472142015-04-20 21:20:1250}
51
danakj03de39b22016-04-23 04:21:0952bool MessagePipeReader::Send(std::unique_ptr<Message> message) {
Roman Karaseva43d5b4e2017-12-21 03:06:0253 CHECK(message->IsValid());
yuhaoz9b8157d2015-08-18 22:21:3554 TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
Roman Karaseva43d5b4e2017-12-21 03:06:0255 "MessagePipeReader::Send", message->flags(),
yuhaoz9b8157d2015-08-18 22:21:3556 TRACE_EVENT_FLAG_FLOW_OUT);
Eve Martin-Jones475e7e62018-02-13 22:57:2557 base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles;
morritad68bedf42014-11-25 23:35:5758 MojoResult result = MOJO_RESULT_OK;
rockot9691a7b2016-03-18 18:58:1559 result = ChannelMojo::ReadFromMessageAttachmentSet(message.get(), &handles);
rockot506f92fa22016-03-23 01:32:1860 if (result != MOJO_RESULT_OK)
morritad68bedf42014-11-25 23:35:5761 return false;
rockot506f92fa22016-03-23 01:32:1862
rockot401fb2c2016-09-06 18:35:5763 if (!sender_)
64 return false;
rockot506f92fa22016-03-23 01:32:1865
Alice Boxhallb0cfd1d2018-07-11 03:37:3766 sender_->Receive(base::make_span(static_cast<const uint8_t*>(message->data()),
67 message->size()),
68 std::move(handles));
69
sammce4d0abd2016-03-07 22:38:0470 DVLOG(4) << "Send " << message->type() << ": " << message->size();
rockot401fb2c2016-09-06 18:35:5771 return true;
morritad68bedf42014-11-25 23:35:5772}
73
rockot7c6bf952016-07-14 00:34:1174void MessagePipeReader::GetRemoteInterface(
75 const std::string& name,
76 mojo::ScopedInterfaceEndpointHandle handle) {
rockot5a908952016-07-28 20:08:1777 if (!sender_.is_bound())
78 return;
Ken Rockot96d1b7b52017-05-13 00:29:2179 sender_->GetAssociatedInterface(
80 name, mojom::GenericInterfaceAssociatedRequest(std::move(handle)));
rockot7c6bf952016-07-14 00:34:1181}
82
rockot0e4de5f2016-07-22 21:18:0783void MessagePipeReader::SetPeerPid(int32_t peer_pid) {
sammcf810f07f2016-11-10 22:34:0784 delegate_->OnPeerPidReceived(peer_pid);
rockot0e4de5f2016-07-22 21:18:0785}
86
Alice Boxhallb0cfd1d2018-07-11 03:37:3787void MessagePipeReader::Receive(
88 base::span<const uint8_t> data,
89 base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles) {
90 if (data.empty()) {
Roman Karaseva43d5b4e2017-12-21 03:06:0291 delegate_->OnBrokenDataReceived();
92 return;
93 }
Alice Boxhallb0cfd1d2018-07-11 03:37:3794 Message message(reinterpret_cast<const char*>(data.data()),
95 static_cast<uint32_t>(data.size()));
Roman Karaseva43d5b4e2017-12-21 03:06:0296 if (!message.IsValid()) {
97 delegate_->OnBrokenDataReceived();
98 return;
99 }
morritad68bedf42014-11-25 23:35:57100
sammce4d0abd2016-03-07 22:38:04101 DVLOG(4) << "Receive " << message.type() << ": " << message.size();
Alice Boxhallb0cfd1d2018-07-11 03:37:37102 MojoResult write_result =
103 ChannelMojo::WriteToMessageAttachmentSet(std::move(handles), &message);
morritad68bedf42014-11-25 23:35:57104 if (write_result != MOJO_RESULT_OK) {
rockot506f92fa22016-03-23 01:32:18105 OnPipeError(write_result);
morritad68bedf42014-11-25 23:35:57106 return;
107 }
morritad68bedf42014-11-25 23:35:57108
yuhaoz9b8157d2015-08-18 22:21:35109 TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
rockot506f92fa22016-03-23 01:32:18110 "MessagePipeReader::Receive",
yuhaoz9b8157d2015-08-18 22:21:35111 message.flags(),
112 TRACE_EVENT_FLAG_FLOW_IN);
morritad68bedf42014-11-25 23:35:57113 delegate_->OnMessageReceived(message);
[email protected]64860882014-08-04 23:44:17114}
115
rockot7c6bf952016-07-14 00:34:11116void MessagePipeReader::GetAssociatedInterface(
yzshen24b40a32016-08-24 01:10:13117 const std::string& name,
rockot7c6bf952016-07-14 00:34:11118 mojom::GenericInterfaceAssociatedRequest request) {
119 DCHECK(thread_checker_.CalledOnValidThread());
120 if (delegate_)
121 delegate_->OnAssociatedInterfaceRequest(name, request.PassHandle());
122}
123
morritad68bedf42014-11-25 23:35:57124void MessagePipeReader::OnPipeError(MojoResult error) {
amistry0b0e7482015-09-02 18:04:22125 DCHECK(thread_checker_.CalledOnValidThread());
rockot0e4de5f2016-07-22 21:18:07126
127 Close();
128
129 // NOTE: The delegate call below may delete |this|.
sammce4d0abd2016-03-07 22:38:04130 if (delegate_)
rockot506f92fa22016-03-23 01:32:18131 delegate_->OnPipeError();
[email protected]64860882014-08-04 23:44:17132}
133
134} // namespace internal
135} // namespace IPC