1use super::types::SetDisplayInfo;
6use crate::base::SettingType;
7use crate::display::display_configuration::{
8 ConfigurationThemeMode, ConfigurationThemeType, DisplayConfiguration,
9};
10use crate::display::display_fidl_handler::Publisher;
11use crate::display::types::{DisplayInfo, LowLightMode, Theme, ThemeBuilder, ThemeMode, ThemeType};
12use crate::handler::setting_handler::ControllerError;
13use anyhow::Error;
14use async_trait::async_trait;
15use fidl_fuchsia_ui_brightness::{
16 ControlMarker as BrightnessControlMarker, ControlProxy as BrightnessControlProxy,
17};
18use fuchsia_async as fasync;
19use futures::StreamExt;
20use futures::channel::mpsc::UnboundedReceiver;
21use futures::channel::oneshot::Sender;
22use serde::{Deserialize, Serialize};
23use settings_common::call;
24use settings_common::config::default_settings::DefaultSetting;
25use settings_common::inspect::event::{ExternalEventPublisher, SettingValuePublisher};
26use settings_common::service_context::{ExternalServiceProxy, ServiceContext};
27use settings_common::utils::Merge;
28use settings_storage::UpdateState;
29use settings_storage::device_storage::{DeviceStorage, DeviceStorageCompatible};
30use settings_storage::storage_factory::{DefaultLoader, NoneT, StorageAccess, StorageFactory};
31use std::rc::Rc;
32use std::sync::Mutex;
33
34pub(super) const DEFAULT_MANUAL_BRIGHTNESS_VALUE: f32 = 0.5;
35pub(super) const DEFAULT_AUTO_BRIGHTNESS_VALUE: f32 = 0.5;
36
37pub(crate) const DEFAULT_DISPLAY_INFO: DisplayInfo = DisplayInfo::new(
39 false, DEFAULT_MANUAL_BRIGHTNESS_VALUE, DEFAULT_AUTO_BRIGHTNESS_VALUE, true, LowLightMode::Disable, None, );
46
47pub struct DisplayInfoLoader {
51 display_configuration: Mutex<DefaultSetting<DisplayConfiguration, &'static str>>,
52}
53
54impl DisplayInfoLoader {
55 pub(crate) fn new(default_setting: DefaultSetting<DisplayConfiguration, &'static str>) -> Self {
56 Self { display_configuration: Mutex::new(default_setting) }
57 }
58}
59
60impl DefaultLoader for DisplayInfoLoader {
61 type Result = DisplayInfo;
62
63 fn default_value(&self) -> Self::Result {
64 let mut default_display_info = DEFAULT_DISPLAY_INFO;
65
66 if let Ok(Some(display_configuration)) =
67 self.display_configuration.lock().unwrap().get_cached_value()
68 {
69 default_display_info.theme = Some(Theme {
70 theme_type: Some(match display_configuration.theme.theme_type {
71 ConfigurationThemeType::Light => ThemeType::Light,
72 }),
73 theme_mode: if display_configuration
74 .theme
75 .theme_mode
76 .contains(&ConfigurationThemeMode::Auto)
77 {
78 ThemeMode::AUTO
79 } else {
80 ThemeMode::empty()
81 },
82 });
83 }
84
85 default_display_info
86 }
87}
88
89impl DeviceStorageCompatible for DisplayInfo {
90 type Loader = DisplayInfoLoader;
91 const KEY: &'static str = "display_info";
92
93 fn try_deserialize_from(value: &str) -> Result<Self, Error> {
94 Self::extract(value).or_else(|_| DisplayInfoV5::try_deserialize_from(value).map(Self::from))
95 }
96}
97
98impl From<DisplayInfoV5> for DisplayInfo {
99 fn from(v5: DisplayInfoV5) -> Self {
100 DisplayInfo {
101 auto_brightness: v5.auto_brightness,
102 auto_brightness_value: DEFAULT_AUTO_BRIGHTNESS_VALUE,
103 manual_brightness_value: v5.manual_brightness_value,
104 screen_enabled: v5.screen_enabled,
105 low_light_mode: v5.low_light_mode,
106 theme: v5.theme,
107 }
108 }
109}
110
111#[async_trait(?Send)]
112pub trait BrightnessManager: Sized {
113 async fn from_context(
114 service_context: &ServiceContext,
115 external_publisher: ExternalEventPublisher,
116 ) -> Result<Self, ControllerError>;
117 async fn update_brightness(
118 &self,
119 info: DisplayInfo,
120 store: &DeviceStorage,
121 always_send: bool,
124 ) -> Result<Option<DisplayInfo>, ControllerError>;
125}
126
127#[async_trait(?Send)]
128impl BrightnessManager for () {
129 async fn from_context(
130 _: &ServiceContext,
131 _: ExternalEventPublisher,
132 ) -> Result<Self, ControllerError> {
133 Ok(())
134 }
135
136 async fn update_brightness(
139 &self,
140 info: DisplayInfo,
141 store: &DeviceStorage,
142 _: bool,
143 ) -> Result<Option<DisplayInfo>, ControllerError> {
144 if !info.is_finite() {
145 return Err(ControllerError::InvalidArgument(
146 SettingType::Display,
147 "display_info".into(),
148 format!("{info:?}").into(),
149 ));
150 }
151 store
152 .write(&info)
153 .await
154 .map(|state| (UpdateState::Updated == state).then_some(info))
155 .map_err(|e| {
156 log::error!("Failed to update display info {e:?}");
157 ControllerError::WriteFailure(SettingType::Display)
158 })
159 }
160}
161
162pub(crate) struct ExternalBrightnessControl {
163 brightness_service: ExternalServiceProxy<BrightnessControlProxy, ExternalEventPublisher>,
164}
165
166#[async_trait(?Send)]
167impl BrightnessManager for ExternalBrightnessControl {
168 async fn from_context(
169 service_context: &ServiceContext,
170 external_publisher: ExternalEventPublisher,
171 ) -> Result<Self, ControllerError> {
172 service_context
173 .connect_with_publisher::<BrightnessControlMarker, _>(external_publisher)
174 .await
175 .map(|brightness_service| Self { brightness_service })
176 .map_err(|_| {
177 ControllerError::InitFailure("could not connect to brightness service".into())
178 })
179 }
180
181 async fn update_brightness(
182 &self,
183 info: DisplayInfo,
184 store: &DeviceStorage,
185 always_send: bool,
186 ) -> Result<Option<DisplayInfo>, ControllerError> {
187 if !info.is_finite() {
188 return Err(ControllerError::InvalidArgument(
189 SettingType::Display,
190 "display_info".into(),
191 format!("{info:?}").into(),
192 ));
193 }
194 let new_info = store
195 .write(&info)
196 .await
197 .map(|state| (UpdateState::Updated == state).then_some(info))
198 .map_err(|e| {
199 log::error!("Failed to update display info {e:?}");
200 ControllerError::WriteFailure(SettingType::Display)
201 })?;
202 if new_info.is_none() && !always_send {
203 return Ok(None);
204 }
205
206 if info.auto_brightness {
207 call!(self.brightness_service => set_auto_brightness())
208 } else {
209 call!(self.brightness_service => set_manual_brightness(info.manual_brightness_value))
210 }
211 .map(|_| new_info)
212 .map_err(|e| {
213 ControllerError::ExternalFailure(
214 SettingType::Display,
215 "brightness_service".into(),
216 "set_brightness".into(),
217 format!("{e:?}").into(),
218 )
219 })
220 }
221}
222
223pub(crate) enum Request {
224 Set(SetDisplayInfo, Sender<Result<(), ControllerError>>),
225}
226
227pub(crate) struct DisplayController<T = ()> {
228 brightness_manager: T,
229 store: Rc<DeviceStorage>,
230 publisher: Option<Publisher>,
231 setting_value_publisher: SettingValuePublisher<DisplayInfo>,
232}
233
234impl<T> StorageAccess for DisplayController<T> {
235 type Storage = DeviceStorage;
236 type Data = DisplayInfo;
237 const STORAGE_KEY: &'static str = DisplayInfo::KEY;
238}
239
240impl<T> DisplayController<T>
241where
242 T: BrightnessManager + 'static,
243{
244 pub(crate) async fn new<F>(
245 service_context: &ServiceContext,
246 storage_factory: Rc<F>,
247 setting_value_publisher: SettingValuePublisher<DisplayInfo>,
248 external_publisher: ExternalEventPublisher,
249 ) -> Result<DisplayController<T>, ControllerError>
250 where
251 F: StorageFactory<Storage = DeviceStorage>,
252 {
253 let brightness_manager =
254 <T as BrightnessManager>::from_context(service_context, external_publisher).await?;
255 Ok(Self {
256 brightness_manager,
257 store: storage_factory.get_store().await,
258 publisher: None,
259 setting_value_publisher,
260 })
261 }
262
263 pub(crate) async fn restore(&self) -> Result<DisplayInfo, ControllerError> {
264 let display_info = self.store.get::<DisplayInfo>().await;
265 assert!(display_info.is_finite());
266
267 self.brightness_manager
269 .update_brightness(display_info, &self.store, true)
270 .await
271 .map(|info| info.unwrap_or(display_info))
274 }
275
276 pub(crate) async fn handle(
277 self,
278 mut request_rx: UnboundedReceiver<Request>,
279 ) -> fasync::Task<()> {
280 fasync::Task::local(async move {
281 while let Some(request) = request_rx.next().await {
282 let Request::Set(mut set_display_info, tx) = request;
283 let display_info = self.store.get::<DisplayInfo>().await;
284 assert!(display_info.is_finite());
285
286 if let Some(theme) = set_display_info.theme {
287 set_display_info.theme = self.build_theme(theme, &display_info);
288 }
289 let res = self
290 .brightness_manager
291 .update_brightness(display_info.merge(set_display_info), &self.store, false)
292 .await
293 .map(|info| {
294 if let Some(info) = info {
295 self.publish(info);
296 }
297 });
298 let _ = tx.send(res);
299 }
300 })
301 }
302
303 fn build_theme(&self, incoming_theme: Theme, display_info: &DisplayInfo) -> Option<Theme> {
304 let existing_theme_type = display_info.theme.and_then(|theme| theme.theme_type);
305 let new_theme_type = incoming_theme.theme_type.or(existing_theme_type);
306
307 ThemeBuilder::new()
308 .set_theme_type(new_theme_type)
309 .set_theme_mode(incoming_theme.theme_mode)
310 .build()
311 }
312}
313
314impl<T> DisplayController<T> {
315 pub(crate) fn register_publisher(&mut self, publisher: Publisher) {
316 self.publisher = Some(publisher);
317 }
318
319 fn publish(&self, info: DisplayInfo) {
320 let _ = self.setting_value_publisher.publish(&info);
321 if let Some(publisher) = self.publisher.as_ref() {
322 publisher.set(info);
323 }
324 }
325}
326
327#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)]
330pub struct DisplayInfoV1 {
331 pub manual_brightness_value: f32,
333 pub auto_brightness: bool,
334 pub low_light_mode: LowLightMode,
335}
336
337impl DisplayInfoV1 {
338 const fn new(
339 auto_brightness: bool,
340 manual_brightness_value: f32,
341 low_light_mode: LowLightMode,
342 ) -> DisplayInfoV1 {
343 DisplayInfoV1 { manual_brightness_value, auto_brightness, low_light_mode }
344 }
345}
346
347impl DeviceStorageCompatible for DisplayInfoV1 {
348 type Loader = NoneT;
349 const KEY: &'static str = "display_infoV1";
350}
351
352impl Default for DisplayInfoV1 {
353 fn default() -> Self {
354 DisplayInfoV1::new(
355 false, DEFAULT_MANUAL_BRIGHTNESS_VALUE, LowLightMode::Disable, )
359 }
360}
361
362#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)]
365pub struct DisplayInfoV2 {
366 pub manual_brightness_value: f32,
367 pub auto_brightness: bool,
368 pub low_light_mode: LowLightMode,
369 pub theme_mode: ThemeModeV1,
370}
371
372impl DisplayInfoV2 {
373 const fn new(
374 auto_brightness: bool,
375 manual_brightness_value: f32,
376 low_light_mode: LowLightMode,
377 theme_mode: ThemeModeV1,
378 ) -> DisplayInfoV2 {
379 DisplayInfoV2 { manual_brightness_value, auto_brightness, low_light_mode, theme_mode }
380 }
381}
382
383impl DeviceStorageCompatible for DisplayInfoV2 {
384 type Loader = NoneT;
385 const KEY: &'static str = "display_infoV2";
386
387 fn try_deserialize_from(value: &str) -> Result<Self, Error> {
388 Self::extract(value).or_else(|_| DisplayInfoV1::try_deserialize_from(value).map(Self::from))
389 }
390}
391
392impl Default for DisplayInfoV2 {
393 fn default() -> Self {
394 DisplayInfoV2::new(
395 false, DEFAULT_MANUAL_BRIGHTNESS_VALUE, LowLightMode::Disable, ThemeModeV1::Unknown, )
400 }
401}
402
403impl From<DisplayInfoV1> for DisplayInfoV2 {
404 fn from(v1: DisplayInfoV1) -> Self {
405 DisplayInfoV2 {
406 auto_brightness: v1.auto_brightness,
407 manual_brightness_value: v1.manual_brightness_value,
408 low_light_mode: v1.low_light_mode,
409 theme_mode: ThemeModeV1::Unknown,
410 }
411 }
412}
413
414#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)]
415pub enum ThemeModeV1 {
416 Unknown,
417 Default,
418 Light,
419 Dark,
420 Auto,
422}
423
424impl From<ThemeModeV1> for ThemeType {
425 fn from(theme_mode_v1: ThemeModeV1) -> Self {
426 match theme_mode_v1 {
427 ThemeModeV1::Default => ThemeType::Default,
428 ThemeModeV1::Light => ThemeType::Light,
429 ThemeModeV1::Dark => ThemeType::Dark,
430 ThemeModeV1::Unknown | ThemeModeV1::Auto => ThemeType::Unknown,
432 }
433 }
434}
435
436#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)]
437pub struct DisplayInfoV3 {
438 pub manual_brightness_value: f32,
440 pub auto_brightness: bool,
441 pub screen_enabled: bool,
442 pub low_light_mode: LowLightMode,
443 pub theme_mode: ThemeModeV1,
444}
445
446impl DisplayInfoV3 {
447 const fn new(
448 auto_brightness: bool,
449 manual_brightness_value: f32,
450 screen_enabled: bool,
451 low_light_mode: LowLightMode,
452 theme_mode: ThemeModeV1,
453 ) -> DisplayInfoV3 {
454 DisplayInfoV3 {
455 manual_brightness_value,
456 auto_brightness,
457 screen_enabled,
458 low_light_mode,
459 theme_mode,
460 }
461 }
462}
463
464impl DeviceStorageCompatible for DisplayInfoV3 {
465 type Loader = NoneT;
466 const KEY: &'static str = "display_info";
467
468 fn try_deserialize_from(value: &str) -> Result<Self, Error> {
469 Self::extract(value).or_else(|_| DisplayInfoV2::try_deserialize_from(value).map(Self::from))
470 }
471}
472
473impl Default for DisplayInfoV3 {
474 fn default() -> Self {
475 DisplayInfoV3::new(
476 false, DEFAULT_MANUAL_BRIGHTNESS_VALUE, true, LowLightMode::Disable, ThemeModeV1::Unknown, )
482 }
483}
484
485impl From<DisplayInfoV2> for DisplayInfoV3 {
486 fn from(v2: DisplayInfoV2) -> Self {
487 DisplayInfoV3 {
488 auto_brightness: v2.auto_brightness,
489 manual_brightness_value: v2.manual_brightness_value,
490 screen_enabled: true,
491 low_light_mode: v2.low_light_mode,
492 theme_mode: v2.theme_mode,
493 }
494 }
495}
496
497#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)]
498pub struct DisplayInfoV4 {
499 pub manual_brightness_value: f32,
501 pub auto_brightness: bool,
502 pub screen_enabled: bool,
503 pub low_light_mode: LowLightMode,
504 pub theme_type: ThemeType,
505}
506
507impl DisplayInfoV4 {
508 const fn new(
509 auto_brightness: bool,
510 manual_brightness_value: f32,
511 screen_enabled: bool,
512 low_light_mode: LowLightMode,
513 theme_type: ThemeType,
514 ) -> DisplayInfoV4 {
515 DisplayInfoV4 {
516 manual_brightness_value,
517 auto_brightness,
518 screen_enabled,
519 low_light_mode,
520 theme_type,
521 }
522 }
523}
524
525impl From<DisplayInfoV3> for DisplayInfoV4 {
526 fn from(v3: DisplayInfoV3) -> Self {
527 DisplayInfoV4 {
528 auto_brightness: v3.auto_brightness,
529 manual_brightness_value: v3.manual_brightness_value,
530 screen_enabled: v3.screen_enabled,
531 low_light_mode: v3.low_light_mode,
532 theme_type: ThemeType::from(v3.theme_mode),
535 }
536 }
537}
538
539impl DeviceStorageCompatible for DisplayInfoV4 {
540 type Loader = NoneT;
541 const KEY: &'static str = "display_info";
542
543 fn try_deserialize_from(value: &str) -> Result<Self, Error> {
544 Self::extract(value).or_else(|_| DisplayInfoV3::try_deserialize_from(value).map(Self::from))
545 }
546}
547
548impl Default for DisplayInfoV4 {
549 fn default() -> Self {
550 DisplayInfoV4::new(
551 false, DEFAULT_MANUAL_BRIGHTNESS_VALUE, true, LowLightMode::Disable, ThemeType::Unknown, )
557 }
558}
559
560#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)]
561#[serde(deny_unknown_fields)]
562pub struct DisplayInfoV5 {
563 pub manual_brightness_value: f32,
565 pub auto_brightness: bool,
566 pub screen_enabled: bool,
567 pub low_light_mode: LowLightMode,
568 pub theme: Option<Theme>,
569}
570
571impl DisplayInfoV5 {
572 const fn new(
573 auto_brightness: bool,
574 manual_brightness_value: f32,
575 screen_enabled: bool,
576 low_light_mode: LowLightMode,
577 theme: Option<Theme>,
578 ) -> DisplayInfoV5 {
579 DisplayInfoV5 {
580 manual_brightness_value,
581 auto_brightness,
582 screen_enabled,
583 low_light_mode,
584 theme,
585 }
586 }
587}
588
589impl From<DisplayInfoV4> for DisplayInfoV5 {
590 fn from(v4: DisplayInfoV4) -> Self {
591 DisplayInfoV5 {
592 auto_brightness: v4.auto_brightness,
593 manual_brightness_value: v4.manual_brightness_value,
594 screen_enabled: v4.screen_enabled,
595 low_light_mode: v4.low_light_mode,
596 theme: Some(Theme::new(Some(v4.theme_type), ThemeMode::empty())),
598 }
599 }
600}
601
602impl DeviceStorageCompatible for DisplayInfoV5 {
603 type Loader = NoneT;
604 const KEY: &'static str = "display_info";
605
606 fn try_deserialize_from(value: &str) -> Result<Self, Error> {
607 Self::extract(value).or_else(|_| DisplayInfoV4::try_deserialize_from(value).map(Self::from))
608 }
609}
610
611impl Default for DisplayInfoV5 {
612 fn default() -> Self {
613 DisplayInfoV5::new(
614 false, DEFAULT_MANUAL_BRIGHTNESS_VALUE, true, LowLightMode::Disable, Some(Theme::new(Some(ThemeType::Unknown), ThemeMode::empty())), )
620 }
621}
622
623#[cfg(test)]
624mod tests {
625 use super::*;
626
627 #[fuchsia::test]
628 fn test_display_migration_v1_to_v2() {
629 let v1 = DisplayInfoV1 {
630 manual_brightness_value: 0.6,
631 auto_brightness: true,
632 low_light_mode: LowLightMode::Enable,
633 };
634
635 let serialized_v1 = v1.serialize_to();
636 let v2 = DisplayInfoV2::try_deserialize_from(&serialized_v1)
637 .expect("deserialization should succeed");
638
639 assert_eq!(
640 v2,
641 DisplayInfoV2 {
642 manual_brightness_value: v1.manual_brightness_value,
643 auto_brightness: v1.auto_brightness,
644 low_light_mode: v1.low_light_mode,
645 theme_mode: DisplayInfoV2::default().theme_mode,
646 }
647 );
648 }
649
650 #[fuchsia::test]
651 fn test_display_migration_v2_to_v3() {
652 let v2 = DisplayInfoV2 {
653 manual_brightness_value: 0.7,
654 auto_brightness: true,
655 low_light_mode: LowLightMode::Enable,
656 theme_mode: ThemeModeV1::Default,
657 };
658
659 let serialized_v2 = v2.serialize_to();
660 let v3 = DisplayInfoV3::try_deserialize_from(&serialized_v2)
661 .expect("deserialization should succeed");
662
663 assert_eq!(
664 v3,
665 DisplayInfoV3 {
666 manual_brightness_value: v2.manual_brightness_value,
667 auto_brightness: v2.auto_brightness,
668 screen_enabled: DisplayInfoV3::default().screen_enabled,
669 low_light_mode: v2.low_light_mode,
670 theme_mode: v2.theme_mode,
671 }
672 );
673 }
674
675 #[fuchsia::test]
676 fn test_display_migration_v3_to_v4() {
677 let v3 = DisplayInfoV3 {
678 manual_brightness_value: 0.7,
679 auto_brightness: true,
680 low_light_mode: LowLightMode::Enable,
681 theme_mode: ThemeModeV1::Light,
682 screen_enabled: false,
683 };
684
685 let serialized_v3 = v3.serialize_to();
686 let v4 = DisplayInfoV4::try_deserialize_from(&serialized_v3)
687 .expect("deserialization should succeed");
688
689 assert_eq!(
691 v4,
692 DisplayInfoV4 {
693 manual_brightness_value: v3.manual_brightness_value,
694 auto_brightness: v3.auto_brightness,
695 low_light_mode: v3.low_light_mode,
696 theme_type: ThemeType::Light,
697 screen_enabled: v3.screen_enabled,
698 }
699 );
700 }
701
702 #[fuchsia::test]
703 fn test_display_migration_v4_to_v5() {
704 let v4 = DisplayInfoV4 {
705 manual_brightness_value: 0.7,
706 auto_brightness: true,
707 low_light_mode: LowLightMode::Enable,
708 theme_type: ThemeType::Dark,
709 screen_enabled: false,
710 };
711
712 let serialized_v4 = v4.serialize_to();
713 let v5 = DisplayInfoV5::try_deserialize_from(&serialized_v4)
714 .expect("deserialization should succeed");
715
716 assert_eq!(
717 v5,
718 DisplayInfoV5 {
719 manual_brightness_value: v4.manual_brightness_value,
720 auto_brightness: v4.auto_brightness,
721 low_light_mode: v4.low_light_mode,
722 theme: Some(Theme::new(Some(v4.theme_type), ThemeMode::empty())),
723 screen_enabled: v4.screen_enabled,
724 }
725 );
726 }
727
728 #[fuchsia::test]
729 fn test_display_migration_v1_to_current() {
730 let v1 = DisplayInfoV1 {
731 manual_brightness_value: 0.6,
732 auto_brightness: true,
733 low_light_mode: LowLightMode::Enable,
734 };
735
736 let serialized_v1 = v1.serialize_to();
737 let current = DisplayInfo::try_deserialize_from(&serialized_v1)
738 .expect("deserialization should succeed");
739
740 assert_eq!(
741 current,
742 DisplayInfo {
743 manual_brightness_value: v1.manual_brightness_value,
744 auto_brightness: v1.auto_brightness,
745 low_light_mode: v1.low_light_mode,
746 theme: Some(Theme::new(Some(ThemeType::Unknown), ThemeMode::empty())),
747 screen_enabled: DisplayInfoV3::default().screen_enabled,
749 auto_brightness_value: DEFAULT_DISPLAY_INFO.auto_brightness_value,
750 }
751 );
752 }
753
754 #[fuchsia::test]
755 fn test_display_migration_v2_to_current() {
756 let v2 = DisplayInfoV2 {
757 manual_brightness_value: 0.6,
758 auto_brightness: true,
759 low_light_mode: LowLightMode::Enable,
760 theme_mode: ThemeModeV1::Light,
761 };
762
763 let serialized_v2 = v2.serialize_to();
764 let current = DisplayInfo::try_deserialize_from(&serialized_v2)
765 .expect("deserialization should succeed");
766
767 assert_eq!(
768 current,
769 DisplayInfo {
770 manual_brightness_value: v2.manual_brightness_value,
771 auto_brightness: v2.auto_brightness,
772 low_light_mode: v2.low_light_mode,
773 theme: Some(Theme::new(Some(ThemeType::Light), ThemeMode::empty())),
774 screen_enabled: DisplayInfoV3::default().screen_enabled,
776 auto_brightness_value: DEFAULT_DISPLAY_INFO.auto_brightness_value,
777 }
778 );
779 }
780
781 #[fuchsia::test]
782 fn test_display_migration_v3_to_current() {
783 let v3 = DisplayInfoV3 {
784 manual_brightness_value: 0.6,
785 auto_brightness: true,
786 low_light_mode: LowLightMode::Enable,
787 theme_mode: ThemeModeV1::Light,
788 screen_enabled: false,
789 };
790
791 let serialized_v3 = v3.serialize_to();
792 let current = DisplayInfo::try_deserialize_from(&serialized_v3)
793 .expect("deserialization should succeed");
794
795 assert_eq!(
796 current,
797 DisplayInfo {
798 manual_brightness_value: v3.manual_brightness_value,
799 auto_brightness: v3.auto_brightness,
800 low_light_mode: v3.low_light_mode,
801 theme: Some(Theme::new(Some(ThemeType::Light), ThemeMode::empty())),
802 screen_enabled: v3.screen_enabled,
804 auto_brightness_value: DEFAULT_DISPLAY_INFO.auto_brightness_value,
805 }
806 );
807 }
808
809 #[fuchsia::test]
810 fn test_display_migration_v4_to_current() {
811 let v4 = DisplayInfoV4 {
812 manual_brightness_value: 0.6,
813 auto_brightness: true,
814 low_light_mode: LowLightMode::Enable,
815 theme_type: ThemeType::Light,
816 screen_enabled: false,
817 };
818
819 let serialized_v4 = v4.serialize_to();
820 let current = DisplayInfo::try_deserialize_from(&serialized_v4)
821 .expect("deserialization should succeed");
822
823 assert_eq!(
824 current,
825 DisplayInfo {
826 manual_brightness_value: v4.manual_brightness_value,
827 auto_brightness: v4.auto_brightness,
828 low_light_mode: v4.low_light_mode,
829 theme: Some(Theme::new(Some(ThemeType::Light), ThemeMode::empty())),
830 screen_enabled: v4.screen_enabled,
831 auto_brightness_value: DEFAULT_DISPLAY_INFO.auto_brightness_value,
832 }
833 );
834 }
835
836 #[fuchsia::test]
837 fn test_display_migration_v5_to_current() {
838 let v5 = DisplayInfoV5 {
839 manual_brightness_value: 0.6,
840 auto_brightness: true,
841 low_light_mode: LowLightMode::Enable,
842 theme: Some(Theme::new(Some(ThemeType::Light), ThemeMode::AUTO)),
843 screen_enabled: false,
844 };
845
846 let serialized_v5 = v5.serialize_to();
847 let current = DisplayInfo::try_deserialize_from(&serialized_v5)
848 .expect("deserialization should succeed");
849
850 assert_eq!(
851 current,
852 DisplayInfo {
853 manual_brightness_value: v5.manual_brightness_value,
854 auto_brightness: v5.auto_brightness,
855 low_light_mode: v5.low_light_mode,
856 theme: Some(Theme::new(Some(ThemeType::Light), ThemeMode::AUTO)),
857 screen_enabled: v5.screen_enabled,
858 auto_brightness_value: DEFAULT_DISPLAY_INFO.auto_brightness_value,
859 }
860 );
861 }
862}