blob: 50ccffa8b6c59a990c580fd030bacd1b510171fd [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 crate::agent::BlueprintHandle;
use crate::base::SettingType;
use crate::config::base::AgentType;
use crate::handler::base::{Context, GenerateHandler};
use crate::handler::device_storage::testing::InMemoryStorageFactory;
use crate::handler::device_storage::DeviceStorage;
use crate::handler::setting_handler::persist::ClientProxy;
use crate::handler::setting_handler::{BoxedController, ClientImpl};
use crate::input::input_controller::InputController;
use crate::input::input_device_configuration::InputConfiguration;
use crate::input::types::InputInfoSources;
use crate::tests::fakes::camera3_service::Camera3Service;
use crate::tests::fakes::input_device_registry_service::InputDeviceRegistryService;
use crate::tests::fakes::service_registry::ServiceRegistry;
use crate::EnvironmentBuilder;
use fidl_fuchsia_settings::{InputMarker, InputProxy};
use futures::lock::Mutex;
use std::sync::Arc;
const ENV_NAME: &str = "settings_service_input_test_environment";
pub struct TestInputEnvironment {
/// For sending requests to the input proxy.
pub input_service: InputProxy,
/// For sending media buttons changes.
pub input_button_service: Arc<Mutex<InputDeviceRegistryService>>,
/// For watching, connecting to, and making requests on the camera device.
pub camera3_service: Arc<Mutex<Camera3Service>>,
/// For storing the InputInfoSources.
pub store: Arc<DeviceStorage>,
}
pub struct TestInputEnvironmentBuilder {
/// The initial InputInfoSources in the environment.
starting_input_info_sources: Option<InputInfoSources>,
/// The config to load from.
input_device_config: Option<InputConfiguration>,
/// The list of agents to include.
agents: Vec<AgentType>,
}
impl TestInputEnvironmentBuilder {
pub fn new() -> Self {
Self {
starting_input_info_sources: None,
input_device_config: None,
agents: vec![AgentType::Restore, AgentType::MediaButtons],
}
}
pub fn set_starting_input_info_sources(
mut self,
starting_input_info_sources: InputInfoSources,
) -> Self {
self.starting_input_info_sources = Some(starting_input_info_sources);
self
}
pub fn set_input_device_config(mut self, input_device_config: InputConfiguration) -> Self {
self.input_device_config = Some(input_device_config);
self
}
pub async fn build(self) -> TestInputEnvironment {
let service_registry = ServiceRegistry::create();
let storage_factory = Arc::new(if let Some(info) = self.starting_input_info_sources {
InMemoryStorageFactory::with_initial_data(&info)
} else {
InMemoryStorageFactory::new()
});
// Register fake input device registry service.
let input_button_service_handle = Arc::new(Mutex::new(InputDeviceRegistryService::new()));
service_registry.lock().await.register_service(input_button_service_handle.clone());
// Register fake camera3 service.
let camera3_service_handle = Arc::new(Mutex::new(Camera3Service::new()));
service_registry.lock().await.register_service(camera3_service_handle.clone());
let mut environment_builder = EnvironmentBuilder::new(Arc::clone(&storage_factory))
.service(Box::new(ServiceRegistry::serve(service_registry)))
.agents(&self.agents.into_iter().map(BlueprintHandle::from).collect::<Vec<_>>())
.settings(&[SettingType::Input]);
if let Some(config) = self.input_device_config {
// If hardware configuration was specified, we need a generate_handler to include the
// specified configuration. This generate_handler method is a copy-paste of
// persist::controller::spawn from setting_handler.rs, with the innermost controller
// create method replaced with our custom constructor from input controller.
// TODO(fxbug.dev/63832): See if we can reduce this rightward drift.
let generate_handler: GenerateHandler = Box::new(move |context: Context| {
let config = config.clone();
Box::pin(async move {
let setting_type = context.setting_type;
ClientImpl::create(
context,
Box::new(move |proxy| {
let config = config.clone();
Box::pin(async move {
let proxy = ClientProxy::new(proxy, setting_type).await;
let controller_result =
InputController::create_with_config(proxy, config.clone())
.await;
controller_result
.map(|controller| Box::new(controller) as BoxedController)
})
}),
)
.await
})
});
environment_builder = environment_builder.handler(SettingType::Input, generate_handler);
}
let env = environment_builder.spawn_and_get_nested_environment(ENV_NAME).await.unwrap();
let input_service = env.connect_to_service::<InputMarker>().unwrap();
let store = storage_factory.get_device_storage().await;
TestInputEnvironment {
input_service,
input_button_service: input_button_service_handle,
camera3_service: camera3_service_handle,
store,
}
}
}