// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ipc/mojo/ipc_channel_mojo_host.h" #include "base/bind.h" #include "base/location.h" #include "base/single_thread_task_runner.h" #include "ipc/mojo/ipc_channel_mojo.h" namespace IPC { class ChannelMojoHost::ChannelDelegateTraits { public: static void Destruct(const ChannelMojoHost::ChannelDelegate* ptr); }; // The delete class lives on the IO thread to talk to ChannelMojo on // behalf of ChannelMojoHost. // // The object must be touched only on the IO thread. class ChannelMojoHost::ChannelDelegate : public base::RefCountedThreadSafe, public ChannelMojo::Delegate { public: explicit ChannelDelegate( scoped_refptr io_task_runner); // ChannelMojo::Delegate base::WeakPtr ToWeakPtr() override; void OnChannelCreated(base::WeakPtr channel) override; // Returns an weak ptr of ChannelDelegate instead of Delegate base::WeakPtr GetWeakPtr(); void OnClientLaunched(base::ProcessHandle process); void DeleteThisSoon() const; private: friend class base::DeleteHelper; ~ChannelDelegate() override; scoped_refptr io_task_runner_; base::WeakPtr channel_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(ChannelDelegate); }; ChannelMojoHost::ChannelDelegate::ChannelDelegate( scoped_refptr io_task_runner) : io_task_runner_(io_task_runner), weak_factory_(this) { } ChannelMojoHost::ChannelDelegate::~ChannelDelegate() { } base::WeakPtr ChannelMojoHost::ChannelDelegate::ToWeakPtr() { return weak_factory_.GetWeakPtr(); } base::WeakPtr ChannelMojoHost::ChannelDelegate::GetWeakPtr() { return weak_factory_.GetWeakPtr(); } void ChannelMojoHost::ChannelDelegate::OnChannelCreated( base::WeakPtr channel) { DCHECK(!channel_); channel_ = channel; } void ChannelMojoHost::ChannelDelegate::OnClientLaunched( base::ProcessHandle process) { if (channel_) channel_->OnClientLaunched(process); } void ChannelMojoHost::ChannelDelegate::DeleteThisSoon() const { io_task_runner_->DeleteSoon(FROM_HERE, this); } // // ChannelMojoHost // ChannelMojoHost::ChannelMojoHost( scoped_refptr io_task_runner) : io_task_runner_(io_task_runner), channel_delegate_(new ChannelDelegate(io_task_runner)), weak_factory_(this) { } ChannelMojoHost::~ChannelMojoHost() { } void ChannelMojoHost::OnClientLaunched(base::ProcessHandle process) { if (io_task_runner_ == base::MessageLoop::current()->task_runner()) { channel_delegate_->OnClientLaunched(process); } else { io_task_runner_->PostTask(FROM_HERE, base::Bind(&ChannelDelegate::OnClientLaunched, channel_delegate_, process)); } } ChannelMojo::Delegate* ChannelMojoHost::channel_delegate() const { return channel_delegate_.get(); } // static void ChannelMojoHost::ChannelDelegateTraits::Destruct( const ChannelMojoHost::ChannelDelegate* ptr) { ptr->DeleteThisSoon(); } } // namespace IPC