Roll src/third_party/WebKit 9f7fb92:f103b33 (svn 202621:202622)
[chromium-blink-merge.git] / components / message_port / web_message_port_channel_impl.cc
blobdb30963b1e5aba031d2623a1bcd45d2a2c15800b
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"
7 #include "base/bind.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) {
28 NOTREACHED();
29 return;
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()) {
39 WaitForNextMessage();
42 WebMessagePortChannelImpl::~WebMessagePortChannelImpl() {
45 void WebMessagePortChannelImpl::setClient(WebMessagePortChannelClient* client) {
46 client_ = client;
49 void WebMessagePortChannelImpl::destroy() {
50 setClient(nullptr);
51 delete this;
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;
60 if (channels) {
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();
67 delete channels;
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(
81 WebString* message,
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)
89 return false;
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) {
102 NOTREACHED();
103 return false;
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());
113 channels = ports;
114 return true;
117 void WebMessagePortChannelImpl::WaitForNextMessage() {
118 handle_watcher_.Start(
119 pipe_.get(),
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)
131 return;
133 DCHECK_EQ(MOJO_RESULT_OK, result);
134 if (!client_)
135 return;
136 client_->messageAvailable();
137 WaitForNextMessage();
140 } // namespace message_port