Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ipc / mojo / ipc_channel_mojo.cc
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
5 #include "ipc/mojo/ipc_channel_mojo.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/lazy_instance.h"
10 #include "ipc/ipc_listener.h"
11 #include "ipc/mojo/client_channel.mojom.h"
12 #include "ipc/mojo/ipc_channel_mojo_readers.h"
13 #include "ipc/mojo/ipc_mojo_bootstrap.h"
14 #include "mojo/edk/embedder/embedder.h"
15 #include "mojo/public/cpp/bindings/error_handler.h"
16
17 #if defined(OS_POSIX) && !defined(OS_NACL)
18 #include "ipc/file_descriptor_set_posix.h"
19 #endif
20
21 namespace IPC {
22
23 namespace {
24
25 class MojoChannelFactory : public ChannelFactory {
26  public:
27   MojoChannelFactory(ChannelMojo::Delegate* delegate,
28                      ChannelHandle channel_handle,
29                      Channel::Mode mode)
30       : delegate_(delegate), channel_handle_(channel_handle), mode_(mode) {}
31
32   std::string GetName() const override {
33     return channel_handle_.name;
34   }
35
36   scoped_ptr<Channel> BuildChannel(Listener* listener) override {
37     return ChannelMojo::Create(delegate_, channel_handle_, mode_, listener);
38   }
39
40  private:
41   ChannelMojo::Delegate* delegate_;
42   ChannelHandle channel_handle_;
43   Channel::Mode mode_;
44 };
45
46 //------------------------------------------------------------------------------
47
48 class ClientChannelMojo
49     : public ChannelMojo,
50       public NON_EXPORTED_BASE(mojo::InterfaceImpl<ClientChannel>) {
51  public:
52   ClientChannelMojo(ChannelMojo::Delegate* delegate,
53                     const ChannelHandle& handle,
54                     Listener* listener);
55   ~ClientChannelMojo() override;
56   // MojoBootstrap::Delegate implementation
57   void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override;
58   // InterfaceImpl implementation
59   void OnConnectionError() override;
60   // ClientChannel implementation
61   void Init(
62       mojo::ScopedMessagePipeHandle pipe,
63       int32_t peer_pid,
64       const mojo::Callback<void(int32_t)>& callback) override;
65
66   DISALLOW_COPY_AND_ASSIGN(ClientChannelMojo);
67 };
68
69 ClientChannelMojo::ClientChannelMojo(ChannelMojo::Delegate* delegate,
70                                      const ChannelHandle& handle,
71                                      Listener* listener)
72     : ChannelMojo(delegate, handle, Channel::MODE_CLIENT, listener) {
73 }
74
75 ClientChannelMojo::~ClientChannelMojo() {
76 }
77
78 void ClientChannelMojo::OnPipeAvailable(
79     mojo::embedder::ScopedPlatformHandle handle) {
80   mojo::WeakBindToPipe(this, CreateMessagingPipe(handle.Pass()));
81 }
82
83 void ClientChannelMojo::OnConnectionError() {
84   listener()->OnChannelError();
85 }
86
87 void ClientChannelMojo::Init(
88     mojo::ScopedMessagePipeHandle pipe,
89     int32_t peer_pid,
90     const mojo::Callback<void(int32_t)>& callback) {
91   InitMessageReader(pipe.Pass(), static_cast<base::ProcessId>(peer_pid));
92   callback.Run(GetSelfPID());
93 }
94
95 //------------------------------------------------------------------------------
96
97 class ServerChannelMojo : public ChannelMojo, public mojo::ErrorHandler {
98  public:
99   ServerChannelMojo(ChannelMojo::Delegate* delegate,
100                     const ChannelHandle& handle,
101                     Listener* listener);
102   ~ServerChannelMojo() override;
103
104   // MojoBootstrap::Delegate implementation
105   void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override;
106   // ErrorHandler implementation
107   void OnConnectionError() override;
108   // Channel override
109   void Close() override;
110
111  private:
112   // ClientChannelClient implementation
113   void ClientChannelWasInitialized(int32_t peer_pid);
114
115   mojo::InterfacePtr<ClientChannel> client_channel_;
116   mojo::ScopedMessagePipeHandle message_pipe_;
117
118   DISALLOW_COPY_AND_ASSIGN(ServerChannelMojo);
119 };
120
121 ServerChannelMojo::ServerChannelMojo(ChannelMojo::Delegate* delegate,
122                                      const ChannelHandle& handle,
123                                      Listener* listener)
124     : ChannelMojo(delegate, handle, Channel::MODE_SERVER, listener) {
125 }
126
127 ServerChannelMojo::~ServerChannelMojo() {
128   Close();
129 }
130
131 void ServerChannelMojo::OnPipeAvailable(
132     mojo::embedder::ScopedPlatformHandle handle) {
133   mojo::ScopedMessagePipeHandle peer;
134   MojoResult create_result =
135       mojo::CreateMessagePipe(nullptr, &message_pipe_, &peer);
136   if (create_result != MOJO_RESULT_OK) {
137     DLOG(WARNING) << "mojo::CreateMessagePipe failed: " << create_result;
138     listener()->OnChannelError();
139     return;
140   }
141
142   client_channel_.Bind(CreateMessagingPipe(handle.Pass()));
143   client_channel_.set_error_handler(this);
144   client_channel_->Init(
145       peer.Pass(),
146       static_cast<int32_t>(GetSelfPID()),
147       base::Bind(&ServerChannelMojo::ClientChannelWasInitialized,
148                  base::Unretained(this)));
149 }
150
151 void ServerChannelMojo::ClientChannelWasInitialized(int32_t peer_pid) {
152   InitMessageReader(message_pipe_.Pass(), peer_pid);
153 }
154
155 void ServerChannelMojo::OnConnectionError() {
156   listener()->OnChannelError();
157 }
158
159 void ServerChannelMojo::Close() {
160   client_channel_.reset();
161   message_pipe_.reset();
162   ChannelMojo::Close();
163 }
164
165 } // namespace
166
167 //------------------------------------------------------------------------------
168
169 void ChannelMojo::ChannelInfoDeleter::operator()(
170     mojo::embedder::ChannelInfo* ptr) const {
171   mojo::embedder::DestroyChannelOnIOThread(ptr);
172 }
173
174 //------------------------------------------------------------------------------
175
176 // static
177 bool ChannelMojo::ShouldBeUsed() {
178   // TODO(morrita): Turn this on for a set of platforms.
179   return false;
180 }
181
182 // static
183 scoped_ptr<ChannelMojo> ChannelMojo::Create(ChannelMojo::Delegate* delegate,
184                                             const ChannelHandle& channel_handle,
185                                             Mode mode,
186                                             Listener* listener) {
187   switch (mode) {
188     case Channel::MODE_CLIENT:
189       return make_scoped_ptr(
190           new ClientChannelMojo(delegate, channel_handle, listener));
191     case Channel::MODE_SERVER:
192       return make_scoped_ptr(
193           new ServerChannelMojo(delegate, channel_handle, listener));
194     default:
195       NOTREACHED();
196       return nullptr;
197   }
198 }
199
200 // static
201 scoped_ptr<ChannelFactory> ChannelMojo::CreateServerFactory(
202     ChannelMojo::Delegate* delegate,
203     const ChannelHandle& channel_handle) {
204   return make_scoped_ptr(
205       new MojoChannelFactory(delegate, channel_handle, Channel::MODE_SERVER));
206 }
207
208 // static
209 scoped_ptr<ChannelFactory> ChannelMojo::CreateClientFactory(
210     const ChannelHandle& channel_handle) {
211   return make_scoped_ptr(
212       new MojoChannelFactory(NULL, channel_handle, Channel::MODE_CLIENT));
213 }
214
215 ChannelMojo::ChannelMojo(ChannelMojo::Delegate* delegate,
216                          const ChannelHandle& handle,
217                          Mode mode,
218                          Listener* listener)
219     : mode_(mode),
220       listener_(listener),
221       peer_pid_(base::kNullProcessId),
222       weak_factory_(this) {
223   // Create MojoBootstrap after all members are set as it touches
224   // ChannelMojo from a different thread.
225   bootstrap_ = MojoBootstrap::Create(handle, mode, this);
226   if (delegate) {
227     if (delegate->GetIOTaskRunner() ==
228         base::MessageLoop::current()->message_loop_proxy()) {
229       InitDelegate(delegate);
230     } else {
231       delegate->GetIOTaskRunner()->PostTask(
232           FROM_HERE,
233           base::Bind(
234               &ChannelMojo::InitDelegate, base::Unretained(this), delegate));
235     }
236   }
237 }
238
239 ChannelMojo::~ChannelMojo() {
240   Close();
241 }
242
243 void ChannelMojo::InitDelegate(ChannelMojo::Delegate* delegate) {
244   delegate_ = delegate->ToWeakPtr();
245   delegate_->OnChannelCreated(weak_factory_.GetWeakPtr());
246 }
247
248 mojo::ScopedMessagePipeHandle ChannelMojo::CreateMessagingPipe(
249     mojo::embedder::ScopedPlatformHandle handle) {
250   DCHECK(!channel_info_.get());
251   mojo::embedder::ChannelInfo* channel_info;
252   mojo::ScopedMessagePipeHandle pipe =
253       mojo::embedder::CreateChannelOnIOThread(handle.Pass(), &channel_info);
254   channel_info_.reset(channel_info);
255   return pipe.Pass();
256 }
257
258 bool ChannelMojo::Connect() {
259   DCHECK(!message_reader_);
260   return bootstrap_->Connect();
261 }
262
263 void ChannelMojo::Close() {
264   message_reader_.reset();
265   channel_info_.reset();
266 }
267
268 void ChannelMojo::OnBootstrapError() {
269   listener_->OnChannelError();
270 }
271
272 void ChannelMojo::InitMessageReader(mojo::ScopedMessagePipeHandle pipe,
273                                     int32_t peer_pid) {
274   message_reader_ =
275       make_scoped_ptr(new internal::MessageReader(pipe.Pass(), this));
276
277   for (size_t i = 0; i < pending_messages_.size(); ++i) {
278     bool sent = message_reader_->Send(make_scoped_ptr(pending_messages_[i]));
279     pending_messages_[i] = NULL;
280     if (!sent) {
281       pending_messages_.clear();
282       listener_->OnChannelError();
283       return;
284     }
285   }
286
287   pending_messages_.clear();
288
289   set_peer_pid(peer_pid);
290   listener_->OnChannelConnected(static_cast<int32_t>(GetPeerPID()));
291 }
292
293 void ChannelMojo::OnPipeClosed(internal::MessagePipeReader* reader) {
294   Close();
295 }
296
297 void ChannelMojo::OnPipeError(internal::MessagePipeReader* reader) {
298   listener_->OnChannelError();
299 }
300
301
302 bool ChannelMojo::Send(Message* message) {
303   if (!message_reader_) {
304     pending_messages_.push_back(message);
305     return true;
306   }
307
308   return message_reader_->Send(make_scoped_ptr(message));
309 }
310
311 base::ProcessId ChannelMojo::GetPeerPID() const {
312   return peer_pid_;
313 }
314
315 base::ProcessId ChannelMojo::GetSelfPID() const {
316   return base::GetCurrentProcId();
317 }
318
319 void ChannelMojo::OnClientLaunched(base::ProcessHandle handle) {
320   bootstrap_->OnClientLaunched(handle);
321 }
322
323 void ChannelMojo::OnMessageReceived(Message& message) {
324   listener_->OnMessageReceived(message);
325   if (message.dispatch_error())
326     listener_->OnBadMessageReceived(message);
327 }
328
329 #if defined(OS_POSIX) && !defined(OS_NACL)
330 int ChannelMojo::GetClientFileDescriptor() const {
331   return bootstrap_->GetClientFileDescriptor();
332 }
333
334 base::ScopedFD ChannelMojo::TakeClientFileDescriptor() {
335   return bootstrap_->TakeClientFileDescriptor();
336 }
337
338 // static
339 MojoResult ChannelMojo::WriteToFileDescriptorSet(
340     const std::vector<MojoHandle>& handle_buffer,
341     Message* message) {
342   for (size_t i = 0; i < handle_buffer.size(); ++i) {
343     mojo::embedder::ScopedPlatformHandle platform_handle;
344     MojoResult unwrap_result = mojo::embedder::PassWrappedPlatformHandle(
345         handle_buffer[i], &platform_handle);
346     if (unwrap_result != MOJO_RESULT_OK) {
347       DLOG(WARNING) << "Pipe failed to covert handles. Closing: "
348                     << unwrap_result;
349       return unwrap_result;
350     }
351
352     bool ok = message->file_descriptor_set()->AddToOwn(
353         base::ScopedFD(platform_handle.release().fd));
354     DCHECK(ok);
355   }
356
357   return MOJO_RESULT_OK;
358 }
359
360 // static
361 MojoResult ChannelMojo::ReadFromFileDescriptorSet(
362     Message* message,
363     std::vector<MojoHandle>* handles) {
364   // We dup() the handles in IPC::Message to transmit.
365   // IPC::FileDescriptorSet has intricate lifecycle semantics
366   // of FDs, so just to dup()-and-own them is the safest option.
367   if (message->HasFileDescriptors()) {
368     FileDescriptorSet* fdset = message->file_descriptor_set();
369     std::vector<base::PlatformFile> fds_to_send(fdset->size());
370     fdset->PeekDescriptors(&fds_to_send[0]);
371     for (size_t i = 0; i < fds_to_send.size(); ++i) {
372       int fd_to_send = dup(fds_to_send[i]);
373       if (-1 == fd_to_send) {
374         DPLOG(WARNING) << "Failed to dup FD to transmit.";
375         fdset->CommitAll();
376         return MOJO_RESULT_UNKNOWN;
377       }
378
379       MojoHandle wrapped_handle;
380       MojoResult wrap_result = CreatePlatformHandleWrapper(
381           mojo::embedder::ScopedPlatformHandle(
382               mojo::embedder::PlatformHandle(fd_to_send)),
383           &wrapped_handle);
384       if (MOJO_RESULT_OK != wrap_result) {
385         DLOG(WARNING) << "Pipe failed to wrap handles. Closing: "
386                       << wrap_result;
387         fdset->CommitAll();
388         return wrap_result;
389       }
390
391       handles->push_back(wrapped_handle);
392     }
393
394     fdset->CommitAll();
395   }
396
397   return MOJO_RESULT_OK;
398 }
399
400 #endif  // defined(OS_POSIX) && !defined(OS_NACL)
401
402 }  // namespace IPC