settings/accessibility/
accessibility_fidl_handler.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
5use crate::accessibility::types::{AccessibilityInfo, CaptionsSettings, ColorBlindnessType};
6use crate::base::{SettingInfo, SettingType};
7use crate::handler::base::Request;
8use crate::ingress::{request, watch, Scoped};
9use crate::job::source::{Error as JobError, ErrorResponder};
10use crate::job::Job;
11use fidl::prelude::*;
12use fidl_fuchsia_settings::{
13    AccessibilityRequest, AccessibilitySetResponder, AccessibilitySetResult, AccessibilitySettings,
14    AccessibilityWatchResponder,
15};
16
17impl ErrorResponder for AccessibilitySetResponder {
18    fn id(&self) -> &'static str {
19        "Accessibility_Set"
20    }
21
22    fn respond(self: Box<Self>, error: fidl_fuchsia_settings::Error) -> Result<(), fidl::Error> {
23        self.send(Err(error))
24    }
25}
26
27impl request::Responder<Scoped<AccessibilitySetResult>> for AccessibilitySetResponder {
28    fn respond(self, Scoped(response): Scoped<AccessibilitySetResult>) {
29        let _ = self.send(response);
30    }
31}
32
33impl watch::Responder<AccessibilitySettings, zx::Status> for AccessibilityWatchResponder {
34    fn respond(self, response: Result<AccessibilitySettings, zx::Status>) {
35        match response {
36            Ok(settings) => {
37                let _ = self.send(&settings);
38            }
39            Err(error) => {
40                self.control_handle().shutdown_with_epitaph(error);
41            }
42        }
43    }
44}
45
46impl TryFrom<AccessibilityRequest> for Job {
47    type Error = JobError;
48
49    fn try_from(item: AccessibilityRequest) -> Result<Self, Self::Error> {
50        #[allow(unreachable_patterns)]
51        match item {
52            AccessibilityRequest::Set { settings, responder } => {
53                Ok(request::Work::new(SettingType::Accessibility, to_request(settings), responder)
54                    .into())
55            }
56            AccessibilityRequest::Watch { responder } => {
57                Ok(watch::Work::new_job(SettingType::Accessibility, responder))
58            }
59            _ => {
60                log::warn!("Received a call to an unsupported API: {:?}", item);
61                Err(JobError::Unsupported)
62            }
63        }
64    }
65}
66
67impl From<SettingInfo> for AccessibilitySettings {
68    fn from(response: SettingInfo) -> Self {
69        if let SettingInfo::Accessibility(info) = response {
70            return AccessibilitySettings {
71                audio_description: info.audio_description,
72                screen_reader: info.screen_reader,
73                color_inversion: info.color_inversion,
74                enable_magnification: info.enable_magnification,
75                color_correction: info.color_correction.map(ColorBlindnessType::into),
76                captions_settings: info.captions_settings.map(CaptionsSettings::into),
77                ..Default::default()
78            };
79        }
80
81        panic!("incorrect value sent to accessibility");
82    }
83}
84
85fn to_request(settings: AccessibilitySettings) -> Request {
86    Request::SetAccessibilityInfo(AccessibilityInfo {
87        audio_description: settings.audio_description,
88        screen_reader: settings.screen_reader,
89        color_inversion: settings.color_inversion,
90        enable_magnification: settings.enable_magnification,
91        color_correction: settings
92            .color_correction
93            .map(fidl_fuchsia_settings::ColorBlindnessType::into),
94        captions_settings: settings
95            .captions_settings
96            .map(fidl_fuchsia_settings::CaptionsSettings::into),
97    })
98}
99
100#[cfg(test)]
101mod tests {
102    use crate::accessibility::types::{CaptionFontFamily, CaptionFontStyle, ColorRgba, EdgeStyle};
103    use fidl_fuchsia_settings::ColorBlindnessType;
104
105    use super::*;
106
107    #[fuchsia::test]
108    fn test_request_try_from_settings_request_empty() {
109        let request = to_request(AccessibilitySettings::default());
110
111        const EXPECTED_ACCESSIBILITY_INFO: AccessibilityInfo = AccessibilityInfo {
112            audio_description: None,
113            screen_reader: None,
114            color_inversion: None,
115            enable_magnification: None,
116            color_correction: None,
117            captions_settings: None,
118        };
119
120        assert_eq!(request, Request::SetAccessibilityInfo(EXPECTED_ACCESSIBILITY_INFO));
121    }
122
123    #[fuchsia::test]
124    fn test_try_from_settings_request() {
125        const TEST_COLOR: ColorRgba =
126            ColorRgba { red: 238.0, green: 23.0, blue: 128.0, alpha: 255.0 };
127        const EXPECTED_FONT_STYLE: CaptionFontStyle = CaptionFontStyle {
128            family: Some(CaptionFontFamily::Casual),
129            color: Some(TEST_COLOR),
130            relative_size: Some(1.0),
131            char_edge_style: Some(EdgeStyle::Raised),
132        };
133        const EXPECTED_CAPTION_SETTINGS: CaptionsSettings = CaptionsSettings {
134            for_media: Some(true),
135            for_tts: Some(true),
136            font_style: Some(EXPECTED_FONT_STYLE),
137            window_color: Some(TEST_COLOR),
138            background_color: Some(TEST_COLOR),
139        };
140        const EXPECTED_ACCESSIBILITY_INFO: AccessibilityInfo = AccessibilityInfo {
141            audio_description: Some(true),
142            screen_reader: Some(true),
143            color_inversion: Some(true),
144            enable_magnification: Some(true),
145            color_correction: Some(crate::accessibility::types::ColorBlindnessType::Protanomaly),
146            captions_settings: Some(EXPECTED_CAPTION_SETTINGS),
147        };
148
149        let accessibility_settings = AccessibilitySettings {
150            audio_description: Some(true),
151            screen_reader: Some(true),
152            color_inversion: Some(true),
153            enable_magnification: Some(true),
154            color_correction: Some(ColorBlindnessType::Protanomaly),
155            captions_settings: Some(EXPECTED_CAPTION_SETTINGS.into()),
156            ..Default::default()
157        };
158
159        let request = to_request(accessibility_settings);
160
161        assert_eq!(request, Request::SetAccessibilityInfo(EXPECTED_ACCESSIBILITY_INFO));
162    }
163}