OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "mojo/services/html_viewer/web_message_port_channel_impl.h" | |
6 | |
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" | |
13 | |
14 using blink::WebMessagePortChannel; | |
15 using blink::WebMessagePortChannelArray; | |
16 using blink::WebMessagePortChannelClient; | |
17 using blink::WebString; | |
18 | |
19 namespace html_viewer { | |
20 | |
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; | |
30 } | |
31 | |
32 *channel1 = new WebMessagePortChannelImpl(pipe1.Pass());; | |
33 *channel2 = new WebMessagePortChannelImpl(pipe2.Pass()); | |
34 } | |
35 | |
36 WebMessagePortChannelImpl::WebMessagePortChannelImpl( | |
37 mojo::ScopedMessagePipeHandle pipe) | |
38 : client_(nullptr), pipe_(pipe.Pass()) { | |
39 WaitForNextMessage(); | |
40 } | |
41 | |
42 WebMessagePortChannelImpl::~WebMessagePortChannelImpl() { | |
43 } | |
44 | |
45 void WebMessagePortChannelImpl::setClient(WebMessagePortChannelClient* client) { | |
46 client_ = client; | |
47 } | |
48 | |
49 void WebMessagePortChannelImpl::destroy() { | |
50 setClient(nullptr); | |
51 delete this; | |
52 } | |
53 | |
54 void WebMessagePortChannelImpl::postMessage( | |
55 const WebString& message_as_string, | |
56 WebMessagePortChannelArray* channels) { | |
57 base::string16 string = message_as_string; | |
58 | |
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(); | |
66 } | |
67 delete channels; | |
68 } | |
69 | |
70 uint32_t num_handles = static_cast<uint32_t>(handles.size()); | |
71 MojoHandle* handles_ptr = handles.empty() ? nullptr : &handles[0]; | |
72 | |
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); | |
78 } | |
79 | |
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; | |
90 | |
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); | |
96 | |
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; | |
104 } | |
105 | |
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()); | |
112 } | |
113 channels = ports; | |
114 return true; | |
115 } | |
116 | |
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))); | |
124 } | |
125 | |
126 void WebMessagePortChannelImpl::OnMessageAvailable(MojoResult result) { | |
127 DCHECK_EQ(MOJO_RESULT_OK, result); | |
128 client_->messageAvailable(); | |
129 WaitForNextMessage(); | |
130 } | |
131 | |
132 } // namespace html_viewer | |
OLD | NEW |