15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_proxy.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_listener.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_logging.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_macros.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_utils.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::MessageFilter::MessageFilter() {}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::MessageFilter::OnFilterAdded(Channel* channel) {}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::MessageFilter::OnFilterRemoved() {}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::MessageFilter::OnChannelConnected(int32 peer_pid) {}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::MessageFilter::OnChannelError() {}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::MessageFilter::OnChannelClosing() {}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::MessageFilter::OnMessageReceived(const Message& message) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::MessageFilter::OnDestruct() const {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::MessageFilter::~MessageFilter() {}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::Context::Context(Listener* listener,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base::SingleThreadTaskRunner* ipc_task_runner)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : listener_task_runner_(base::ThreadTaskRunnerHandle::Get()),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      listener_(listener),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ipc_task_runner_(ipc_task_runner),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      channel_connected_called_(false),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      peer_pid_(base::kNullProcessId) {
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(ipc_task_runner_.get());
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::Context::~Context() {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::ClearIPCTaskRunner() {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc_task_runner_ = NULL;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::CreateChannel(const IPC::ChannelHandle& handle,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const Channel::Mode& mode) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(channel_.get() == NULL);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_id_ = handle.name;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_.reset(new Channel(handle, mode, this));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Context::TryFilters(const Message& message) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Logging* logger = Logging::GetInstance();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (logger->Enabled())
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger->OnPreDispatchMessage(message);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); ++i) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (filters_[i]->OnMessageReceived(message)) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (logger->Enabled())
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        logger->OnPostDispatchMessage(message, channel_id_);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Context::OnMessageReceived(const Message& message) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First give a chance to the filters to process this message.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!TryFilters(message))
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnMessageReceivedNoFilter(message);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: This code relies on the listener's message loop not going away while
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this thread is active.  That should be a reasonable assumption, but it
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // feels risky.  We may want to invent some more indirect way of referring to
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a MessageLoop if this becomes a problem.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_task_runner_->PostTask(
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnDispatchMessage, this, message));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelConnected(int32 peer_pid) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add any pending filters.  This avoids a race condition where someone
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // creates a ChannelProxy, calls AddFilter, and then right after starts the
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // peer process.  The IO thread could receive a message before the task to add
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the filter is run on the IO thread.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnAddFilter();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We cache off the peer_pid so it can be safely accessed from both threads.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  peer_pid_ = channel_->peer_pid();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); ++i)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_[i]->OnChannelConnected(peer_pid);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See above comment about using listener_task_runner_ here.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_task_runner_->PostTask(
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnDispatchConnected, this));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelError() {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); ++i)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_[i]->OnChannelError();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See above comment about using listener_task_runner_ here.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_task_runner_->PostTask(
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnDispatchError, this));
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelOpened() {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(channel_ != NULL);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume a reference to ourselves on behalf of this thread.  This reference
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be released when we are closed.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRef();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!channel_->Connect()) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnChannelError();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); ++i)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_[i]->OnFilterAdded(channel_.get());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelClosed() {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It's okay for IPC::ChannelProxy::Close to be called more than once, which
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // would result in this branch being taken.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!channel_.get())
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); ++i) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_[i]->OnChannelClosing();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_[i]->OnFilterRemoved();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't need the filters anymore.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filters_.clear();
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_.reset();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Balance with the reference taken during startup.  This may result in
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // self-destruction.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::Clear() {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_ = NULL;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnSendMessage(scoped_ptr<Message> message) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!channel_.get()) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnChannelClosed();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!channel_->Send(message.release()))
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnChannelError();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnAddFilter() {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<scoped_refptr<MessageFilter> > new_filters;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock auto_lock(pending_filters_lock_);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_filters.swap(pending_filters_);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < new_filters.size(); ++i) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_.push_back(new_filters[i]);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the channel has already been created, then we need to send this
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // message so that the filter gets access to the Channel.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (channel_.get())
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_filters[i]->OnFilterAdded(channel_.get());
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ditto for if the channel has been connected.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (peer_pid_)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_filters[i]->OnChannelConnected(peer_pid_);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnRemoveFilter(MessageFilter* filter) {
2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!channel_.get())
2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;  // The filters have already been deleted.
2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); ++i) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (filters_[i].get() == filter) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      filter->OnFilterRemoved();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      filters_.erase(filters_.begin() + i);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED() << "filter to be removed not found";
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::AddFilter(MessageFilter* filter) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock auto_lock(pending_filters_lock_);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_filters_.push_back(make_scoped_refptr(filter));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc_task_runner_->PostTask(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnAddFilter, this));
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnDispatchMessage(const Message& message) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Logging* logger = Logging::GetInstance();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logger->GetMessageText(message.type(), &name, &message, NULL);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT1("task", "ChannelProxy::Context::OnDispatchMessage",
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "name", name);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT2("task", "ChannelProxy::Context::OnDispatchMessage",
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "class", IPC_MESSAGE_ID_CLASS(message.type()),
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "line", IPC_MESSAGE_ID_LINE(message.type()));
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!listener_)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnDispatchConnected();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message.type() == IPC_LOGGING_ID) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger->OnReceivedLoggingMessage(message);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (logger->Enabled())
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger->OnPreDispatchMessage(message);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_->OnMessageReceived(message);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (logger->Enabled())
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger->OnPostDispatchMessage(message, channel_id_);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnDispatchConnected() {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (channel_connected_called_)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_connected_called_ = true;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (listener_)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->OnChannelConnected(peer_pid_);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnDispatchError() {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (listener_)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->OnChannelError();
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::ChannelProxy(const IPC::ChannelHandle& channel_handle,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           Channel::Mode mode,
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           Listener* listener,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base::SingleThreadTaskRunner* ipc_task_runner)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : context_(new Context(listener, ipc_task_runner)),
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outgoing_message_filter_(NULL),
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      did_init_(false) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Init(channel_handle, mode, true);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::ChannelProxy(Context* context)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : context_(context),
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outgoing_message_filter_(NULL),
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      did_init_(false) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::~ChannelProxy() {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Close();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Init(const IPC::ChannelHandle& channel_handle,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        Channel::Mode mode,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        bool create_pipe_now) {
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!did_init_);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When we are creating a server on POSIX, we need its file descriptor
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to be created immediately so that it can be accessed and passed
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to other processes. Forcing it to be created immediately avoids
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // race conditions that may otherwise arise.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mode & Channel::MODE_SERVER_FLAG) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    create_pipe_now = true;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_POSIX)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (create_pipe_now) {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create the channel immediately.  This effectively sets up the
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // low-level pipe so that the client can connect.  Without creating
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the pipe immediately, it is possible for a listener to attempt
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to connect and get an error since the pipe doesn't exist yet.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->CreateChannel(channel_handle, mode);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->ipc_task_runner()->PostTask(
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE, base::Bind(&Context::CreateChannel, context_.get(),
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              channel_handle, mode));
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // complete initialization on the background thread
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->ipc_task_runner()->PostTask(
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnChannelOpened, context_.get()));
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  did_init_ = true;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Close() {
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the backpointer to the listener so that any pending calls to
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Context::OnDispatchMessage or OnDispatchError will be ignored.  It is
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // possible that the channel could be closed while it is receiving messages!
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->Clear();
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (context_->ipc_task_runner()) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->ipc_task_runner()->PostTask(
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE, base::Bind(&Context::OnChannelClosed, context_.get()));
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Send(Message* message) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(did_init_);
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(alexeypa): add DCHECK(CalledOnValidThread()) here. Currently there are
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // tests that call Send() from a wrong thread. See http://crbug.com/163523.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (outgoing_message_filter())
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message = outgoing_message_filter()->Rewrite(message);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Logging::GetInstance()->OnSendMessage(message, context_->channel_id());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->ipc_task_runner()->PostTask(
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ChannelProxy::Context::OnSendMessage,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 context_, base::Passed(scoped_ptr<Message>(message))));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::AddFilter(MessageFilter* filter) {
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->AddFilter(filter);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::RemoveFilter(MessageFilter* filter) {
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->ipc_task_runner()->PostTask(
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnRemoveFilter, context_.get(),
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            make_scoped_refptr(filter)));
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::ClearIPCTaskRunner() {
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context()->ClearIPCTaskRunner();
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_NACL)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See the TODO regarding lazy initialization of the channel in
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ChannelProxy::Init().
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChannelProxy::GetClientFileDescriptor() {
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Channel* channel = context_.get()->channel_.get();
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Channel must have been created first.
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(channel) << context_.get()->channel_id_;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return channel->GetClientFileDescriptor();
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChannelProxy::TakeClientFileDescriptor() {
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Channel* channel = context_.get()->channel_.get();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Channel must have been created first.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(channel) << context_.get()->channel_id_;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return channel->TakeClientFileDescriptor();
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ChannelProxy::GetPeerEuid(uid_t* peer_euid) const {
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Channel* channel = context_.get()->channel_.get();
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Channel must have been created first.
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(channel) << context_.get()->channel_id_;
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return channel->GetPeerEuid(peer_euid);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace IPC
433