xref: /aosp_15_r20/external/libchrome/ipc/ipc_message_pipe_reader.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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