1*635a8641SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message_pipe_reader.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include <utility>
10*635a8641SAndroid Build Coastguard Worker
11*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/bind_helpers.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/location.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/single_thread_task_runner.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_task_runner_handle.h"
18*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_channel_mojo.h"
19*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/message.h"
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker namespace IPC {
22*635a8641SAndroid Build Coastguard Worker namespace internal {
23*635a8641SAndroid Build Coastguard Worker
MessagePipeReader(mojo::MessagePipeHandle pipe,mojom::ChannelAssociatedPtr sender,mojo::AssociatedInterfaceRequest<mojom::Channel> receiver,MessagePipeReader::Delegate * delegate)24*635a8641SAndroid Build Coastguard Worker MessagePipeReader::MessagePipeReader(
25*635a8641SAndroid Build Coastguard Worker mojo::MessagePipeHandle pipe,
26*635a8641SAndroid Build Coastguard Worker mojom::ChannelAssociatedPtr sender,
27*635a8641SAndroid Build Coastguard Worker mojo::AssociatedInterfaceRequest<mojom::Channel> receiver,
28*635a8641SAndroid Build Coastguard Worker MessagePipeReader::Delegate* delegate)
29*635a8641SAndroid Build Coastguard Worker : delegate_(delegate),
30*635a8641SAndroid Build Coastguard Worker sender_(std::move(sender)),
31*635a8641SAndroid Build Coastguard Worker binding_(this, std::move(receiver)) {
32*635a8641SAndroid Build Coastguard Worker sender_.set_connection_error_handler(
33*635a8641SAndroid Build Coastguard Worker base::Bind(&MessagePipeReader::OnPipeError, base::Unretained(this),
34*635a8641SAndroid Build Coastguard Worker MOJO_RESULT_FAILED_PRECONDITION));
35*635a8641SAndroid Build Coastguard Worker binding_.set_connection_error_handler(
36*635a8641SAndroid Build Coastguard Worker base::Bind(&MessagePipeReader::OnPipeError, base::Unretained(this),
37*635a8641SAndroid Build Coastguard Worker MOJO_RESULT_FAILED_PRECONDITION));
38*635a8641SAndroid Build Coastguard Worker }
39*635a8641SAndroid Build Coastguard Worker
~MessagePipeReader()40*635a8641SAndroid Build Coastguard Worker MessagePipeReader::~MessagePipeReader() {
41*635a8641SAndroid Build Coastguard Worker DCHECK(thread_checker_.CalledOnValidThread());
42*635a8641SAndroid Build Coastguard Worker // The pipe should be closed before deletion.
43*635a8641SAndroid Build Coastguard Worker }
44*635a8641SAndroid Build Coastguard Worker
Close()45*635a8641SAndroid Build Coastguard Worker void MessagePipeReader::Close() {
46*635a8641SAndroid Build Coastguard Worker DCHECK(thread_checker_.CalledOnValidThread());
47*635a8641SAndroid Build Coastguard Worker sender_.reset();
48*635a8641SAndroid Build Coastguard Worker if (binding_.is_bound())
49*635a8641SAndroid Build Coastguard Worker binding_.Close();
50*635a8641SAndroid Build Coastguard Worker }
51*635a8641SAndroid Build Coastguard Worker
Send(std::unique_ptr<Message> message)52*635a8641SAndroid Build Coastguard Worker bool MessagePipeReader::Send(std::unique_ptr<Message> message) {
53*635a8641SAndroid Build Coastguard Worker CHECK(message->IsValid());
54*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
55*635a8641SAndroid Build Coastguard Worker "MessagePipeReader::Send", message->flags(),
56*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_FLAG_FLOW_OUT);
57*635a8641SAndroid Build Coastguard Worker base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles;
58*635a8641SAndroid Build Coastguard Worker MojoResult result = MOJO_RESULT_OK;
59*635a8641SAndroid Build Coastguard Worker result = ChannelMojo::ReadFromMessageAttachmentSet(message.get(), &handles);
60*635a8641SAndroid Build Coastguard Worker if (result != MOJO_RESULT_OK)
61*635a8641SAndroid Build Coastguard Worker return false;
62*635a8641SAndroid Build Coastguard Worker
63*635a8641SAndroid Build Coastguard Worker if (!sender_)
64*635a8641SAndroid Build Coastguard Worker return false;
65*635a8641SAndroid Build Coastguard Worker
66*635a8641SAndroid Build Coastguard Worker sender_->Receive(MessageView(*message, std::move(handles)));
67*635a8641SAndroid Build Coastguard Worker DVLOG(4) << "Send " << message->type() << ": " << message->size();
68*635a8641SAndroid Build Coastguard Worker return true;
69*635a8641SAndroid Build Coastguard Worker }
70*635a8641SAndroid Build Coastguard Worker
GetRemoteInterface(const std::string & name,mojo::ScopedInterfaceEndpointHandle handle)71*635a8641SAndroid Build Coastguard Worker void MessagePipeReader::GetRemoteInterface(
72*635a8641SAndroid Build Coastguard Worker const std::string& name,
73*635a8641SAndroid Build Coastguard Worker mojo::ScopedInterfaceEndpointHandle handle) {
74*635a8641SAndroid Build Coastguard Worker if (!sender_.is_bound())
75*635a8641SAndroid Build Coastguard Worker return;
76*635a8641SAndroid Build Coastguard Worker sender_->GetAssociatedInterface(
77*635a8641SAndroid Build Coastguard Worker name, mojom::GenericInterfaceAssociatedRequest(std::move(handle)));
78*635a8641SAndroid Build Coastguard Worker }
79*635a8641SAndroid Build Coastguard Worker
SetPeerPid(int32_t peer_pid)80*635a8641SAndroid Build Coastguard Worker void MessagePipeReader::SetPeerPid(int32_t peer_pid) {
81*635a8641SAndroid Build Coastguard Worker delegate_->OnPeerPidReceived(peer_pid);
82*635a8641SAndroid Build Coastguard Worker }
83*635a8641SAndroid Build Coastguard Worker
Receive(MessageView message_view)84*635a8641SAndroid Build Coastguard Worker void MessagePipeReader::Receive(MessageView message_view) {
85*635a8641SAndroid Build Coastguard Worker if (!message_view.size()) {
86*635a8641SAndroid Build Coastguard Worker delegate_->OnBrokenDataReceived();
87*635a8641SAndroid Build Coastguard Worker return;
88*635a8641SAndroid Build Coastguard Worker }
89*635a8641SAndroid Build Coastguard Worker Message message(message_view.data(), message_view.size());
90*635a8641SAndroid Build Coastguard Worker if (!message.IsValid()) {
91*635a8641SAndroid Build Coastguard Worker delegate_->OnBrokenDataReceived();
92*635a8641SAndroid Build Coastguard Worker return;
93*635a8641SAndroid Build Coastguard Worker }
94*635a8641SAndroid Build Coastguard Worker
95*635a8641SAndroid Build Coastguard Worker DVLOG(4) << "Receive " << message.type() << ": " << message.size();
96*635a8641SAndroid Build Coastguard Worker MojoResult write_result = ChannelMojo::WriteToMessageAttachmentSet(
97*635a8641SAndroid Build Coastguard Worker message_view.TakeHandles(), &message);
98*635a8641SAndroid Build Coastguard Worker if (write_result != MOJO_RESULT_OK) {
99*635a8641SAndroid Build Coastguard Worker OnPipeError(write_result);
100*635a8641SAndroid Build Coastguard Worker return;
101*635a8641SAndroid Build Coastguard Worker }
102*635a8641SAndroid Build Coastguard Worker
103*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
104*635a8641SAndroid Build Coastguard Worker "MessagePipeReader::Receive",
105*635a8641SAndroid Build Coastguard Worker message.flags(),
106*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_FLAG_FLOW_IN);
107*635a8641SAndroid Build Coastguard Worker delegate_->OnMessageReceived(message);
108*635a8641SAndroid Build Coastguard Worker }
109*635a8641SAndroid Build Coastguard Worker
GetAssociatedInterface(const std::string & name,mojom::GenericInterfaceAssociatedRequest request)110*635a8641SAndroid Build Coastguard Worker void MessagePipeReader::GetAssociatedInterface(
111*635a8641SAndroid Build Coastguard Worker const std::string& name,
112*635a8641SAndroid Build Coastguard Worker mojom::GenericInterfaceAssociatedRequest request) {
113*635a8641SAndroid Build Coastguard Worker DCHECK(thread_checker_.CalledOnValidThread());
114*635a8641SAndroid Build Coastguard Worker if (delegate_)
115*635a8641SAndroid Build Coastguard Worker delegate_->OnAssociatedInterfaceRequest(name, request.PassHandle());
116*635a8641SAndroid Build Coastguard Worker }
117*635a8641SAndroid Build Coastguard Worker
OnPipeError(MojoResult error)118*635a8641SAndroid Build Coastguard Worker void MessagePipeReader::OnPipeError(MojoResult error) {
119*635a8641SAndroid Build Coastguard Worker DCHECK(thread_checker_.CalledOnValidThread());
120*635a8641SAndroid Build Coastguard Worker
121*635a8641SAndroid Build Coastguard Worker Close();
122*635a8641SAndroid Build Coastguard Worker
123*635a8641SAndroid Build Coastguard Worker // NOTE: The delegate call below may delete |this|.
124*635a8641SAndroid Build Coastguard Worker if (delegate_)
125*635a8641SAndroid Build Coastguard Worker delegate_->OnPipeError();
126*635a8641SAndroid Build Coastguard Worker }
127*635a8641SAndroid Build Coastguard Worker
128*635a8641SAndroid Build Coastguard Worker } // namespace internal
129*635a8641SAndroid Build Coastguard Worker } // namespace IPC
130