blob: ebc18a3a943d0aaf95809f4a69bd523641bb55a0 [file] [log] [blame]
morrita@chromium.org15996aa2014-08-05 08:44:17 +09001// 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
amistry6555e692016-06-23 16:52:37 +09005#include "ipc/ipc_message_pipe_reader.h"
morrita@chromium.org15996aa2014-08-05 08:44:17 +09006
tfarina1cbfa082015-09-05 03:47:57 +09007#include <stdint.h>
rockot6e3d4922016-03-23 10:32:18 +09008
dcheng6c1ffcf2015-12-28 11:24:50 +09009#include <utility>
tfarina1cbfa082015-09-05 03:47:57 +090010
morrita@chromium.org15996aa2014-08-05 08:44:17 +090011#include "base/bind.h"
12#include "base/bind_helpers.h"
13#include "base/location.h"
14#include "base/logging.h"
rockot6e3d4922016-03-23 10:32:18 +090015#include "base/macros.h"
skyostile468e662015-05-12 20:29:21 +090016#include "base/single_thread_task_runner.h"
gab0867a902016-05-12 03:51:11 +090017#include "base/threading/thread_task_runner_handle.h"
amistry6555e692016-06-23 16:52:37 +090018#include "ipc/ipc_channel_mojo.h"
rockot6e3d4922016-03-23 10:32:18 +090019#include "mojo/public/cpp/bindings/message.h"
morrita@chromium.org15996aa2014-08-05 08:44:17 +090020
21namespace IPC {
22namespace internal {
23
sammc6194d972016-03-08 07:38:04 +090024MessagePipeReader::MessagePipeReader(
rockot6e3d4922016-03-23 10:32:18 +090025 mojo::MessagePipeHandle pipe,
sammc6194d972016-03-08 07:38:04 +090026 mojom::ChannelAssociatedPtr sender,
27 mojo::AssociatedInterfaceRequest<mojom::Channel> receiver,
28 MessagePipeReader::Delegate* delegate)
29 : delegate_(delegate),
30 sender_(std::move(sender)),
rockot685505b2016-09-07 03:35:57 +090031 binding_(this, std::move(receiver)) {
sammc6194d972016-03-08 07:38:04 +090032 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}
morrita@chromium.org15996aa2014-08-05 08:44:17 +090039
40MessagePipeReader::~MessagePipeReader() {
amistry5dfb9c22015-09-03 03:04:22 +090041 DCHECK(thread_checker_.CalledOnValidThread());
morrita5138bf52015-04-21 06:20:12 +090042 // The pipe should be closed before deletion.
morrita@chromium.org15996aa2014-08-05 08:44:17 +090043}
44
45void MessagePipeReader::Close() {
amistry5dfb9c22015-09-03 03:04:22 +090046 DCHECK(thread_checker_.CalledOnValidThread());
sammc6194d972016-03-08 07:38:04 +090047 sender_.reset();
48 if (binding_.is_bound())
49 binding_.Close();
morrita5138bf52015-04-21 06:20:12 +090050}
51
danakjc3fb6c52016-04-23 13:21:09 +090052bool MessagePipeReader::Send(std::unique_ptr<Message> message) {
yuhaoz1fc1a2f2015-08-19 07:21:35 +090053 TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
54 "MessagePipeReader::Send",
55 message->flags(),
56 TRACE_EVENT_FLAG_FLOW_OUT);
Ken Rockotb3a77c92017-09-14 13:23:41 +090057 base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles;
morrita1f42dc62014-11-26 08:35:57 +090058 MojoResult result = MOJO_RESULT_OK;
rockotb1b03902016-03-19 03:58:15 +090059 result = ChannelMojo::ReadFromMessageAttachmentSet(message.get(), &handles);
rockot6e3d4922016-03-23 10:32:18 +090060 if (result != MOJO_RESULT_OK)
morrita1f42dc62014-11-26 08:35:57 +090061 return false;
rockot6e3d4922016-03-23 10:32:18 +090062
rockot685505b2016-09-07 03:35:57 +090063 if (!sender_)
64 return false;
rockot6e3d4922016-03-23 10:32:18 +090065
Yuzhu Shena7e8f9c2017-08-26 07:31:39 +090066 sender_->Receive(base::make_span(static_cast<const uint8_t*>(message->data()),
67 message->size()),
68 std::move(handles));
rockot6e3d4922016-03-23 10:32:18 +090069
sammc6194d972016-03-08 07:38:04 +090070 DVLOG(4) << "Send " << message->type() << ": " << message->size();
rockot685505b2016-09-07 03:35:57 +090071 return true;
morrita1f42dc62014-11-26 08:35:57 +090072}
73
rockota6edf832016-07-14 09:34:11 +090074void MessagePipeReader::GetRemoteInterface(
75 const std::string& name,
76 mojo::ScopedInterfaceEndpointHandle handle) {
rockot157ce7b2016-07-29 05:08:17 +090077 if (!sender_.is_bound())
78 return;
Ken Rockot05405fe2017-05-13 09:29:21 +090079 sender_->GetAssociatedInterface(
80 name, mojom::GenericInterfaceAssociatedRequest(std::move(handle)));
rockota6edf832016-07-14 09:34:11 +090081}
82
rockota01dbc72016-07-23 06:18:07 +090083void MessagePipeReader::SetPeerPid(int32_t peer_pid) {
sammcb83485d2016-11-11 07:34:07 +090084 delegate_->OnPeerPidReceived(peer_pid);
rockota01dbc72016-07-23 06:18:07 +090085}
86
rockotb1b03902016-03-19 03:58:15 +090087void MessagePipeReader::Receive(
Yuzhu Shena7e8f9c2017-08-26 07:31:39 +090088 base::span<const uint8_t> data,
Ken Rockotb3a77c92017-09-14 13:23:41 +090089 base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles) {
rockotb1b03902016-03-19 03:58:15 +090090 Message message(
yzshen8af798c2016-08-24 10:10:13 +090091 data.empty() ? "" : reinterpret_cast<const char*>(data.data()),
rockotb1b03902016-03-19 03:58:15 +090092 static_cast<uint32_t>(data.size()));
morrita1f42dc62014-11-26 08:35:57 +090093
sammc6194d972016-03-08 07:38:04 +090094 DVLOG(4) << "Receive " << message.type() << ": " << message.size();
rockotb1b03902016-03-19 03:58:15 +090095 MojoResult write_result =
96 ChannelMojo::WriteToMessageAttachmentSet(std::move(handles), &message);
morrita1f42dc62014-11-26 08:35:57 +090097 if (write_result != MOJO_RESULT_OK) {
rockot6e3d4922016-03-23 10:32:18 +090098 OnPipeError(write_result);
morrita1f42dc62014-11-26 08:35:57 +090099 return;
100 }
morrita1f42dc62014-11-26 08:35:57 +0900101
yuhaoz1fc1a2f2015-08-19 07:21:35 +0900102 TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
rockot6e3d4922016-03-23 10:32:18 +0900103 "MessagePipeReader::Receive",
yuhaoz1fc1a2f2015-08-19 07:21:35 +0900104 message.flags(),
105 TRACE_EVENT_FLAG_FLOW_IN);
morrita1f42dc62014-11-26 08:35:57 +0900106 delegate_->OnMessageReceived(message);
morrita@chromium.org15996aa2014-08-05 08:44:17 +0900107}
108
rockota6edf832016-07-14 09:34:11 +0900109void MessagePipeReader::GetAssociatedInterface(
yzshen8af798c2016-08-24 10:10:13 +0900110 const std::string& name,
rockota6edf832016-07-14 09:34:11 +0900111 mojom::GenericInterfaceAssociatedRequest request) {
112 DCHECK(thread_checker_.CalledOnValidThread());
113 if (delegate_)
114 delegate_->OnAssociatedInterfaceRequest(name, request.PassHandle());
115}
116
morrita1f42dc62014-11-26 08:35:57 +0900117void MessagePipeReader::OnPipeError(MojoResult error) {
amistry5dfb9c22015-09-03 03:04:22 +0900118 DCHECK(thread_checker_.CalledOnValidThread());
rockota01dbc72016-07-23 06:18:07 +0900119
120 Close();
121
122 // NOTE: The delegate call below may delete |this|.
sammc6194d972016-03-08 07:38:04 +0900123 if (delegate_)
rockot6e3d4922016-03-23 10:32:18 +0900124 delegate_->OnPipeError();
morrita@chromium.org15996aa2014-08-05 08:44:17 +0900125}
126
127} // namespace internal
128} // namespace IPC