Skip to main content

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