1 // Copyright 2015 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.
5 #include "components/message_port/web_message_port_channel_impl.h"
8 #include "base/logging.h"
9 #include "base/strings/string16.h"
10 #include "third_party/WebKit/public/platform/WebMessagePortChannelClient.h"
11 #include "third_party/WebKit/public/platform/WebString.h"
12 #include "third_party/mojo/src/mojo/public/cpp/system/message_pipe.h"
14 using blink::WebMessagePortChannel
;
15 using blink::WebMessagePortChannelArray
;
16 using blink::WebMessagePortChannelClient
;
17 using blink::WebString
;
19 namespace message_port
{
21 void WebMessagePortChannelImpl::CreatePair(
22 blink::WebMessagePortChannel
** channel1
,
23 blink::WebMessagePortChannel
** channel2
) {
24 mojo::ScopedMessagePipeHandle pipe1
;
25 mojo::ScopedMessagePipeHandle pipe2
;
26 MojoResult result
= mojo::CreateMessagePipe(nullptr, &pipe1
, &pipe2
);
27 if (result
!= MOJO_RESULT_OK
) {
32 *channel1
= new WebMessagePortChannelImpl(pipe1
.Pass());;
33 *channel2
= new WebMessagePortChannelImpl(pipe2
.Pass());
36 WebMessagePortChannelImpl::WebMessagePortChannelImpl(
37 mojo::ScopedMessagePipeHandle pipe
)
38 : client_(nullptr), pipe_(pipe
.Pass()) {
42 WebMessagePortChannelImpl::~WebMessagePortChannelImpl() {
45 void WebMessagePortChannelImpl::setClient(WebMessagePortChannelClient
* client
) {
49 void WebMessagePortChannelImpl::destroy() {
54 void WebMessagePortChannelImpl::postMessage(
55 const WebString
& message_as_string
,
56 WebMessagePortChannelArray
* channels
) {
57 base::string16 string
= message_as_string
;
59 std::vector
<MojoHandle
> handles
;
61 for (size_t i
= 0; i
< channels
->size(); ++i
) {
62 WebMessagePortChannelImpl
* channel
=
63 static_cast<WebMessagePortChannelImpl
*>((*channels
)[i
]);
64 handles
.push_back(channel
->pipe_
.release().value());
65 channel
->handle_watcher_
.Stop();
70 uint32_t num_handles
= static_cast<uint32_t>(handles
.size());
71 MojoHandle
* handles_ptr
= handles
.empty() ? nullptr : &handles
[0];
73 MojoResult result
= MojoWriteMessage(
74 pipe_
.get().value(), string
.c_str(),
75 static_cast<uint32_t>(string
.length() * sizeof(base::char16
)),
76 handles_ptr
, num_handles
, MOJO_WRITE_MESSAGE_FLAG_NONE
);
77 DCHECK_EQ(MOJO_RESULT_OK
, result
);
80 bool WebMessagePortChannelImpl::tryGetMessage(
82 WebMessagePortChannelArray
& channels
) {
83 uint32_t num_bytes
= 0;
84 uint32_t num_handles
= 0;
85 MojoResult result
= MojoReadMessage(
86 pipe_
.get().value(), nullptr, &num_bytes
, nullptr, &num_handles
,
87 MOJO_READ_MESSAGE_FLAG_NONE
);
88 if (result
!= MOJO_RESULT_RESOURCE_EXHAUSTED
)
91 base::string16 message16
;
92 CHECK(num_bytes
% sizeof(base::char16
) == 0);
93 message16
.resize(num_bytes
/ sizeof(base::char16
));
94 std::vector
<MojoHandle
> handles
;
95 handles
.resize(num_handles
);
97 MojoHandle
* handles_ptr
= handles
.empty() ? nullptr : &handles
[0];
98 result
= MojoReadMessage(
99 pipe_
.get().value(), &message16
[0], &num_bytes
, handles_ptr
, &num_handles
,
100 MOJO_READ_MESSAGE_FLAG_NONE
);
101 if (result
!= MOJO_RESULT_OK
) {
106 *message
= message16
;
107 WebMessagePortChannelArray
ports(handles
.size());
108 for (size_t i
= 0; i
< handles
.size(); ++i
) {
109 mojo::MessagePipeHandle
mph(handles
[i
]);
110 mojo::ScopedMessagePipeHandle
handle(mph
);
111 ports
[i
] = new WebMessagePortChannelImpl(handle
.Pass());
117 void WebMessagePortChannelImpl::WaitForNextMessage() {
118 handle_watcher_
.Start(
120 MOJO_HANDLE_SIGNAL_READABLE
,
121 MOJO_DEADLINE_INDEFINITE
,
122 base::Bind(&WebMessagePortChannelImpl::OnMessageAvailable
,
123 base::Unretained(this)));
126 void WebMessagePortChannelImpl::OnMessageAvailable(MojoResult result
) {
127 // |result| can be MOJO_RESULT_ABORTED when the message loop shuts down, or
128 // MOJO_RESULT_FAILED_PRECONDITION when the end-of-file is reached.
129 if (result
== MOJO_RESULT_ABORTED
||
130 result
== MOJO_RESULT_FAILED_PRECONDITION
)
133 DCHECK_EQ(MOJO_RESULT_OK
, result
);
136 client_
->messageAvailable();
137 WaitForNextMessage();
140 } // namespace message_port