blob: c9a7510dac0898113e26685e237428f5c4504b9b [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 "src/media/audio/virtual_audio_service/virtual_audio_service_impl.h"
#include <fcntl.h>
#include <fuchsia/virtualaudio/c/fidl.h>
#include <lib/fdio/fdio.h>
#include <lib/syslog/cpp/macros.h>
#include "src/media/audio/drivers/virtual_audio/virtual_audio.h"
namespace virtual_audio {
VirtualAudioServiceImpl::VirtualAudioServiceImpl(
std::unique_ptr<sys::ComponentContext> component_context)
: component_context_(std::move(component_context)) {
FX_DCHECK(component_context_);
component_context_->outgoing()->AddPublicService<fuchsia::virtualaudio::Control>(
[this](fidl::InterfaceRequest<fuchsia::virtualaudio::Control> request) {
if (driver_open_) {
ForwardControlRequest(std::move(request));
}
});
component_context_->outgoing()->AddPublicService<fuchsia::virtualaudio::Input>(
[this](fidl::InterfaceRequest<fuchsia::virtualaudio::Input> request) {
if (driver_open_) {
ForwardInputRequest(std::move(request));
}
});
component_context_->outgoing()->AddPublicService<fuchsia::virtualaudio::Output>(
[this](fidl::InterfaceRequest<fuchsia::virtualaudio::Output> request) {
if (driver_open_) {
ForwardOutputRequest(std::move(request));
}
});
}
VirtualAudioServiceImpl::~VirtualAudioServiceImpl() {
if (driver_open_) {
FX_LOGS(INFO) << "Closing '" << virtual_audio::kCtlNodeName << "'";
zx_handle_close(channel_handle_);
}
}
// If we couldn't open the control driver, the service isn't operational.
zx_status_t VirtualAudioServiceImpl::Init() {
return (OpenControlDriver() ? ZX_OK : ZX_ERR_INTERNAL);
}
// Return a bool representing whether control driver was successfully opened.
bool VirtualAudioServiceImpl::OpenControlDriver() {
if (driver_open_) {
FX_LOGS(WARNING) << "Already connected to '" << virtual_audio::kCtlNodeName << "'";
return true;
}
int ctl_node_file_desc = open(virtual_audio::kCtlNodeName, O_RDONLY);
if (ctl_node_file_desc <= 0) {
FX_LOGS(WARNING) << "Failed to open '" << virtual_audio::kCtlNodeName << "' - result "
<< ctl_node_file_desc;
return false;
}
zx_status_t status = fdio_get_service_handle(ctl_node_file_desc, &channel_handle_);
if (status != ZX_OK || channel_handle_ == ZX_KOID_INVALID) {
FX_LOGS(WARNING) << "fdio_get_service_handle returned " << status << "; handle is "
<< channel_handle_ << "; we will exit now";
return false;
}
driver_open_ = true;
return true;
}
zx_status_t VirtualAudioServiceImpl::ForwardControlRequest(
fidl::InterfaceRequest<fuchsia::virtualaudio::Control> control_request) {
auto control_request_handle = control_request.TakeChannel().release();
zx_status_t status =
fuchsia_virtualaudio_ForwarderSendControl(channel_handle_, control_request_handle);
if (status != ZX_OK) {
FX_LOGS(WARNING) << __func__ << " returned " << status;
}
return status;
}
zx_status_t VirtualAudioServiceImpl::ForwardInputRequest(
fidl::InterfaceRequest<fuchsia::virtualaudio::Input> input_request) {
auto input_request_handle = input_request.TakeChannel().release();
zx_status_t status =
fuchsia_virtualaudio_ForwarderSendInput(channel_handle_, input_request_handle);
if (status != ZX_OK) {
FX_LOGS(WARNING) << __func__ << " returned " << status;
}
return status;
}
zx_status_t VirtualAudioServiceImpl::ForwardOutputRequest(
fidl::InterfaceRequest<fuchsia::virtualaudio::Output> output_request) {
auto output_request_handle = output_request.TakeChannel().release();
zx_status_t status =
fuchsia_virtualaudio_ForwarderSendOutput(channel_handle_, output_request_handle);
if (status != ZX_OK) {
FX_LOGS(WARNING) << __func__ << " returned " << status;
}
return status;
}
} // namespace virtual_audio