settings/night_mode/
night_mode_controller.rs1use super::night_mode_fidl_handler::Publisher;
6use crate::night_mode::types::NightModeInfo;
7use anyhow::Error;
8use fuchsia_async as fasync;
9use futures::channel::mpsc::UnboundedReceiver;
10use futures::channel::oneshot::Sender;
11use futures::StreamExt;
12use settings_common::inspect::event::{ResponseType, SettingValuePublisher};
13use settings_storage::device_storage::{DeviceStorage, DeviceStorageCompatible};
14use settings_storage::storage_factory::{NoneT, StorageAccess, StorageFactory};
15use settings_storage::UpdateState;
16use std::rc::Rc;
17
18impl DeviceStorageCompatible for NightModeInfo {
19 type Loader = NoneT;
20 const KEY: &'static str = "night_mode_info";
21}
22
23impl StorageAccess for NightModeController {
24 type Storage = DeviceStorage;
25 type Data = NightModeInfo;
26 const STORAGE_KEY: &'static str = NightModeInfo::KEY;
27}
28
29#[derive(thiserror::Error, Debug)]
30pub(crate) enum NightModeError {
31 #[error("Write failed for NightMode: {0:?}")]
32 WriteFailure(Error),
33}
34
35impl From<&NightModeError> for ResponseType {
36 fn from(error: &NightModeError) -> Self {
37 match error {
38 NightModeError::WriteFailure(..) => ResponseType::StorageFailure,
39 }
40 }
41}
42
43pub(crate) enum Request {
44 Set(Option<bool>, Sender<Result<(), NightModeError>>),
45}
46
47pub struct NightModeController {
48 store: Rc<DeviceStorage>,
49 publisher: Option<Publisher>,
50 setting_value_publisher: SettingValuePublisher<NightModeInfo>,
51}
52
53impl NightModeController {
54 pub(super) async fn new<F>(
55 storage_factory: Rc<F>,
56 setting_value_publisher: SettingValuePublisher<NightModeInfo>,
57 ) -> Self
58 where
59 F: StorageFactory<Storage = DeviceStorage>,
60 {
61 NightModeController {
62 store: storage_factory.get_store().await,
63 publisher: None,
64 setting_value_publisher,
65 }
66 }
67
68 pub(super) fn register_publisher(&mut self, publisher: Publisher) {
69 self.publisher = Some(publisher);
70 }
71
72 fn publish(&self, info: NightModeInfo) {
73 let _ = self.setting_value_publisher.publish(&info);
74 if let Some(publisher) = self.publisher.as_ref() {
75 publisher.set(info);
76 }
77 }
78
79 pub(super) async fn handle(
80 self,
81 mut request_rx: UnboundedReceiver<Request>,
82 ) -> fasync::Task<()> {
83 fasync::Task::local(async move {
84 while let Some(request) = request_rx.next().await {
85 let Request::Set(night_mode_enabled, tx) = request;
86 let res = self.set(night_mode_enabled).await.map(|info| {
87 if let Some(info) = info {
88 self.publish(info);
89 }
90 });
91 let _ = tx.send(res);
92 }
93 })
94 }
95
96 async fn set(
97 &self,
98 night_mode_enabled: Option<bool>,
99 ) -> Result<Option<NightModeInfo>, NightModeError> {
100 let mut info = self.store.get::<NightModeInfo>().await;
101 info.night_mode_enabled = night_mode_enabled;
102
103 self.store
104 .write(&info)
105 .await
106 .map(|state| (UpdateState::Updated == state).then_some(info))
107 .map_err(NightModeError::WriteFailure)
108 }
109
110 pub(super) async fn restore(&self) -> NightModeInfo {
111 self.store.get::<NightModeInfo>().await
112 }
113}