blob: 894d34021b1fff26c2314ccf078636a5c4055c48 [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/audio_core/reporter.h"
#include "src/lib/fxl/logging.h"
#include "src/media/audio/audio_core/audio_device.h"
namespace media::audio {
#if ENABLE_REPORTER
// static
Reporter& Reporter::Singleton() {
static Reporter singleton;
return singleton;
}
void Reporter::Init(sys::ComponentContext* component_context) {
FXL_DCHECK(component_context);
FXL_DCHECK(!component_context_);
component_context_ = component_context;
inspector_ = inspect_deprecated::ComponentInspector::Initialize(component_context_);
inspect_deprecated::Node& root_node = inspector_->root_tree()->GetRoot();
failed_to_open_device_count_ = root_node.CreateUIntMetric("count of failures to open device", 0);
failed_to_obtain_fdio_service_channel_count_ =
root_node.CreateUIntMetric("count of failures to obtain device fdio service channel", 0);
failed_to_obtain_stream_channel_count_ =
root_node.CreateUIntMetric("count of failures to obtain device stream channel", 0);
device_startup_failed_count_ =
root_node.CreateUIntMetric("count of failures to start a device", 0);
outputs_node_ = root_node.CreateChild("output devices");
inputs_node_ = root_node.CreateChild("input devices");
renderers_node_ = root_node.CreateChild("renderers");
capturers_node_ = root_node.CreateChild("capturers");
}
void Reporter::FailedToOpenDevice(const std::string& name, bool is_input, int err) {
failed_to_open_device_count_.Add(1);
}
void Reporter::FailedToObtainFdioServiceChannel(const std::string& name, bool is_input,
zx_status_t status) {
failed_to_obtain_fdio_service_channel_count_.Add(1);
}
void Reporter::FailedToObtainStreamChannel(const std::string& name, bool is_input,
zx_status_t status) {
failed_to_obtain_stream_channel_count_.Add(1);
}
void Reporter::AddingDevice(const std::string& name, const AudioDevice& device) {
if (device.is_output()) {
outputs_.emplace(&device, Output(outputs_node_.CreateChild(name)));
} else {
FXL_DCHECK(device.is_input());
inputs_.emplace(&device, Input(inputs_node_.CreateChild(name)));
}
}
void Reporter::RemovingDevice(const AudioDevice& device) {
if (device.is_output()) {
outputs_.erase(&device);
} else {
FXL_DCHECK(device.is_input());
inputs_.erase(&device);
}
}
void Reporter::DeviceStartupFailed(const AudioDevice& device) {
device_startup_failed_count_.Add(1);
}
void Reporter::IgnoringDevice(const AudioDevice& device) {
// Not reporting this via inspect.
}
void Reporter::ActivatingDevice(const AudioDevice& device) {
// Not reporting this via inspect...devices not activated are quickly removed.
}
void Reporter::SettingDeviceGainInfo(const AudioDevice& device,
const fuchsia::media::AudioGainInfo& gain_info,
uint32_t set_flags) {
Device* d = device.is_output() ? FindOutput(device) : FindInput(device);
if (d == nullptr) {
FXL_DLOG(FATAL);
return;
}
if (set_flags & fuchsia::media::SetAudioGainFlag_GainValid) {
d->gain_db_.Set(gain_info.gain_db);
}
if (set_flags & fuchsia::media::SetAudioGainFlag_MuteValid) {
d->muted_.Set((gain_info.flags & fuchsia::media::AudioGainInfoFlag_Mute) ? 1 : 0);
}
if (set_flags & fuchsia::media::SetAudioGainFlag_AgcValid) {
d->agc_supported_.Set((gain_info.flags & fuchsia::media::AudioGainInfoFlag_AgcSupported) ? 1
: 0);
d->agc_enabled_.Set((gain_info.flags & fuchsia::media::AudioGainInfoFlag_AgcEnabled) ? 1 : 0);
}
}
void Reporter::AddingRenderer(const AudioRendererImpl& renderer) {
renderers_.emplace(&renderer, Renderer(renderers_node_.CreateChild(NextRendererName())));
}
void Reporter::RemovingRenderer(const AudioRendererImpl& renderer) { renderers_.erase(&renderer); }
void Reporter::SettingRendererStreamType(const AudioRendererImpl& renderer,
const fuchsia::media::AudioStreamType& stream_type) {
Renderer* r = FindRenderer(renderer);
if (r == nullptr) {
FXL_DLOG(FATAL);
return;
}
r->sample_format_.Set(static_cast<uint64_t>(stream_type.sample_format));
r->channels_.Set(stream_type.channels);
r->frames_per_second_.Set(stream_type.frames_per_second);
}
void Reporter::AddingRendererPayloadBuffer(const AudioRendererImpl& renderer, uint32_t buffer_id,
uint64_t size) {
Renderer* r = FindRenderer(renderer);
if (r == nullptr) {
FXL_DLOG(FATAL);
return;
}
r->payload_buffers_.emplace(
buffer_id,
PayloadBuffer(r->payload_buffers_node_.CreateChild(std::to_string(buffer_id)), size));
}
void Reporter::RemovingRendererPayloadBuffer(const AudioRendererImpl& renderer,
uint32_t buffer_id) {
Renderer* r = FindRenderer(renderer);
if (r == nullptr) {
FXL_DLOG(FATAL);
return;
}
r->payload_buffers_.erase(buffer_id);
}
void Reporter::SendingRendererPacket(const AudioRendererImpl& renderer,
const fuchsia::media::StreamPacket& packet) {
Renderer* r = FindRenderer(renderer);
if (r == nullptr) {
FXL_DLOG(FATAL);
return;
}
auto payload_buffer = r->payload_buffers_.find(packet.payload_buffer_id);
if (payload_buffer == r->payload_buffers_.end()) {
FXL_DLOG(FATAL);
return;
}
payload_buffer->second.packets_.Add(1);
}
void Reporter::SettingRendererGain(const AudioRendererImpl& renderer, float gain_db) {
Renderer* r = FindRenderer(renderer);
if (r == nullptr) {
FXL_DLOG(FATAL);
return;
}
r->gain_db_.Set(gain_db);
}
void Reporter::SettingRendererGainWithRamp(const AudioRendererImpl& renderer, float gain_db,
zx_duration_t duration_ns,
fuchsia::media::audio::RampType ramp_type) {
Renderer* r = FindRenderer(renderer);
if (r == nullptr) {
FXL_DLOG(FATAL);
return;
}
// Just counting these for now.
r->set_gain_with_ramp_calls_.Add(1);
}
void Reporter::SettingRendererMute(const AudioRendererImpl& renderer, bool muted) {
Renderer* r = FindRenderer(renderer);
if (r == nullptr) {
FXL_DLOG(FATAL);
return;
}
r->muted_.Set(muted);
}
void Reporter::SettingRendererMinClockLeadTime(const AudioRendererImpl& renderer,
int64_t min_clock_lead_time_ns) {
Renderer* r = FindRenderer(renderer);
if (r == nullptr) {
FXL_DLOG(FATAL);
return;
}
r->min_clock_lead_time_ns_.Set(static_cast<uint64_t>(min_clock_lead_time_ns));
}
void Reporter::SettingRendererPtsContinuityThreshold(const AudioRendererImpl& renderer,
float threshold_seconds) {
Renderer* r = FindRenderer(renderer);
if (r == nullptr) {
FXL_DLOG(FATAL);
return;
}
r->pts_continuity_threshold_seconds_.Set(threshold_seconds);
}
void Reporter::AddingCapturer(const AudioCapturerImpl& capturer) {
capturers_.emplace(&capturer, Capturer(capturers_node_.CreateChild(NextCapturerName())));
}
void Reporter::RemovingCapturer(const AudioCapturerImpl& capturer) { capturers_.erase(&capturer); }
void Reporter::SettingCapturerStreamType(const AudioCapturerImpl& capturer,
const fuchsia::media::AudioStreamType& stream_type) {
Capturer* c = FindCapturer(capturer);
if (c == nullptr) {
FXL_DLOG(FATAL);
return;
}
c->sample_format_.Set(static_cast<uint64_t>(stream_type.sample_format));
c->channels_.Set(stream_type.channels);
c->frames_per_second_.Set(stream_type.frames_per_second);
}
void Reporter::AddingCapturerPayloadBuffer(const AudioCapturerImpl& capturer, uint32_t buffer_id,
uint64_t size) {
Capturer* c = FindCapturer(capturer);
if (c == nullptr) {
FXL_DLOG(FATAL);
return;
}
c->payload_buffers_.emplace(
buffer_id,
PayloadBuffer(c->payload_buffers_node_.CreateChild(std::to_string(buffer_id)), size));
}
void Reporter::SendingCapturerPacket(const AudioCapturerImpl& capturer,
const fuchsia::media::StreamPacket& packet) {
Capturer* c = FindCapturer(capturer);
if (c == nullptr) {
FXL_DLOG(FATAL);
return;
}
auto payload_buffer = c->payload_buffers_.find(packet.payload_buffer_id);
if (payload_buffer == c->payload_buffers_.end()) {
FXL_DLOG(FATAL);
return;
}
payload_buffer->second.packets_.Add(1);
}
void Reporter::SettingCapturerGain(const AudioCapturerImpl& capturer, float gain_db) {
Capturer* c = FindCapturer(capturer);
if (c == nullptr) {
FXL_DLOG(FATAL);
return;
}
c->gain_db_.Set(gain_db);
}
void Reporter::SettingCapturerGainWithRamp(const AudioCapturerImpl& capturer, float gain_db,
zx_duration_t duration_ns,
fuchsia::media::audio::RampType ramp_type) {
Capturer* c = FindCapturer(capturer);
if (c == nullptr) {
FXL_DLOG(FATAL);
return;
}
// Just counting these for now.
c->set_gain_with_ramp_calls_.Add(1);
}
void Reporter::SettingCapturerMute(const AudioCapturerImpl& capturer, bool muted) {
Capturer* c = FindCapturer(capturer);
if (c == nullptr) {
FXL_DLOG(FATAL);
return;
}
c->muted_.Set(muted);
}
Reporter::Device* Reporter::FindOutput(const AudioDevice& device) {
auto i = outputs_.find(&device);
return i == outputs_.end() ? nullptr : &i->second;
}
Reporter::Device* Reporter::FindInput(const AudioDevice& device) {
auto i = inputs_.find(&device);
return i == inputs_.end() ? nullptr : &i->second;
}
Reporter::Renderer* Reporter::FindRenderer(const AudioRendererImpl& renderer) {
auto i = renderers_.find(&renderer);
return i == renderers_.end() ? nullptr : &i->second;
}
Reporter::Capturer* Reporter::FindCapturer(const AudioCapturerImpl& capturer) {
auto i = capturers_.find(&capturer);
return i == capturers_.end() ? nullptr : &i->second;
}
std::string Reporter::NextRendererName() {
std::ostringstream os;
os << ++next_renderer_name_;
return os.str();
}
std::string Reporter::NextCapturerName() {
std::ostringstream os;
os << ++next_capturer_name_;
return os.str();
}
#endif // ENABLE_REPORTER
} // namespace media::audio