blob: ab5466e33639c5cf85e2d4115f951262e92f99d9 [file] [log] [blame]
[email protected]64860882014-08-04 23:44:171// 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/mojo/ipc_message_pipe_reader.h"
6
tfarina10a5c062015-09-04 18:47:577#include <stdint.h>
dchenge48600452015-12-28 02:24:508#include <utility>
tfarina10a5c062015-09-04 18:47:579
[email protected]64860882014-08-04 23:44:1710#include "base/bind.h"
11#include "base/bind_helpers.h"
12#include "base/location.h"
13#include "base/logging.h"
skyostile687bdff2015-05-12 11:29:2114#include "base/single_thread_task_runner.h"
15#include "base/thread_task_runner_handle.h"
morritad68bedf42014-11-25 23:35:5716#include "ipc/mojo/ipc_channel_mojo.h"
[email protected]64860882014-08-04 23:44:1717
18namespace IPC {
19namespace internal {
20
sammce4d0abd2016-03-07 22:38:0421MessagePipeReader::MessagePipeReader(
22 mojom::ChannelAssociatedPtr sender,
23 mojo::AssociatedInterfaceRequest<mojom::Channel> receiver,
24 MessagePipeReader::Delegate* delegate)
25 : delegate_(delegate),
26 sender_(std::move(sender)),
27 binding_(this, std::move(receiver)) {
28 sender_.set_connection_error_handler(
29 base::Bind(&MessagePipeReader::OnPipeError, base::Unretained(this),
30 MOJO_RESULT_FAILED_PRECONDITION));
31 binding_.set_connection_error_handler(
32 base::Bind(&MessagePipeReader::OnPipeError, base::Unretained(this),
33 MOJO_RESULT_FAILED_PRECONDITION));
34}
[email protected]64860882014-08-04 23:44:1735
36MessagePipeReader::~MessagePipeReader() {
amistry0b0e7482015-09-02 18:04:2237 DCHECK(thread_checker_.CalledOnValidThread());
morritab4472142015-04-20 21:20:1238 // The pipe should be closed before deletion.
[email protected]64860882014-08-04 23:44:1739}
40
41void MessagePipeReader::Close() {
amistry0b0e7482015-09-02 18:04:2242 DCHECK(thread_checker_.CalledOnValidThread());
sammce4d0abd2016-03-07 22:38:0443 sender_.reset();
44 if (binding_.is_bound())
45 binding_.Close();
[email protected]64860882014-08-04 23:44:1746 OnPipeClosed();
47}
48
49void MessagePipeReader::CloseWithError(MojoResult error) {
amistry0b0e7482015-09-02 18:04:2250 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]64860882014-08-04 23:44:1751 OnPipeError(error);
morritab4472142015-04-20 21:20:1252}
53
morritad68bedf42014-11-25 23:35:5754bool MessagePipeReader::Send(scoped_ptr<Message> message) {
yuhaoz9b8157d2015-08-18 22:21:3555 TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
56 "MessagePipeReader::Send",
57 message->flags(),
58 TRACE_EVENT_FLAG_FLOW_OUT);
sammce4d0abd2016-03-07 22:38:0459 mojom::MessagePtr ipc_message = mojom::Message::New();
morritad68bedf42014-11-25 23:35:5760 MojoResult result = MOJO_RESULT_OK;
sammce4d0abd2016-03-07 22:38:0461 result = ChannelMojo::ReadFromMessageAttachmentSet(message.get(),
62 &ipc_message->handles);
morritad68bedf42014-11-25 23:35:5763 if (result != MOJO_RESULT_OK) {
sammce4d0abd2016-03-07 22:38:0464 CloseWithError(result);
morritad68bedf42014-11-25 23:35:5765 return false;
66 }
sammce4d0abd2016-03-07 22:38:0467 ipc_message->data.resize(message->size());
68 std::copy(reinterpret_cast<const uint8_t*>(message->data()),
69 reinterpret_cast<const uint8_t*>(message->data()) + message->size(),
70 &ipc_message->data[0]);
71 sender_->Receive(std::move(ipc_message));
72 DVLOG(4) << "Send " << message->type() << ": " << message->size();
morritad68bedf42014-11-25 23:35:5773 return true;
74}
75
sammce4d0abd2016-03-07 22:38:0476void MessagePipeReader::Receive(mojom::MessagePtr ipc_message) {
77 Message message(ipc_message->data.size() == 0
78 ? ""
79 : reinterpret_cast<const char*>(&ipc_message->data[0]),
80 static_cast<uint32_t>(ipc_message->data.size()));
morritad68bedf42014-11-25 23:35:5781
sammce4d0abd2016-03-07 22:38:0482 DVLOG(4) << "Receive " << message.type() << ": " << message.size();
83 MojoResult write_result = ChannelMojo::WriteToMessageAttachmentSet(
84 std::move(ipc_message->handles), &message);
morritad68bedf42014-11-25 23:35:5785 if (write_result != MOJO_RESULT_OK) {
86 CloseWithError(write_result);
87 return;
88 }
morritad68bedf42014-11-25 23:35:5789
yuhaoz9b8157d2015-08-18 22:21:3590 TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
91 "MessagePipeReader::OnMessageReceived",
92 message.flags(),
93 TRACE_EVENT_FLAG_FLOW_IN);
morritad68bedf42014-11-25 23:35:5794 delegate_->OnMessageReceived(message);
[email protected]64860882014-08-04 23:44:1795}
96
morritad68bedf42014-11-25 23:35:5797void MessagePipeReader::OnPipeClosed() {
amistry0b0e7482015-09-02 18:04:2298 DCHECK(thread_checker_.CalledOnValidThread());
morritad68bedf42014-11-25 23:35:5799 if (!delegate_)
[email protected]64860882014-08-04 23:44:17100 return;
morritad68bedf42014-11-25 23:35:57101 delegate_->OnPipeClosed(this);
102 delegate_ = nullptr;
103}
104
105void MessagePipeReader::OnPipeError(MojoResult error) {
amistry0b0e7482015-09-02 18:04:22106 DCHECK(thread_checker_.CalledOnValidThread());
sammce4d0abd2016-03-07 22:38:04107 if (delegate_)
108 delegate_->OnPipeError(this);
109 Close();
[email protected]64860882014-08-04 23:44:17110}
111
112void MessagePipeReader::DelayedDeleter::operator()(
113 MessagePipeReader* ptr) const {
114 ptr->Close();
skyostile687bdff2015-05-12 11:29:21115 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
116 base::Bind(&DeleteNow, ptr));
[email protected]64860882014-08-04 23:44:17117}
118
119} // namespace internal
120} // namespace IPC