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)
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ipc/ipc_channel_proxy.h"
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ipc/ipc_channel_factory.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_listener.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_logging.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_macros.h"
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ipc/message_filter.h"
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ipc/message_filter_router.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciChannelProxy::Context::Context(
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Listener* listener,
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : listener_task_runner_(base::ThreadTaskRunnerHandle::Get()),
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      listener_(listener),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ipc_task_runner_(ipc_task_runner),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      channel_connected_called_(false),
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      message_filter_router_(new MessageFilterRouter()),
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      peer_pid_(base::kNullProcessId) {
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(ipc_task_runner_.get());
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The Listener thread where Messages are handled must be a separate thread
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // to avoid oversubscribing the IO thread. If you trigger this error, you
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // need to either:
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // 1) Create the ChannelProxy on a different thread, or
390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // 2) Just use Channel
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Note, we currently make an exception for a NULL listener. That usage
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // basically works, but is outside the intent of ChannelProxy. This support
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // will disappear, so please don't rely on it. See crbug.com/364241
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(!listener || (ipc_task_runner_.get() != listener_task_runner_.get()));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::Context::~Context() {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::ClearIPCTaskRunner() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc_task_runner_ = NULL;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChannelProxy::Context::CreateChannel(scoped_ptr<ChannelFactory> factory) {
5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(!channel_);
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  channel_id_ = factory->GetName();
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  channel_ = factory->BuildChannel(this);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Context::TryFilters(const Message& message) {
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(message_filter_router_);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Logging* logger = Logging::GetInstance();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (logger->Enabled())
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger->OnPreDispatchMessage(message);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (message_filter_router_->TryFilters(message)) {
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (message.dispatch_error()) {
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      listener_task_runner_->PostTask(
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          FROM_HERE, base::Bind(&Context::OnDispatchBadMessage, this, message));
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (logger->Enabled())
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      logger->OnPostDispatchMessage(message, channel_id_);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Context::OnMessageReceived(const Message& message) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First give a chance to the filters to process this message.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!TryFilters(message))
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnMessageReceivedNoFilter(message);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_task_runner_->PostTask(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnDispatchMessage, this, message));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelConnected(int32 peer_pid) {
9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // We cache off the peer_pid so it can be safely accessed from both threads.
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  peer_pid_ = channel_->GetPeerPID();
10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add any pending filters.  This avoids a race condition where someone
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // creates a ChannelProxy, calls AddFilter, and then right after starts the
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // peer process.  The IO thread could receive a message before the task to add
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the filter is run on the IO thread.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnAddFilter();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See above comment about using listener_task_runner_ here.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_task_runner_->PostTask(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnDispatchConnected, this));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelError() {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); ++i)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_[i]->OnChannelError();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See above comment about using listener_task_runner_ here.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_task_runner_->PostTask(
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnDispatchError, this));
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelOpened() {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(channel_ != NULL);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume a reference to ourselves on behalf of this thread.  This reference
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be released when we are closed.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRef();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!channel_->Connect()) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnChannelError();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); ++i)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_[i]->OnFilterAdded(channel_.get());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnChannelClosed() {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It's okay for IPC::ChannelProxy::Close to be called more than once, which
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // would result in this branch being taken.
14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!channel_)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); ++i) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_[i]->OnChannelClosing();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_[i]->OnFilterRemoved();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't need the filters anymore.
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message_filter_router_->Clear();
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  filters_.clear();
15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // We don't need the lock, because at this point, the listener thread can't
15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // access it any more.
15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  pending_filters_.clear();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_.reset();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Balance with the reference taken during startup.  This may result in
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // self-destruction.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::Clear() {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_ = NULL;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnSendMessage(scoped_ptr<Message> message) {
17123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!channel_) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnChannelClosed();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!channel_->Send(message.release()))
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnChannelError();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the IPC::Channel thread
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnAddFilter() {
18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Our OnChannelConnected method has not yet been called, so we can't be
18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // sure that channel_ is valid yet. When OnChannelConnected *is* called,
18423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // it invokes OnAddFilter, so any pending filter(s) will be added at that
18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // time.
18623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (peer_pid_ == base::kNullProcessId)
18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return;
18823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<scoped_refptr<MessageFilter> > new_filters;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock auto_lock(pending_filters_lock_);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_filters.swap(pending_filters_);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < new_filters.size(); ++i) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    filters_.push_back(new_filters[i]);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_filter_router_->AddFilter(new_filters[i].get());
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // The channel has already been created and connected, so we need to
20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // inform the filters right now.
20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    new_filters[i]->OnFilterAdded(channel_.get());
20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (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) {
20923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (peer_pid_ == base::kNullProcessId) {
21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // The channel is not yet connected, so any filters are still pending.
21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    base::AutoLock auto_lock(pending_filters_lock_);
21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    for (size_t i = 0; i < pending_filters_.size(); ++i) {
21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      if (pending_filters_[i].get() == filter) {
21423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        filter->OnFilterRemoved();
21523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        pending_filters_.erase(pending_filters_.begin() + i);
21623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        return;
21723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      }
21823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
21923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return;
22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!channel_)
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;  // The filters have already been deleted.
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message_filter_router_->RemoveFilter(filter);
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < filters_.size(); ++i) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (filters_[i].get() == filter) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      filter->OnFilterRemoved();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      filters_.erase(filters_.begin() + i);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED() << "filter to be removed not found";
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::AddFilter(MessageFilter* filter) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock auto_lock(pending_filters_lock_);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_filters_.push_back(make_scoped_refptr(filter));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc_task_runner_->PostTask(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnAddFilter, this));
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnDispatchMessage(const Message& message) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Logging* logger = Logging::GetInstance();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logger->GetMessageText(message.type(), &name, &message, NULL);
251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  TRACE_EVENT1("ipc", "ChannelProxy::Context::OnDispatchMessage",
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "name", name);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  TRACE_EVENT2("ipc", "ChannelProxy::Context::OnDispatchMessage",
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "class", IPC_MESSAGE_ID_CLASS(message.type()),
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "line", IPC_MESSAGE_ID_LINE(message.type()));
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!listener_)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnDispatchConnected();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message.type() == IPC_LOGGING_ID) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger->OnReceivedLoggingMessage(message);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (logger->Enabled())
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger->OnPreDispatchMessage(message);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listener_->OnMessageReceived(message);
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (message.dispatch_error())
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    listener_->OnBadMessageReceived(message);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (logger->Enabled())
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger->OnPostDispatchMessage(message, channel_id_);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnDispatchConnected() {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (channel_connected_called_)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_connected_called_ = true;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (listener_)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->OnChannelConnected(peer_pid_);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called on the listener's thread
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Context::OnDispatchError() {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (listener_)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listener_->OnChannelError();
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called on the listener's thread
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ChannelProxy::Context::OnDispatchBadMessage(const Message& message) {
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (listener_)
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    listener_->OnBadMessageReceived(message);
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static
30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)scoped_ptr<ChannelProxy> ChannelProxy::Create(
31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const IPC::ChannelHandle& channel_handle,
31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    Channel::Mode mode,
31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    Listener* listener,
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<ChannelProxy> channel(new ChannelProxy(listener, ipc_task_runner));
31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  channel->Init(channel_handle, mode, true);
31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return channel.Pass();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_ptr<ChannelProxy> ChannelProxy::Create(
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<ChannelFactory> factory,
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Listener* listener,
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<ChannelProxy> channel(new ChannelProxy(listener, ipc_task_runner));
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  channel->Init(factory.Pass(), true);
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return channel.Pass();
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::ChannelProxy(Context* context)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : context_(context),
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      did_init_(false) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciChannelProxy::ChannelProxy(
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Listener* listener,
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner)
33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    : context_(new Context(listener, ipc_task_runner)), did_init_(false) {
33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelProxy::~ChannelProxy() {
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Close();
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Init(const IPC::ChannelHandle& channel_handle,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        Channel::Mode mode,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        bool create_pipe_now) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When we are creating a server on POSIX, we need its file descriptor
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to be created immediately so that it can be accessed and passed
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to other processes. Forcing it to be created immediately avoids
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // race conditions that may otherwise arise.
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mode & Channel::MODE_SERVER_FLAG) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    create_pipe_now = true;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_POSIX)
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Init(ChannelFactory::Create(channel_handle, mode),
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       create_pipe_now);
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ChannelProxy::Init(scoped_ptr<ChannelFactory> factory,
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        bool create_pipe_now) {
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(CalledOnValidThread());
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!did_init_);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (create_pipe_now) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create the channel immediately.  This effectively sets up the
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // low-level pipe so that the client can connect.  Without creating
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the pipe immediately, it is possible for a listener to attempt
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to connect and get an error since the pipe doesn't exist yet.
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    context_->CreateChannel(factory.Pass());
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->ipc_task_runner()->PostTask(
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        FROM_HERE, base::Bind(&Context::CreateChannel,
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              context_.get(), Passed(factory.Pass())));
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // complete initialization on the background thread
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->ipc_task_runner()->PostTask(
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnChannelOpened, context_.get()));
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  did_init_ = true;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::Close() {
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the backpointer to the listener so that any pending calls to
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Context::OnDispatchMessage or OnDispatchError will be ignored.  It is
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // possible that the channel could be closed while it is receiving messages!
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->Clear();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (context_->ipc_task_runner()) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_->ipc_task_runner()->PostTask(
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE, base::Bind(&Context::OnChannelClosed, context_.get()));
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelProxy::Send(Message* message) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(did_init_);
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(alexeypa): add DCHECK(CalledOnValidThread()) here. Currently there are
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // tests that call Send() from a wrong thread. See http://crbug.com/163523.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Logging::GetInstance()->OnSendMessage(message, context_->channel_id());
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->ipc_task_runner()->PostTask(
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ChannelProxy::Context::OnSendMessage,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 context_, base::Passed(scoped_ptr<Message>(message))));
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::AddFilter(MessageFilter* filter) {
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->AddFilter(filter);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::RemoveFilter(MessageFilter* filter) {
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->ipc_task_runner()->PostTask(
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE, base::Bind(&Context::OnRemoveFilter, context_.get(),
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            make_scoped_refptr(filter)));
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelProxy::ClearIPCTaskRunner() {
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context()->ClearIPCTaskRunner();
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_NACL)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See the TODO regarding lazy initialization of the channel in
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ChannelProxy::Init().
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChannelProxy::GetClientFileDescriptor() {
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Channel* channel = context_.get()->channel_.get();
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Channel must have been created first.
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(channel) << context_.get()->channel_id_;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return channel->GetClientFileDescriptor();
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChannelProxy::TakeClientFileDescriptor() {
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Channel* channel = context_.get()->channel_.get();
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Channel must have been created first.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(channel) << context_.get()->channel_id_;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return channel->TakeClientFileDescriptor();
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace IPC
462