settings/
input.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5pub 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}