morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 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 | |
amistry | 6555e69 | 2016-06-23 16:52:37 +0900 | [diff] [blame] | 5 | #include "ipc/ipc_message_pipe_reader.h" |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 6 | |
tfarina | 1cbfa08 | 2015-09-05 03:47:57 +0900 | [diff] [blame] | 7 | #include <stdint.h> |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 8 | |
dcheng | 6c1ffcf | 2015-12-28 11:24:50 +0900 | [diff] [blame] | 9 | #include <utility> |
tfarina | 1cbfa08 | 2015-09-05 03:47:57 +0900 | [diff] [blame] | 10 | |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 11 | #include "base/bind.h" |
| 12 | #include "base/bind_helpers.h" |
| 13 | #include "base/location.h" |
| 14 | #include "base/logging.h" |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 15 | #include "base/macros.h" |
skyostil | e468e66 | 2015-05-12 20:29:21 +0900 | [diff] [blame] | 16 | #include "base/single_thread_task_runner.h" |
gab | 0867a90 | 2016-05-12 03:51:11 +0900 | [diff] [blame] | 17 | #include "base/threading/thread_task_runner_handle.h" |
amistry | 6555e69 | 2016-06-23 16:52:37 +0900 | [diff] [blame] | 18 | #include "ipc/ipc_channel_mojo.h" |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 19 | #include "mojo/public/cpp/bindings/message.h" |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 20 | |
| 21 | namespace IPC { |
| 22 | namespace internal { |
| 23 | |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 24 | MessagePipeReader::MessagePipeReader( |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 25 | mojo::MessagePipeHandle pipe, |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 26 | mojom::ChannelAssociatedPtr sender, |
| 27 | mojo::AssociatedInterfaceRequest<mojom::Channel> receiver, |
| 28 | MessagePipeReader::Delegate* delegate) |
| 29 | : delegate_(delegate), |
| 30 | sender_(std::move(sender)), |
rockot | 685505b | 2016-09-07 03:35:57 +0900 | [diff] [blame] | 31 | binding_(this, std::move(receiver)) { |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 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 | } |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 39 | |
| 40 | MessagePipeReader::~MessagePipeReader() { |
amistry | 5dfb9c2 | 2015-09-03 03:04:22 +0900 | [diff] [blame] | 41 | DCHECK(thread_checker_.CalledOnValidThread()); |
morrita | 5138bf5 | 2015-04-21 06:20:12 +0900 | [diff] [blame] | 42 | // The pipe should be closed before deletion. |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 43 | } |
| 44 | |
| 45 | void MessagePipeReader::Close() { |
amistry | 5dfb9c2 | 2015-09-03 03:04:22 +0900 | [diff] [blame] | 46 | DCHECK(thread_checker_.CalledOnValidThread()); |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 47 | sender_.reset(); |
| 48 | if (binding_.is_bound()) |
| 49 | binding_.Close(); |
morrita | 5138bf5 | 2015-04-21 06:20:12 +0900 | [diff] [blame] | 50 | } |
| 51 | |
danakj | c3fb6c5 | 2016-04-23 13:21:09 +0900 | [diff] [blame] | 52 | bool MessagePipeReader::Send(std::unique_ptr<Message> message) { |
yuhaoz | 1fc1a2f | 2015-08-19 07:21:35 +0900 | [diff] [blame] | 53 | TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), |
| 54 | "MessagePipeReader::Send", |
| 55 | message->flags(), |
| 56 | TRACE_EVENT_FLAG_FLOW_OUT); |
Ken Rockot | b3a77c9 | 2017-09-14 13:23:41 +0900 | [diff] [blame] | 57 | base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles; |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 58 | MojoResult result = MOJO_RESULT_OK; |
rockot | b1b0390 | 2016-03-19 03:58:15 +0900 | [diff] [blame] | 59 | result = ChannelMojo::ReadFromMessageAttachmentSet(message.get(), &handles); |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 60 | if (result != MOJO_RESULT_OK) |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 61 | return false; |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 62 | |
rockot | 685505b | 2016-09-07 03:35:57 +0900 | [diff] [blame] | 63 | if (!sender_) |
| 64 | return false; |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 65 | |
Yuzhu Shen | a7e8f9c | 2017-08-26 07:31:39 +0900 | [diff] [blame] | 66 | sender_->Receive(base::make_span(static_cast<const uint8_t*>(message->data()), |
| 67 | message->size()), |
| 68 | std::move(handles)); |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 69 | |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 70 | DVLOG(4) << "Send " << message->type() << ": " << message->size(); |
rockot | 685505b | 2016-09-07 03:35:57 +0900 | [diff] [blame] | 71 | return true; |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 72 | } |
| 73 | |
rockot | a6edf83 | 2016-07-14 09:34:11 +0900 | [diff] [blame] | 74 | void MessagePipeReader::GetRemoteInterface( |
| 75 | const std::string& name, |
| 76 | mojo::ScopedInterfaceEndpointHandle handle) { |
rockot | 157ce7b | 2016-07-29 05:08:17 +0900 | [diff] [blame] | 77 | if (!sender_.is_bound()) |
| 78 | return; |
Ken Rockot | 05405fe | 2017-05-13 09:29:21 +0900 | [diff] [blame] | 79 | sender_->GetAssociatedInterface( |
| 80 | name, mojom::GenericInterfaceAssociatedRequest(std::move(handle))); |
rockot | a6edf83 | 2016-07-14 09:34:11 +0900 | [diff] [blame] | 81 | } |
| 82 | |
rockot | a01dbc7 | 2016-07-23 06:18:07 +0900 | [diff] [blame] | 83 | void MessagePipeReader::SetPeerPid(int32_t peer_pid) { |
sammc | b83485d | 2016-11-11 07:34:07 +0900 | [diff] [blame] | 84 | delegate_->OnPeerPidReceived(peer_pid); |
rockot | a01dbc7 | 2016-07-23 06:18:07 +0900 | [diff] [blame] | 85 | } |
| 86 | |
rockot | b1b0390 | 2016-03-19 03:58:15 +0900 | [diff] [blame] | 87 | void MessagePipeReader::Receive( |
Yuzhu Shen | a7e8f9c | 2017-08-26 07:31:39 +0900 | [diff] [blame] | 88 | base::span<const uint8_t> data, |
Ken Rockot | b3a77c9 | 2017-09-14 13:23:41 +0900 | [diff] [blame] | 89 | base::Optional<std::vector<mojo::native::SerializedHandlePtr>> handles) { |
rockot | b1b0390 | 2016-03-19 03:58:15 +0900 | [diff] [blame] | 90 | Message message( |
yzshen | 8af798c | 2016-08-24 10:10:13 +0900 | [diff] [blame] | 91 | data.empty() ? "" : reinterpret_cast<const char*>(data.data()), |
rockot | b1b0390 | 2016-03-19 03:58:15 +0900 | [diff] [blame] | 92 | static_cast<uint32_t>(data.size())); |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 93 | |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 94 | DVLOG(4) << "Receive " << message.type() << ": " << message.size(); |
rockot | b1b0390 | 2016-03-19 03:58:15 +0900 | [diff] [blame] | 95 | MojoResult write_result = |
| 96 | ChannelMojo::WriteToMessageAttachmentSet(std::move(handles), &message); |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 97 | if (write_result != MOJO_RESULT_OK) { |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 98 | OnPipeError(write_result); |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 99 | return; |
| 100 | } |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 101 | |
yuhaoz | 1fc1a2f | 2015-08-19 07:21:35 +0900 | [diff] [blame] | 102 | TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 103 | "MessagePipeReader::Receive", |
yuhaoz | 1fc1a2f | 2015-08-19 07:21:35 +0900 | [diff] [blame] | 104 | message.flags(), |
| 105 | TRACE_EVENT_FLAG_FLOW_IN); |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 106 | delegate_->OnMessageReceived(message); |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 107 | } |
| 108 | |
rockot | a6edf83 | 2016-07-14 09:34:11 +0900 | [diff] [blame] | 109 | void MessagePipeReader::GetAssociatedInterface( |
yzshen | 8af798c | 2016-08-24 10:10:13 +0900 | [diff] [blame] | 110 | const std::string& name, |
rockot | a6edf83 | 2016-07-14 09:34:11 +0900 | [diff] [blame] | 111 | mojom::GenericInterfaceAssociatedRequest request) { |
| 112 | DCHECK(thread_checker_.CalledOnValidThread()); |
| 113 | if (delegate_) |
| 114 | delegate_->OnAssociatedInterfaceRequest(name, request.PassHandle()); |
| 115 | } |
| 116 | |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 117 | void MessagePipeReader::OnPipeError(MojoResult error) { |
amistry | 5dfb9c2 | 2015-09-03 03:04:22 +0900 | [diff] [blame] | 118 | DCHECK(thread_checker_.CalledOnValidThread()); |
rockot | a01dbc7 | 2016-07-23 06:18:07 +0900 | [diff] [blame] | 119 | |
| 120 | Close(); |
| 121 | |
| 122 | // NOTE: The delegate call below may delete |this|. |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 123 | if (delegate_) |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 124 | delegate_->OnPipeError(); |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 125 | } |
| 126 | |
| 127 | } // namespace internal |
| 128 | } // namespace IPC |