blob: 34bf88a4766214b53d57a00dd351663a0756a986 [file] [log] [blame]
// Copyright 2015 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 "content/common/mojo/mojo_shell_connection_impl.h"
#include <utility>
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/stl_util.h"
#include "base/threading/thread_local.h"
#include "mojo/converters/network/network_type_converters.h"
#include "mojo/runner/child/runner_connection.h"
#include "mojo/shell/public/cpp/application_delegate.h"
#include "mojo/shell/public/cpp/application_impl.h"
namespace content {
namespace {
using MojoShellConnectionPtr =
base::ThreadLocalPointer<MojoShellConnectionImpl>;
// Env is thread local so that aura may be used on multiple threads.
base::LazyInstance<MojoShellConnectionPtr>::Leaky lazy_tls_ptr =
LAZY_INSTANCE_INITIALIZER;
} // namespace
bool IsRunningInMojoShell() {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
"mojo-platform-channel-handle");
}
// static
void MojoShellConnectionImpl::Create() {
DCHECK(!lazy_tls_ptr.Pointer()->Get());
MojoShellConnectionImpl* connection = new MojoShellConnectionImpl;
lazy_tls_ptr.Pointer()->Set(connection);
}
// static
MojoShellConnectionImpl* MojoShellConnectionImpl::Get() {
return static_cast<MojoShellConnectionImpl*>(MojoShellConnection::Get());
}
void MojoShellConnectionImpl::BindToCommandLinePlatformChannel() {
DCHECK(IsRunningInMojoShell());
if (initialized_)
return;
WaitForShell(mojo::ScopedMessagePipeHandle());
}
void MojoShellConnectionImpl::BindToMessagePipe(
mojo::ScopedMessagePipeHandle handle) {
if (initialized_)
return;
WaitForShell(std::move(handle));
}
MojoShellConnectionImpl::MojoShellConnectionImpl() : initialized_(false) {}
MojoShellConnectionImpl::~MojoShellConnectionImpl() {
STLDeleteElements(&listeners_);
}
void MojoShellConnectionImpl::WaitForShell(
mojo::ScopedMessagePipeHandle handle) {
mojo::InterfaceRequest<mojo::Application> application_request;
runner_connection_.reset(mojo::runner::RunnerConnection::ConnectToRunner(
&application_request, std::move(handle)));
application_impl_.reset(
new mojo::ApplicationImpl(this, std::move(application_request)));
application_impl_->WaitForInitialize();
}
void MojoShellConnectionImpl::Initialize(mojo::ApplicationImpl* application) {
initialized_ = true;
}
bool MojoShellConnectionImpl::ConfigureIncomingConnection(
mojo::ApplicationConnection* connection) {
bool found = false;
for (auto listener : listeners_)
found |= listener->ConfigureIncomingConnection(connection);
return found;
}
mojo::ApplicationImpl* MojoShellConnectionImpl::GetApplication() {
DCHECK(initialized_);
return application_impl_.get();
}
void MojoShellConnectionImpl::AddListener(Listener* listener) {
DCHECK(std::find(listeners_.begin(), listeners_.end(), listener) ==
listeners_.end());
listeners_.push_back(listener);
}
void MojoShellConnectionImpl::RemoveListener(Listener* listener) {
auto it = std::find(listeners_.begin(), listeners_.end(), listener);
DCHECK(it != listeners_.end());
listeners_.erase(it);
}
// static
MojoShellConnection* MojoShellConnection::Get() {
return lazy_tls_ptr.Pointer()->Get();
}
// static
void MojoShellConnection::Destroy() {
// This joins the shell controller thread.
delete Get();
lazy_tls_ptr.Pointer()->Set(nullptr);
}
MojoShellConnection::~MojoShellConnection() {}
} // namespace content