1pub mod input_controller;
6pub mod input_device_configuration;
7mod input_fidl_handler;
8pub mod types;
9
10use self::input_controller::InputController;
11pub use self::input_device_configuration::build_input_default_settings;
12use self::input_fidl_handler::InputFidlHandler;
13use crate::InputConfiguration;
14use anyhow::{Context, Result};
15use fuchsia_async as fasync;
16use futures::StreamExt;
17use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender};
18use futures::channel::oneshot;
19use input_controller::InputError;
20use settings_common::config::default_settings::DefaultSetting;
21use settings_common::inspect::event::{
22 ExternalEventPublisher, RequestType, ResponseType, SettingValuePublisher, UsagePublisher,
23};
24use settings_common::service_context::ServiceContext;
25use settings_storage::device_storage::DeviceStorage;
26use settings_storage::storage_factory::StorageFactory;
27use std::rc::Rc;
28use types::InputInfo;
29
30pub struct SetupResult {
31 pub input_fidl_handler: InputFidlHandler,
32 pub camera_watcher_event_tx: UnboundedSender<bool>,
33 pub media_buttons_event_tx: UnboundedSender<settings_media_buttons::Event>,
34 pub task: fuchsia_async::Task<()>,
35}
36
37pub async fn setup_input_api<F>(
38 service_context: Rc<ServiceContext>,
39 input_configuration: &mut DefaultSetting<InputConfiguration, &'static str>,
40 storage_factory: Rc<F>,
41 setting_value_publisher: SettingValuePublisher<InputInfo>,
42 usage_publisher: UsagePublisher<InputInfo>,
43 external_publisher: ExternalEventPublisher,
44) -> Result<SetupResult>
45where
46 F: StorageFactory<Storage = DeviceStorage>,
47{
48 let mut input_controller = InputController::new(
49 service_context,
50 input_configuration,
51 storage_factory,
52 setting_value_publisher.clone(),
53 external_publisher,
54 )
55 .await
56 .context("Failed to initialize input: {e:?}")?;
57 let initial_value = input_controller.restore().await.context("Failed to restore input")?;
58 let _ = setting_value_publisher.publish(&initial_value);
59
60 let (input_fidl_handler, request_rx) =
61 InputFidlHandler::new(&mut input_controller, usage_publisher.clone(), initial_value);
62 let (camera_watcher_event_tx, camera_watcher_event_rx) = mpsc::unbounded();
63 let inner_camera_event_rx =
64 event_request_logger(camera_watcher_event_rx, usage_publisher.clone(), RequestType::Camera);
65 let (media_buttons_event_tx, media_buttons_event_rx) = mpsc::unbounded();
66 let inner_media_buttons_event_rx =
67 event_request_logger(media_buttons_event_rx, usage_publisher.clone(), RequestType::Camera);
68 let task = input_controller
69 .handle(inner_camera_event_rx, inner_media_buttons_event_rx, request_rx)
70 .await;
71 Ok(SetupResult { input_fidl_handler, camera_watcher_event_tx, media_buttons_event_tx, task })
72}
73type ResultSender = oneshot::Sender<Result<Option<()>, InputError>>;
74
75fn event_request_logger<T>(
76 mut event_rx: UnboundedReceiver<T>,
77 usage_publisher: UsagePublisher<InputInfo>,
78 request_type: RequestType,
79) -> UnboundedReceiver<(T, ResultSender)>
80where
81 T: std::fmt::Debug + 'static,
82{
83 let (inner_event_tx, inner_event_rx) = mpsc::unbounded();
84 fasync::Task::local(async move {
85 while let Some(event) = event_rx.next().await {
86 let usage_responder = usage_publisher.request(format!("{event:?}"), request_type);
87 let (tx, rx) = oneshot::channel::<Result<Option<()>, InputError>>();
88 let _ = inner_event_tx.unbounded_send((event, tx));
89 if let Ok(res) = rx.await {
90 usage_responder.respond(
91 format!("{res:?}"),
92 res.map(|res| {
93 if res.is_some() { ResponseType::OkSome } else { ResponseType::OkNone }
94 })
95 .unwrap_or_else(|e| ResponseType::from(&e)),
96 );
97 } else {
98 usage_responder
99 .respond("Err(ControllerDied)".to_string(), ResponseType::UnexpectedError);
100 }
101 }
102 })
103 .detach();
104 inner_event_rx
105}