Skip to main content

settings_display/
types.rs

1// Copyright 2021 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 bitflags::bitflags;
6use serde::{Deserialize, Serialize};
7use settings_common::inspect::event::Nameable;
8use settings_common::utils::Merge;
9
10#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)]
11#[serde(deny_unknown_fields)]
12pub struct DisplayInfo {
13    /// The last brightness value that was manually set.
14    pub manual_brightness_value: f32,
15    pub auto_brightness_value: f32,
16    pub auto_brightness: bool,
17    pub screen_enabled: bool,
18    pub low_light_mode: LowLightMode,
19    pub theme: Option<Theme>,
20}
21
22impl DisplayInfo {
23    pub(crate) const fn new(
24        auto_brightness: bool,
25        manual_brightness_value: f32,
26        auto_brightness_value: f32,
27        screen_enabled: bool,
28        low_light_mode: LowLightMode,
29        theme: Option<Theme>,
30    ) -> DisplayInfo {
31        DisplayInfo {
32            manual_brightness_value,
33            auto_brightness_value,
34            auto_brightness,
35            screen_enabled,
36            low_light_mode,
37            theme,
38        }
39    }
40
41    pub(crate) fn is_finite(&self) -> bool {
42        self.manual_brightness_value.is_finite() && self.auto_brightness_value.is_finite()
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn test_display_info_is_finite() {
52        let mut info = DisplayInfo::new(false, 0.5, 0.5, true, LowLightMode::Disable, None);
53        assert!(info.is_finite());
54
55        info.manual_brightness_value = f32::NAN;
56        assert!(!info.is_finite());
57
58        info.manual_brightness_value = 0.5;
59        info.auto_brightness_value = f32::NAN;
60        assert!(!info.is_finite());
61
62        info.manual_brightness_value = f32::INFINITY;
63        assert!(!info.is_finite());
64
65        info.auto_brightness_value = f32::NEG_INFINITY;
66        assert!(!info.is_finite());
67    }
68}
69
70impl Nameable for DisplayInfo {
71    const NAME: &str = "Display";
72}
73
74#[derive(Debug, Default, PartialEq, Copy, Clone)]
75pub struct SetDisplayInfo {
76    pub manual_brightness_value: Option<f32>,
77    pub auto_brightness_value: Option<f32>,
78    pub auto_brightness: Option<bool>,
79    pub screen_enabled: Option<bool>,
80    pub low_light_mode: Option<LowLightMode>,
81    pub theme: Option<Theme>,
82}
83
84impl Merge<SetDisplayInfo> for DisplayInfo {
85    fn merge(&self, other: SetDisplayInfo) -> Self {
86        Self {
87            manual_brightness_value: other
88                .manual_brightness_value
89                .unwrap_or(self.manual_brightness_value),
90            auto_brightness_value: other
91                .auto_brightness_value
92                .unwrap_or(self.auto_brightness_value),
93            auto_brightness: other.auto_brightness.unwrap_or(self.auto_brightness),
94            screen_enabled: other.screen_enabled.unwrap_or(self.screen_enabled),
95            low_light_mode: other.low_light_mode.unwrap_or(self.low_light_mode),
96            theme: other.theme.or(self.theme),
97        }
98    }
99}
100
101#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize, Hash, Eq)]
102pub enum LowLightMode {
103    /// Device should not be in low-light mode.
104    Disable,
105    /// Device should not be in low-light mode and should transition
106    /// out of it immediately.
107    DisableImmediately,
108    /// Device should be in low-light mode.
109    Enable,
110}
111
112#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)]
113pub enum ThemeType {
114    Unknown,
115    Default,
116    Light,
117    Dark,
118}
119
120bitflags! {
121    #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
122    pub struct ThemeMode: u32 {
123        /// Product can choose a theme based on ambient cues.
124        const AUTO = 0b00000001;
125    }
126}
127
128bitflags_serde_legacy::impl_traits!(ThemeMode);
129
130#[derive(Debug, Clone, PartialEq, Copy, Serialize, Deserialize)]
131pub struct Theme {
132    pub theme_type: Option<ThemeType>,
133    pub theme_mode: ThemeMode,
134}
135
136impl Theme {
137    pub(super) fn new(theme_type: Option<ThemeType>, theme_mode: ThemeMode) -> Self {
138        Self { theme_type, theme_mode }
139    }
140}
141
142/// Builder for `Theme` that with a `build` method that returns
143/// an `Option` that will be None if all the fields of the Theme would
144/// otherwise be empty.
145pub struct ThemeBuilder {
146    theme_type: Option<ThemeType>,
147    theme_mode: ThemeMode,
148}
149
150impl ThemeBuilder {
151    pub(super) fn new() -> Self {
152        Self { theme_type: None, theme_mode: ThemeMode::empty() }
153    }
154
155    pub(super) fn set_theme_type(&mut self, theme_type: Option<ThemeType>) -> &mut Self {
156        self.theme_type = theme_type;
157        self
158    }
159
160    pub(super) fn set_theme_mode(&mut self, theme_mode: ThemeMode) -> &mut Self {
161        self.theme_mode = theme_mode;
162        self
163    }
164
165    pub(super) fn build(&self) -> Option<Theme> {
166        if self.theme_type.is_none() && self.theme_mode.is_empty() {
167            None
168        } else {
169            Some(Theme { theme_type: self.theme_type, theme_mode: self.theme_mode })
170        }
171    }
172}