blob: 81f2443ba1b677722f7be858c59157738eee70a8 [file] [log] [blame] [edit]
/*
* Copyright 2018 The Chromium OS 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 "common/camera_mojo_channel_manager_impl.h"
#include <utility>
#include <base/bind.h>
#include <base/logging.h>
#include "cros-camera/common.h"
#include "cros-camera/constants.h"
#include "cros-camera/future.h"
#include "cros-camera/ipc_util.h"
namespace cros {
CameraMojoChannelManager* CameraMojoChannelManager::GetInstance() {
static CameraMojoChannelManagerImpl* instance =
new CameraMojoChannelManagerImpl();
if (!instance->Start())
return nullptr;
return instance;
}
CameraMojoChannelManagerImpl::CameraMojoChannelManagerImpl()
: ipc_thread_("IpcThread"), is_started_(false) {
VLOGF_ENTER();
}
CameraMojoChannelManagerImpl::~CameraMojoChannelManagerImpl() {
VLOGF_ENTER();
dispatcher_.reset();
ipc_thread_.Stop();
mojo::edk::ShutdownIPCSupport();
VLOGF_EXIT();
}
bool CameraMojoChannelManagerImpl::Start() {
base::AutoLock l(start_lock_);
if (is_started_) {
return true;
}
mojo::edk::Init();
if (!ipc_thread_.StartWithOptions(
base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) {
LOGF(ERROR) << "Failed to start IPC Thread";
return false;
}
mojo::edk::InitIPCSupport(this, ipc_thread_.task_runner());
is_started_ = true;
return true;
}
void CameraMojoChannelManagerImpl::CreateJpegDecodeAccelerator(
mojom::JpegDecodeAcceleratorRequest request) {
ipc_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(
&CameraMojoChannelManagerImpl::CreateJpegDecodeAcceleratorOnIpcThread,
base::Unretained(this), base::Passed(std::move(request))));
}
void CameraMojoChannelManagerImpl::CreateJpegEncodeAccelerator(
mojom::JpegEncodeAcceleratorRequest request) {
ipc_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(
&CameraMojoChannelManagerImpl::CreateJpegEncodeAcceleratorOnIpcThread,
base::Unretained(this), base::Passed(std::move(request))));
}
mojom::CameraAlgorithmOpsPtr
CameraMojoChannelManagerImpl::CreateCameraAlgorithmOpsPtr() {
VLOGF_ENTER();
mojo::ScopedMessagePipeHandle parent_pipe;
mojom::CameraAlgorithmOpsPtr algorithm_ops;
base::FilePath socket_path(constants::kCrosCameraAlgoSocketPathString);
MojoResult result = cros::CreateMojoChannelToChildByUnixDomainSocket(
socket_path, &parent_pipe);
if (result != MOJO_RESULT_OK) {
LOGF(WARNING) << "Failed to create Mojo Channel to" << socket_path.value();
return nullptr;
}
algorithm_ops.Bind(
mojom::CameraAlgorithmOpsPtrInfo(std::move(parent_pipe), 0u));
LOGF(INFO) << "Connected to CameraAlgorithmOps";
VLOGF_EXIT();
return algorithm_ops;
}
void CameraMojoChannelManagerImpl::CreateJpegDecodeAcceleratorOnIpcThread(
mojom::JpegDecodeAcceleratorRequest request) {
DCHECK(ipc_thread_.task_runner()->BelongsToCurrentThread());
EnsureDispatcherConnectedOnIpcThread();
if (dispatcher_.is_bound()) {
dispatcher_->GetJpegDecodeAccelerator(std::move(request));
}
}
void CameraMojoChannelManagerImpl::CreateJpegEncodeAcceleratorOnIpcThread(
mojom::JpegEncodeAcceleratorRequest request) {
DCHECK(ipc_thread_.task_runner()->BelongsToCurrentThread());
EnsureDispatcherConnectedOnIpcThread();
if (dispatcher_.is_bound()) {
dispatcher_->GetJpegEncodeAccelerator(std::move(request));
}
}
void CameraMojoChannelManagerImpl::EnsureDispatcherConnectedOnIpcThread() {
DCHECK(ipc_thread_.task_runner()->BelongsToCurrentThread());
VLOGF_ENTER();
if (dispatcher_.is_bound()) {
return;
}
mojo::ScopedMessagePipeHandle child_pipe;
base::FilePath socket_path(constants::kCrosCameraSocketPathString);
MojoResult result = cros::CreateMojoChannelToParentByUnixDomainSocket(
socket_path, &child_pipe);
if (result != MOJO_RESULT_OK) {
LOGF(WARNING) << "Failed to create Mojo Channel to" << socket_path.value();
return;
}
dispatcher_ = mojo::MakeProxy(
mojom::CameraHalDispatcherPtrInfo(std::move(child_pipe), 0u),
ipc_thread_.task_runner());
dispatcher_.set_connection_error_handler(
base::Bind(&CameraMojoChannelManagerImpl::OnDispatcherError,
base::Unretained(this)));
LOGF(INFO) << "Connected to CameraHalDispatcher";
VLOGF_EXIT();
}
void CameraMojoChannelManagerImpl::OnDispatcherError() {
DCHECK(ipc_thread_.task_runner()->BelongsToCurrentThread());
VLOGF_ENTER();
LOGF(ERROR) << "Mojo channel to CameraHalDispatcher is broken";
dispatcher_.reset();
VLOGF_EXIT();
}
} // namespace cros