| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "ppapi/proxy/proxy_channel.h" | |
| #include "base/logging.h" | |
| #include "build/build_config.h" | |
| #include "ipc/ipc_platform_file.h" | |
| #include "ipc/ipc_test_sink.h" | |
| #if defined(OS_NACL) | |
| #include <unistd.h> | |
| #endif | |
| namespace ppapi { | |
| namespace proxy { | |
| ProxyChannel::ProxyChannel() | |
| : delegate_(NULL), | |
| peer_pid_(base::kNullProcessId), | |
| test_sink_(NULL) { | |
| } | |
| ProxyChannel::~ProxyChannel() { | |
| DVLOG(1) << "ProxyChannel::~ProxyChannel()"; | |
| } | |
| bool ProxyChannel::InitWithChannel(Delegate* delegate, | |
| base::ProcessId peer_pid, | |
| const IPC::ChannelHandle& channel_handle, | |
| bool is_client) { | |
| delegate_ = delegate; | |
| peer_pid_ = peer_pid; | |
| IPC::Channel::Mode mode = is_client | |
| ? IPC::Channel::MODE_CLIENT | |
| : IPC::Channel::MODE_SERVER; | |
| channel_ = IPC::SyncChannel::Create( | |
| channel_handle, mode, this, delegate->GetIPCTaskRunner(), | |
| base::ThreadTaskRunnerHandle::Get(), true, delegate->GetShutdownEvent()); | |
| return true; | |
| } | |
| void ProxyChannel::InitWithTestSink(IPC::TestSink* test_sink) { | |
| DCHECK(!test_sink_); | |
| test_sink_ = test_sink; | |
| #if !defined(OS_NACL) | |
| peer_pid_ = base::GetCurrentProcId(); | |
| #endif | |
| } | |
| void ProxyChannel::OnChannelError() { | |
| channel_.reset(); | |
| } | |
| IPC::PlatformFileForTransit ProxyChannel::ShareHandleWithRemote( | |
| base::PlatformFile handle, | |
| bool should_close_source) { | |
| // Channel could be closed if the plugin crashes. | |
| if (!channel_.get()) { | |
| if (should_close_source) { | |
| base::File file_closer(handle); | |
| } | |
| return IPC::InvalidPlatformFileForTransit(); | |
| } | |
| DCHECK(peer_pid_ != base::kNullProcessId); | |
| return delegate_->ShareHandleWithRemote(handle, peer_pid_, | |
| should_close_source); | |
| } | |
| base::SharedMemoryHandle ProxyChannel::ShareSharedMemoryHandleWithRemote( | |
| const base::SharedMemoryHandle& handle) { | |
| if (!channel_.get()) | |
| return base::SharedMemoryHandle(); | |
| DCHECK(peer_pid_ != base::kNullProcessId); | |
| return delegate_->ShareSharedMemoryHandleWithRemote(handle, peer_pid_); | |
| } | |
| base::UnsafeSharedMemoryRegion | |
| ProxyChannel::ShareUnsafeSharedMemoryRegionWithRemote( | |
| const base::UnsafeSharedMemoryRegion& region) { | |
| if (!channel_.get()) | |
| return base::UnsafeSharedMemoryRegion(); | |
| DCHECK(peer_pid_ != base::kNullProcessId); | |
| return delegate_->ShareUnsafeSharedMemoryRegionWithRemote(region, peer_pid_); | |
| } | |
| base::ReadOnlySharedMemoryRegion | |
| ProxyChannel::ShareReadOnlySharedMemoryRegionWithRemote( | |
| const base::ReadOnlySharedMemoryRegion& region) { | |
| if (!channel_.get()) | |
| return base::ReadOnlySharedMemoryRegion(); | |
| DCHECK(peer_pid_ != base::kNullProcessId); | |
| return delegate_->ShareReadOnlySharedMemoryRegionWithRemote(region, | |
| peer_pid_); | |
| } | |
| bool ProxyChannel::Send(IPC::Message* msg) { | |
| if (test_sink_) | |
| return test_sink_->Send(msg); | |
| if (channel_.get()) | |
| return channel_->Send(msg); | |
| // Remote side crashed, drop this message. | |
| delete msg; | |
| return false; | |
| } | |
| } // namespace proxy | |
| } // namespace ppapi |