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