blob: 2881b1fbda0a3f229d4cfda13e30354e873bf39f [file] [log] [blame]
// Copyright 2020 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 fidl_fuchsia_samplertestcontroller::*;
use fuchsia_async as fasync;
use fuchsia_component::server::ServiceFs;
use fuchsia_inspect::component;
use futures::{FutureExt, StreamExt, TryStreamExt};
use std::{
collections::HashMap,
sync::{Arc, Mutex},
};
#[fuchsia::main]
async fn main() {
let mut fs = ServiceFs::new();
let inspector = component::inspector();
inspect_runtime::serve(inspector, &mut fs).unwrap();
tracing::info!("Started SamplerTestController");
fs.dir("svc").add_fidl_service(move |stream| serve_sampler_test_controller(stream));
fs.take_and_serve_directory_handle().unwrap();
fs.collect::<()>().await;
}
struct TestState {
integer_property_map: HashMap<u16, (String, i64)>,
optional_integer: Option<i64>,
sample_count_callback_opt: Option<SamplerTestControllerWaitForSampleResponder>,
}
static INSPECT_NAME_FOR_OPTIONAL: &str = "optional";
impl TestState {
pub fn new() -> Arc<Mutex<TestState>> {
let mut integer_property_map: HashMap<u16, (String, i64)> = HashMap::new();
integer_property_map.insert(1, ("counter".to_string(), 0));
integer_property_map.insert(2, ("integer_1".to_string(), 10));
integer_property_map.insert(3, ("integer_2".to_string(), 20));
integer_property_map.insert(4, ("integer_3".to_string(), 30));
Arc::new(Mutex::new(TestState {
integer_property_map,
optional_integer: None,
sample_count_callback_opt: None,
}))
}
}
fn add_lazy_sampled_node(
parent: &fuchsia_inspect::Node,
state: Arc<Mutex<TestState>>,
) -> fuchsia_inspect::LazyNode {
parent.create_lazy_child("samples", move || {
let state = state.clone();
async move {
let mut unwrapped = state.lock().unwrap();
if let Some(responder) = unwrapped.sample_count_callback_opt.take() {
responder.send(&mut Ok(())).unwrap();
}
let samples = fuchsia_inspect::Inspector::new();
for (_, (name, int_val)) in unwrapped.integer_property_map.clone() {
let () = samples.root().record_int(name, int_val);
}
if let Some(value) = unwrapped.optional_integer {
let () = samples.root().record_int(INSPECT_NAME_FOR_OPTIONAL, value);
}
Ok(samples)
}
.boxed()
})
}
fn serve_sampler_test_controller(mut stream: SamplerTestControllerRequestStream) {
fasync::Task::spawn(async move {
let state = TestState::new();
let inspector = component::inspector();
let _lazy_state_node = add_lazy_sampled_node(inspector.root(), state.clone());
while let Some(req) = stream.try_next().await.unwrap() {
match req {
SamplerTestControllerRequest::IncrementInt { property_id, responder } => {
let mut unwrapped = state.lock().unwrap();
unwrapped.integer_property_map.get_mut(&property_id).unwrap().1 += 1;
responder.send().unwrap();
}
SamplerTestControllerRequest::SetOptional { value, responder } => {
let mut unwrapped = state.lock().unwrap();
unwrapped.optional_integer = Some(value);
responder.send().unwrap();
}
SamplerTestControllerRequest::RemoveOptional { responder } => {
let mut unwrapped = state.lock().unwrap();
unwrapped.optional_integer = None;
responder.send().unwrap();
}
SamplerTestControllerRequest::WaitForSample { responder } => {
let mut unwrapped = state.lock().unwrap();
if unwrapped.sample_count_callback_opt.is_some() {
responder
.send(&mut Err(SamplingError::MultipleSampleCallbacksError))
.unwrap();
continue;
}
unwrapped.sample_count_callback_opt = Some(responder);
}
}
}
})
.detach();
}