1use crate::accessibility::types::AccessibilityInfo;
6use crate::audio::types::SetAudioStream;
7use crate::base::{SettingInfo, SettingType};
8use crate::display::types::SetDisplayInfo;
9use crate::do_not_disturb::types::DoNotDisturbInfo;
10use crate::handler::setting_handler::ControllerError;
11use crate::input::types::InputDevice;
12use crate::input::MediaButtons;
13use crate::intl::types::IntlInfo;
14use crate::keyboard::types::KeyboardInfo;
15use crate::light::types::LightState;
16use crate::night_mode::types::NightModeInfo;
17use crate::payload_convert;
18use crate::service::message::{Delegate, Messenger, Receptor, Signature};
19use crate::service_context::ServiceContext;
20use crate::setup::types::SetConfigurationInterfacesParams;
21
22use async_trait::async_trait;
23use fuchsia_trace as ftrace;
24use futures::future::LocalBoxFuture;
25use std::borrow::Cow;
26use std::collections::HashSet;
27use std::rc::Rc;
28
29pub type ControllerGenerateResult = Result<(), anyhow::Error>;
30
31pub(crate) type GenerateHandler =
32 Box<dyn Fn(Context) -> LocalBoxFuture<'static, ControllerGenerateResult>>;
33
34pub type Response = Result<Option<SettingInfo>, Error>;
35
36#[macro_export]
40macro_rules! generate_inspect {
41 (@underscore $_type:ty) => { _ };
42 ($(#[$metas:meta])* pub enum $name:ident {
43 $(
44 $(#[$variant_meta:meta])*
45 $variant:ident
46 $( ($($data:ty),+ $(,)?) )?
47 ),* $(,)?
48 }
49 ) => {
50 $(#[$metas])*
51 pub enum $name {
52 $(
53 $(#[$variant_meta])*
54 $variant$(($($data,)+))?,
55 )*
56 }
57
58 impl $name {
59 pub(crate) fn for_inspect(&self) -> &'static str {
60 match self {
61 $(
62 $name::$variant $(
63 ( $(generate_inspect!(@underscore $data)),+ )
64 )? => stringify!($variant),
65 )*
66 }
67 }
68 }
69 };
70}
71
72generate_inspect! {
73 #[derive(PartialEq, Debug, Clone)]
77 pub enum Request {
78 Get,
80
81 Listen,
83
84 OnCameraSWState(bool),
86
87 OnButton(MediaButtons),
89
90 SetAccessibilityInfo(AccessibilityInfo),
92
93 SetVolume(Vec<SetAudioStream>, ftrace::Id),
95
96 SetDisplayInfo(SetDisplayInfo),
98
99 SetDnD(DoNotDisturbInfo),
101
102 SetLocalResetAllowed(bool),
104
105 SetInputStates(Vec<InputDevice>),
107
108 SetIntlInfo(IntlInfo),
110
111 SetKeyboardInfo(KeyboardInfo),
113
114 SetLightGroupValue(String, Vec<LightState>),
116
117 SetNightModeInfo(NightModeInfo),
119
120 Restore,
122
123 Rebroadcast,
125
126 SetUserDataSharingConsent(Option<bool>),
128
129 SetConfigurationInterfaces(SetConfigurationInterfacesParams),
131 }
132}
133
134#[derive(Clone, PartialEq, Debug)]
137pub enum Payload {
138 Request(Request),
145 Response(Response),
149}
150
151payload_convert!(Setting, Payload);
153
154#[derive(thiserror::Error, Debug, Clone, PartialEq)]
155pub enum Error {
158 #[error("Unimplemented Request:{0:?} for setting type: {1:?}")]
159 UnimplementedRequest(SettingType, Request),
160
161 #[error("Storage failure for setting type: {0:?}")]
162 StorageFailure(SettingType),
163
164 #[error("Initialization failure: cause {0:?}")]
165 InitFailure(Cow<'static, str>),
166
167 #[error("Restoration of setting on controller startup failed: cause {0:?}")]
168 RestoreFailure(Cow<'static, str>),
169
170 #[error("Invalid argument for setting type: {0:?} argument:{1:?} value:{2:?}")]
171 InvalidArgument(SettingType, Cow<'static, str>, Cow<'static, str>),
172
173 #[error(
174 "Incompatible argument values passed: {setting_type:?} argument:{main_arg:?} cannot be \
175 combined with arguments:[{other_args:?}] with respective values:[{values:?}]. {reason:?}"
176 )]
177 IncompatibleArguments {
178 setting_type: SettingType,
179 main_arg: Cow<'static, str>,
180 other_args: Cow<'static, str>,
181 values: Cow<'static, str>,
182 reason: Cow<'static, str>,
183 },
184
185 #[error("External failure for setting type:{0:?} dependency: {1:?} request:{2:?} error:{3}")]
186 ExternalFailure(SettingType, Cow<'static, str>, Cow<'static, str>, Cow<'static, str>),
187
188 #[error("Unhandled type: {0:?}")]
189 UnhandledType(SettingType),
190
191 #[error("Delivery error for type: {0:?} received by: {1:?}")]
192 DeliveryError(SettingType, SettingType),
193
194 #[error("Unexpected error: {0}")]
195 UnexpectedError(Cow<'static, str>),
196
197 #[error("Undeliverable Request:{1:?} for setting type: {0:?}")]
198 UndeliverableError(SettingType, Request),
199
200 #[error("Unsupported request for setting type: {0:?}")]
201 UnsupportedError(SettingType),
202
203 #[error("Communication error")]
204 CommunicationError,
205
206 #[error("Irrecoverable error")]
207 IrrecoverableError,
208
209 #[error("Timeout error")]
210 TimeoutError,
211}
212
213impl From<ControllerError> for Error {
214 fn from(error: ControllerError) -> Self {
215 match error {
216 ControllerError::UnimplementedRequest(setting_type, request) => {
217 Error::UnimplementedRequest(setting_type, request)
218 }
219 ControllerError::WriteFailure(setting_type) => Error::StorageFailure(setting_type),
220 ControllerError::InitFailure(description) => Error::InitFailure(description),
221 ControllerError::RestoreFailure(description) => Error::RestoreFailure(description),
222 ControllerError::ExternalFailure(setting_type, dependency, request, error) => {
223 Error::ExternalFailure(setting_type, dependency, request, error)
224 }
225 ControllerError::InvalidArgument(setting_type, argument, value) => {
226 Error::InvalidArgument(setting_type, argument, value)
227 }
228 ControllerError::IncompatibleArguments {
229 setting_type,
230 main_arg,
231 other_args,
232 values,
233 reason,
234 } => {
235 Error::IncompatibleArguments { setting_type, main_arg, other_args, values, reason }
236 }
237 ControllerError::UnhandledType(setting_type) => Error::UnhandledType(setting_type),
238 ControllerError::UnexpectedError(error) => Error::UnexpectedError(error),
239 ControllerError::UndeliverableError(setting_type, request) => {
240 Error::UndeliverableError(setting_type, request)
241 }
242 ControllerError::UnsupportedError(setting_type) => {
243 Error::UnsupportedError(setting_type)
244 }
245 ControllerError::DeliveryError(setting_type, setting_type_2) => {
246 Error::DeliveryError(setting_type, setting_type_2)
247 }
248 ControllerError::IrrecoverableError => Error::IrrecoverableError,
249 ControllerError::TimeoutError => Error::TimeoutError,
250 ControllerError::ExitError => Error::IrrecoverableError,
251 }
252 }
253}
254
255#[derive(thiserror::Error, Debug, Clone, PartialEq)]
256pub enum SettingHandlerFactoryError {
257 #[error("Setting type {0:?} not registered in environment")]
258 SettingNotFound(SettingType),
259
260 #[error("Cannot find setting handler generator for {0:?}")]
261 GeneratorNotFound(SettingType),
262
263 #[error("MessageHub Messenger for setting handler could not be created")]
264 HandlerMessengerError,
265
266 #[error("MessageHub Messenger for controller messenger could not be created")]
267 ControllerMessengerError,
268
269 #[error("MessageHub Messenger for lifecycle messenger could not be created")]
270 LifecycleMessengerError,
271
272 #[error("Setting handler for {0:?} failed to startup. cause: {1:?}")]
273 HandlerStartupError(SettingType, Cow<'static, str>),
274}
275
276#[async_trait(?Send)]
279pub(crate) trait SettingHandlerFactory {
280 async fn generate(
281 &mut self,
282 setting_type: SettingType,
283 delegate: Delegate,
284 notifier_signature: Signature,
285 ) -> Result<Signature, SettingHandlerFactoryError>;
286}
287
288pub struct Environment {
289 pub settings: HashSet<SettingType>,
290 pub service_context: Rc<ServiceContext>,
291}
292
293impl Clone for Environment {
294 fn clone(&self) -> Environment {
295 Environment::new(self.settings.clone(), self.service_context.clone())
296 }
297}
298
299impl Environment {
300 pub(crate) fn new(
301 settings: HashSet<SettingType>,
302 service_context: Rc<ServiceContext>,
303 ) -> Environment {
304 Environment { settings, service_context }
305 }
306}
307
308pub struct Context {
311 pub setting_type: SettingType,
312 pub messenger: Messenger,
313 pub receptor: Receptor,
314 pub notifier_signature: Signature,
315 pub environment: Environment,
316 pub id: u64,
317}
318
319impl Context {
320 pub(crate) fn new(
321 setting_type: SettingType,
322 messenger: Messenger,
323 receptor: Receptor,
324 notifier_signature: Signature,
325 environment: Environment,
326 id: u64,
327 ) -> Context {
328 Context { setting_type, messenger, receptor, notifier_signature, environment, id }
329 }
330}
331
332#[cfg(test)]
335pub(crate) struct ContextBuilder {
336 setting_type: SettingType,
337 settings: HashSet<SettingType>,
338 service_context: Option<Rc<ServiceContext>>,
339 messenger: Messenger,
340 receptor: Receptor,
341 notifier_signature: Signature,
342 id: u64,
343}
344
345#[cfg(test)]
346impl ContextBuilder {
347 pub(crate) fn new(
348 setting_type: SettingType,
349 messenger: Messenger,
350 receptor: Receptor,
351 notifier_signature: Signature,
352 id: u64,
353 ) -> Self {
354 Self {
355 setting_type,
356 settings: HashSet::new(),
357 service_context: None,
358 messenger,
359 receptor,
360 notifier_signature,
361 id,
362 }
363 }
364
365 pub(crate) fn build(self) -> Context {
367 let service_context =
368 self.service_context.unwrap_or_else(|| Rc::new(ServiceContext::new(None, None)));
369 let environment = Environment::new(self.settings, service_context);
370
371 Context::new(
376 self.setting_type,
377 self.messenger,
378 self.receptor,
379 self.notifier_signature,
380 environment,
381 self.id,
382 )
383 }
384}