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