blob: beb18ee5e99ffc53d7159d1b6cb4c68b8cdcd398 [file] [log] [blame]
// 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/message_loop/message_loop.h"
#include "ipc/mojo/ipc_channel_mojo.h"
namespace IPC {
// 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 ChannelMojo::Delegate {
public:
explicit ChannelDelegate(scoped_refptr<base::TaskRunner> io_task_runner);
~ChannelDelegate() override;
// ChannelMojo::Delegate
base::WeakPtr<Delegate> ToWeakPtr() override;
void OnChannelCreated(base::WeakPtr<ChannelMojo> channel) override;
scoped_refptr<base::TaskRunner> GetIOTaskRunner() override;
// Returns an weak ptr of ChannelDelegate instead of Delegate
base::WeakPtr<ChannelDelegate> GetWeakPtr();
void OnClientLaunched(base::ProcessHandle process);
void DeleteThisSoon();
private:
scoped_refptr<base::TaskRunner> io_task_runner_;
base::WeakPtr<ChannelMojo> channel_;
base::WeakPtrFactory<ChannelDelegate> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ChannelDelegate);
};
ChannelMojoHost::ChannelDelegate::ChannelDelegate(
scoped_refptr<base::TaskRunner> io_task_runner)
: io_task_runner_(io_task_runner), weak_factory_(this) {
}
ChannelMojoHost::ChannelDelegate::~ChannelDelegate() {
}
base::WeakPtr<ChannelMojo::Delegate>
ChannelMojoHost::ChannelDelegate::ToWeakPtr() {
return weak_factory_.GetWeakPtr();
}
base::WeakPtr<ChannelMojoHost::ChannelDelegate>
ChannelMojoHost::ChannelDelegate::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void ChannelMojoHost::ChannelDelegate::OnChannelCreated(
base::WeakPtr<ChannelMojo> channel) {
DCHECK(!channel_);
channel_ = channel;
}
scoped_refptr<base::TaskRunner>
ChannelMojoHost::ChannelDelegate::GetIOTaskRunner() {
return io_task_runner_;
}
void ChannelMojoHost::ChannelDelegate::OnClientLaunched(
base::ProcessHandle process) {
if (channel_)
channel_->OnClientLaunched(process);
}
void ChannelMojoHost::ChannelDelegate::DeleteThisSoon() {
io_task_runner_->PostTask(
FROM_HERE,
base::Bind(&base::DeletePointer<ChannelMojoHost::ChannelDelegate>,
base::Unretained(this)));
}
//
// ChannelMojoHost
//
ChannelMojoHost::ChannelMojoHost(scoped_refptr<base::TaskRunner> 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()->message_loop_proxy()) {
channel_delegate_->OnClientLaunched(process);
} else {
io_task_runner_->PostTask(FROM_HERE,
base::Bind(&ChannelDelegate::OnClientLaunched,
channel_delegate_->GetWeakPtr(),
process));
}
}
ChannelMojo::Delegate* ChannelMojoHost::channel_delegate() const {
return channel_delegate_.get();
}
void ChannelMojoHost::DelegateDeleter::operator()(
ChannelMojoHost::ChannelDelegate* ptr) const {
ptr->DeleteThisSoon();
}
} // namespace IPC