Home | History | Annotate | Download | only in mojo
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ipc/mojo/ipc_channel_mojo_host.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "ipc/mojo/ipc_channel_mojo.h"
     10 
     11 namespace IPC {
     12 
     13 // The delete class lives on the IO thread to talk to ChannelMojo on
     14 // behalf of ChannelMojoHost.
     15 //
     16 // The object must be touched only on the IO thread.
     17 class ChannelMojoHost::ChannelDelegate : public ChannelMojo::Delegate {
     18  public:
     19   explicit ChannelDelegate(scoped_refptr<base::TaskRunner> io_task_runner);
     20   virtual ~ChannelDelegate();
     21 
     22   // ChannelMojo::Delegate
     23   virtual base::WeakPtr<Delegate> ToWeakPtr() OVERRIDE;
     24   virtual void OnChannelCreated(base::WeakPtr<ChannelMojo> channel) OVERRIDE;
     25   virtual scoped_refptr<base::TaskRunner> GetIOTaskRunner() OVERRIDE;
     26 
     27   // Returns an weak ptr of ChannelDelegate instead of Delegate
     28   base::WeakPtr<ChannelDelegate> GetWeakPtr();
     29   void OnClientLaunched(base::ProcessHandle process);
     30   void DeleteThisSoon();
     31 
     32  private:
     33   scoped_refptr<base::TaskRunner> io_task_runner_;
     34   base::WeakPtrFactory<ChannelDelegate> weak_factory_;
     35   base::WeakPtr<ChannelMojo> channel_;
     36 
     37   DISALLOW_COPY_AND_ASSIGN(ChannelDelegate);
     38 };
     39 
     40 ChannelMojoHost::ChannelDelegate::ChannelDelegate(
     41     scoped_refptr<base::TaskRunner> io_task_runner)
     42     : io_task_runner_(io_task_runner), weak_factory_(this) {
     43 }
     44 
     45 ChannelMojoHost::ChannelDelegate::~ChannelDelegate() {
     46 }
     47 
     48 base::WeakPtr<ChannelMojo::Delegate>
     49 ChannelMojoHost::ChannelDelegate::ToWeakPtr() {
     50   return weak_factory_.GetWeakPtr();
     51 }
     52 
     53 base::WeakPtr<ChannelMojoHost::ChannelDelegate>
     54 ChannelMojoHost::ChannelDelegate::GetWeakPtr() {
     55   return weak_factory_.GetWeakPtr();
     56 }
     57 
     58 void ChannelMojoHost::ChannelDelegate::OnChannelCreated(
     59     base::WeakPtr<ChannelMojo> channel) {
     60   DCHECK(!channel_);
     61   channel_ = channel;
     62 }
     63 
     64 scoped_refptr<base::TaskRunner>
     65 ChannelMojoHost::ChannelDelegate::GetIOTaskRunner() {
     66   return io_task_runner_;
     67 }
     68 
     69 void ChannelMojoHost::ChannelDelegate::OnClientLaunched(
     70     base::ProcessHandle process) {
     71   if (channel_)
     72     channel_->OnClientLaunched(process);
     73 }
     74 
     75 void ChannelMojoHost::ChannelDelegate::DeleteThisSoon() {
     76   io_task_runner_->PostTask(
     77       FROM_HERE,
     78       base::Bind(&base::DeletePointer<ChannelMojoHost::ChannelDelegate>,
     79                  base::Unretained(this)));
     80 }
     81 
     82 //
     83 // ChannelMojoHost
     84 //
     85 
     86 ChannelMojoHost::ChannelMojoHost(scoped_refptr<base::TaskRunner> io_task_runner)
     87     : weak_factory_(this),
     88       io_task_runner_(io_task_runner),
     89       channel_delegate_(new ChannelDelegate(io_task_runner)) {
     90 }
     91 
     92 ChannelMojoHost::~ChannelMojoHost() {
     93 }
     94 
     95 void ChannelMojoHost::OnClientLaunched(base::ProcessHandle process) {
     96   if (io_task_runner_ == base::MessageLoop::current()->message_loop_proxy()) {
     97     channel_delegate_->OnClientLaunched(process);
     98   } else {
     99     io_task_runner_->PostTask(FROM_HERE,
    100                               base::Bind(&ChannelDelegate::OnClientLaunched,
    101                                          channel_delegate_->GetWeakPtr(),
    102                                          process));
    103   }
    104 }
    105 
    106 ChannelMojo::Delegate* ChannelMojoHost::channel_delegate() const {
    107   return channel_delegate_.get();
    108 }
    109 
    110 void ChannelMojoHost::DelegateDeleter::operator()(
    111     ChannelMojoHost::ChannelDelegate* ptr) const {
    112   ptr->DeleteThisSoon();
    113 }
    114 
    115 }  // namespace IPC
    116