settings/keyboard/
keyboard_controller.rs

1// Copyright 2021 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
5use crate::base::{SettingInfo, SettingType};
6use crate::handler::base::Request;
7use crate::handler::setting_handler::persist::{controller as data_controller, ClientProxy};
8use crate::handler::setting_handler::{
9    controller, ControllerError, IntoHandlerResult, SettingHandlerResult,
10};
11use crate::keyboard::types::{KeyboardInfo, KeymapId};
12use crate::trace;
13use settings_storage::device_storage::{DeviceStorage, DeviceStorageCompatible};
14use settings_storage::storage_factory::{NoneT, StorageAccess};
15
16use async_trait::async_trait;
17
18impl DeviceStorageCompatible for KeyboardInfo {
19    type Loader = NoneT;
20    const KEY: &'static str = "keyboard_info";
21}
22
23impl Default for KeyboardInfo {
24    fn default() -> Self {
25        // The US_QWERTY keymap is the default if no settings are ever applied.
26        KeyboardInfo { keymap: Some(KeymapId::UsQwerty), autorepeat: None }
27    }
28}
29
30impl From<KeyboardInfo> for SettingInfo {
31    fn from(info: KeyboardInfo) -> SettingInfo {
32        SettingInfo::Keyboard(info)
33    }
34}
35
36pub struct KeyboardController {
37    client: ClientProxy,
38}
39
40impl StorageAccess for KeyboardController {
41    type Storage = DeviceStorage;
42    type Data = KeyboardInfo;
43    const STORAGE_KEY: &'static str = KeyboardInfo::KEY;
44}
45
46#[async_trait(?Send)]
47impl data_controller::Create for KeyboardController {
48    async fn create(client: ClientProxy) -> Result<Self, ControllerError> {
49        Ok(KeyboardController { client })
50    }
51}
52
53#[async_trait(?Send)]
54impl controller::Handle for KeyboardController {
55    async fn handle(&self, request: Request) -> Option<SettingHandlerResult> {
56        match request {
57            Request::SetKeyboardInfo(keyboard_info) => {
58                let id = fuchsia_trace::Id::new();
59                trace!(id, c"set keyboard");
60                let mut current = self.client.read_setting::<KeyboardInfo>(id).await;
61                if !keyboard_info.is_valid() {
62                    return Some(Err(ControllerError::InvalidArgument(
63                        SettingType::Keyboard,
64                        "keyboard".into(),
65                        format!("{keyboard_info:?}").into(),
66                    )));
67                }
68                // Save the value locally.
69                current.keymap = keyboard_info.keymap.or(current.keymap);
70                current.autorepeat =
71                    keyboard_info.autorepeat.or(current.autorepeat).and_then(|value| {
72                        if value.delay == 0 && value.period == 0 {
73                            // Clean up Autorepeat when delay and period are set to zero.
74                            None
75                        } else {
76                            Some(value)
77                        }
78                    });
79                Some(self.client.write_setting(current.into(), id).await.into_handler_result())
80            }
81            Request::Get => {
82                let id = fuchsia_trace::Id::new();
83                trace!(id, c"get keyboard");
84                Some(self.client.read_setting_info::<KeyboardInfo>(id).await.into_handler_result())
85            }
86            _ => None,
87        }
88    }
89}