| // 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 |