blob: fdd4ceda752d5b2c3e864665e65c4be1d8300069 [file] [log] [blame]
// Copyright 2022 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.
use crate::base::SettingType;
use crate::inspect::utils::inspect_map::InspectMap;
use fuchsia_inspect::{self as inspect, component, NumericProperty};
use fuchsia_inspect_derive::{Inspect, WithInspect};
use fuchsia_syslog::fx_log_err;
const LISTENER_INSPECT_NODE_NAME: &str = "active_listeners";
pub struct ListenerInspectLogger {
/// The inspector, stored for access in tests.
pub inspector: &'static inspect::Inspector,
/// The saved inspect node for the active listeners.
inspect_node: inspect::Node,
/// The saved information about each setting type's active listeners.
listener_counts: InspectMap<ListenerInspectInfo>,
}
impl Default for ListenerInspectLogger {
fn default() -> Self {
Self::new()
}
}
/// Information about active listeners to be written to inspect.
///
/// Inspect nodes are not used, but need to be held as they're deleted from inspect once they go
/// out of scope.
#[derive(Default, Inspect)]
struct ListenerInspectInfo {
/// Node of this info.
inspect_node: inspect::Node,
/// Number of active listeners.
count: inspect::UintProperty,
}
impl ListenerInspectInfo {
fn new(node: &inspect::Node, key: &str) -> Self {
Self::default().with_inspect(node, key).expect("Failed to create ListenerInspectInfo node")
}
}
impl ListenerInspectLogger {
pub fn new() -> Self {
let inspector = component::inspector();
Self {
inspector,
inspect_node: inspector.root().create_child(LISTENER_INSPECT_NODE_NAME),
listener_counts: InspectMap::new(),
}
}
/// Adds a listener to the count for [setting_type].
pub fn add_listener(&mut self, setting_type: SettingType) {
let setting_type_str = format!("{:?}", setting_type);
match self.listener_counts.get_mut(&setting_type_str) {
Some(listener_inspect_info) => listener_inspect_info.count.add(1u64),
None => {
let listener_inspect_info =
ListenerInspectInfo::new(&self.inspect_node, &setting_type_str);
listener_inspect_info.count.add(1u64);
self.listener_counts.set(setting_type_str, listener_inspect_info);
}
}
}
/// Removes a listener from the count for [setting_type].
pub fn remove_listener(&mut self, setting_type: SettingType) {
let setting_type_str = format!("{:?}", setting_type);
match self.listener_counts.get_mut(&setting_type_str) {
Some(listener_inspect_info) => listener_inspect_info.count.subtract(1u64),
None => fx_log_err!("Tried to subtract from nonexistent listener count"),
}
}
}