Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2012 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 "ppapi/proxy/proxy_channel.h"
      6 
      7 #include "base/logging.h"
      8 #include "ipc/ipc_platform_file.h"
      9 #include "ipc/ipc_test_sink.h"
     10 
     11 #if defined(OS_NACL)
     12 #include <unistd.h>
     13 #endif
     14 
     15 namespace ppapi {
     16 namespace proxy {
     17 
     18 ProxyChannel::ProxyChannel()
     19     : delegate_(NULL),
     20       peer_pid_(base::kNullProcessId),
     21       test_sink_(NULL) {
     22 }
     23 
     24 ProxyChannel::~ProxyChannel() {
     25   DVLOG(1) << "ProxyChannel::~ProxyChannel()";
     26 }
     27 
     28 bool ProxyChannel::InitWithChannel(Delegate* delegate,
     29                                    base::ProcessId peer_pid,
     30                                    const IPC::ChannelHandle& channel_handle,
     31                                    bool is_client) {
     32   delegate_ = delegate;
     33   peer_pid_ = peer_pid;
     34   IPC::Channel::Mode mode = is_client ? IPC::Channel::MODE_CLIENT
     35                                       : IPC::Channel::MODE_SERVER;
     36   channel_.reset(new IPC::SyncChannel(channel_handle, mode, this,
     37                                       delegate->GetIPCMessageLoop(), true,
     38                                       delegate->GetShutdownEvent()));
     39   return true;
     40 }
     41 
     42 void ProxyChannel::InitWithTestSink(IPC::TestSink* test_sink) {
     43   DCHECK(!test_sink_);
     44   test_sink_ = test_sink;
     45 #if !defined(OS_NACL)
     46   peer_pid_ = base::GetCurrentProcId();
     47 #endif
     48 }
     49 
     50 void ProxyChannel::OnChannelError() {
     51   channel_.reset();
     52 }
     53 
     54 #if defined(OS_POSIX) && !defined(OS_NACL)
     55 int ProxyChannel::TakeRendererFD() {
     56   DCHECK(channel());
     57   return channel()->TakeClientFileDescriptor();
     58 }
     59 #endif
     60 
     61 IPC::PlatformFileForTransit ProxyChannel::ShareHandleWithRemote(
     62       base::PlatformFile handle,
     63       bool should_close_source) {
     64   // Channel could be closed if the plugin crashes.
     65   if (!channel_.get()) {
     66     if (should_close_source) {
     67 #if !defined(OS_NACL)
     68       base::ClosePlatformFile(handle);
     69 #else
     70       close(handle);
     71 #endif
     72     }
     73     return IPC::InvalidPlatformFileForTransit();
     74   }
     75   DCHECK(peer_pid_ != base::kNullProcessId);
     76   return delegate_->ShareHandleWithRemote(handle, peer_pid_,
     77                                           should_close_source);
     78 }
     79 
     80 bool ProxyChannel::Send(IPC::Message* msg) {
     81   if (test_sink_)
     82     return test_sink_->Send(msg);
     83   if (channel_.get())
     84     return channel_->Send(msg);
     85 
     86   // Remote side crashed, drop this message.
     87   delete msg;
     88   return false;
     89 }
     90 
     91 }  // namespace proxy
     92 }  // namespace ppapi
     93