settings/display/
display_fidl_handler.rs1use crate::base::{SettingInfo, SettingType};
5use crate::display::types::{LowLightMode, SetDisplayInfo, Theme, ThemeMode, ThemeType};
6use crate::handler::base::Request;
7use crate::ingress::{request, watch, Scoped};
8use crate::job::source::{Error as JobError, ErrorResponder};
9use crate::job::Job;
10use fidl::endpoints::{ControlHandle, Responder};
11use fidl_fuchsia_settings::{
12 DisplayRequest, DisplaySetResponder, DisplaySetResult, DisplaySettings, DisplayWatchResponder,
13 LowLightMode as FidlLowLightMode, Theme as FidlTheme, ThemeMode as FidlThemeMode,
14 ThemeType as FidlThemeType,
15};
16
17impl From<FidlThemeMode> for ThemeMode {
18 fn from(fidl: FidlThemeMode) -> Self {
19 ThemeMode::from_bits(FidlThemeMode::bits(&fidl))
20 .expect("failed to convert FidlThemeMode to ThemeMode")
21 }
22}
23
24impl From<ThemeMode> for FidlThemeMode {
25 fn from(fidl: ThemeMode) -> Self {
26 FidlThemeMode::from_bits(ThemeMode::bits(&fidl))
27 .expect("failed to convert ThemeMode to FidlThemeMode")
28 }
29}
30
31impl From<FidlLowLightMode> for LowLightMode {
32 fn from(fidl_low_light_mode: FidlLowLightMode) -> Self {
33 match fidl_low_light_mode {
34 FidlLowLightMode::Disable => LowLightMode::Disable,
35 FidlLowLightMode::DisableImmediately => LowLightMode::DisableImmediately,
36 FidlLowLightMode::Enable => LowLightMode::Enable,
37 }
38 }
39}
40
41impl From<FidlThemeType> for ThemeType {
42 fn from(fidl_theme_type: FidlThemeType) -> Self {
43 match fidl_theme_type {
44 FidlThemeType::Default => ThemeType::Default,
45 FidlThemeType::Light => ThemeType::Light,
46 FidlThemeType::Dark => ThemeType::Dark,
47 }
48 }
49}
50
51impl From<FidlTheme> for Theme {
52 fn from(fidl_theme: FidlTheme) -> Self {
53 Self {
54 theme_type: fidl_theme.theme_type.map(Into::into),
55 theme_mode: fidl_theme.theme_mode.map(Into::into).unwrap_or_else(ThemeMode::empty),
56 }
57 }
58}
59
60impl From<SettingInfo> for DisplaySettings {
61 fn from(response: SettingInfo) -> Self {
62 if let SettingInfo::Brightness(info) = response {
63 fidl_fuchsia_settings::DisplaySettings {
64 auto_brightness: Some(info.auto_brightness),
65 adjusted_auto_brightness: Some(info.auto_brightness_value),
66 brightness_value: Some(info.manual_brightness_value),
67 screen_enabled: Some(info.screen_enabled),
68 low_light_mode: Some(match info.low_light_mode {
69 LowLightMode::Enable => FidlLowLightMode::Enable,
70 LowLightMode::Disable => FidlLowLightMode::Disable,
71 LowLightMode::DisableImmediately => FidlLowLightMode::DisableImmediately,
72 }),
73 theme: Some(FidlTheme {
74 theme_type: match info.theme {
75 Some(Theme { theme_type: Some(theme_type), .. }) => match theme_type {
76 ThemeType::Unknown => None,
77 ThemeType::Default => Some(FidlThemeType::Default),
78 ThemeType::Light => Some(FidlThemeType::Light),
79 ThemeType::Dark => Some(FidlThemeType::Dark),
80 },
81 _ => None,
82 },
83 theme_mode: match info.theme {
84 Some(Theme { theme_mode, .. }) if !theme_mode.is_empty() => {
85 Some(FidlThemeMode::from(theme_mode))
86 }
87 _ => None,
88 },
89 ..Default::default()
90 }),
91 ..Default::default()
92 }
93 } else {
94 panic!("incorrect value sent to display");
95 }
96 }
97}
98
99impl ErrorResponder for DisplaySetResponder {
100 fn id(&self) -> &'static str {
101 "Display_Set"
102 }
103
104 fn respond(self: Box<Self>, error: fidl_fuchsia_settings::Error) -> Result<(), fidl::Error> {
105 self.send(Err(error))
106 }
107}
108
109impl request::Responder<Scoped<DisplaySetResult>> for DisplaySetResponder {
110 fn respond(self, Scoped(response): Scoped<DisplaySetResult>) {
111 let _ = self.send(response);
112 }
113}
114
115impl watch::Responder<DisplaySettings, zx::Status> for DisplayWatchResponder {
116 fn respond(self, response: Result<DisplaySettings, zx::Status>) {
117 match response {
118 Ok(settings) => {
119 let _ = self.send(&settings);
120 }
121 Err(error) => {
122 self.control_handle().shutdown_with_epitaph(error);
123 }
124 }
125 }
126}
127
128fn to_request(settings: DisplaySettings) -> Option<Request> {
129 let set_display_info = SetDisplayInfo {
130 manual_brightness_value: settings.brightness_value,
131 auto_brightness_value: settings.adjusted_auto_brightness,
132 auto_brightness: settings.auto_brightness,
133 screen_enabled: settings.screen_enabled,
134 low_light_mode: settings.low_light_mode.map(Into::into),
135 theme: settings.theme.map(Into::into),
136 };
137 match set_display_info {
138 SetDisplayInfo {
140 manual_brightness_value: None,
141 auto_brightness_value: None,
142 auto_brightness: None,
143 screen_enabled: None,
144 low_light_mode: None,
145 theme: None,
146 } => None,
147 _ => Some(Request::SetDisplayInfo(set_display_info)),
148 }
149}
150
151impl TryFrom<DisplayRequest> for Job {
152 type Error = JobError;
153 fn try_from(req: DisplayRequest) -> Result<Self, Self::Error> {
154 #[allow(unreachable_patterns)]
156 match req {
157 DisplayRequest::Set { settings, responder } => match to_request(settings) {
158 Some(request) => {
159 Ok(request::Work::new(SettingType::Display, request, responder).into())
160 }
161 None => Err(JobError::InvalidInput(Box::new(responder))),
162 },
163 DisplayRequest::Watch { responder } => {
164 Ok(watch::Work::new_job(SettingType::Display, responder))
165 }
166 _ => {
167 log::warn!("Received a call to an unsupported API: {:?}", req);
168 Err(JobError::Unsupported)
169 }
170 }
171 }
172}