Skip to main content

framework_tool_tui/framework/
fingerprint.rs

1use color_eyre::eyre::Report;
2use framework_lib::chromium_ec::{commands::FpLedBrightnessLevel, CrosEc};
3
4use crate::framework::EcErrorWrapper;
5
6const FP_LED_BRIGHTNESS_LEVEL_LOW: u8 = 15;
7const FP_LED_BRIGHTNESS_LEVEL_MEDIUM: u8 = 40;
8const FP_LED_BRIGHTNESS_LEVEL_HIGH: u8 = 55;
9
10pub enum FpLedBrightnessCapability {
11    Level,
12    Percentage,
13}
14
15pub struct Fingerprint {
16    pub led_brightness_capability: FpLedBrightnessCapability,
17}
18
19impl Fingerprint {
20    pub fn new(ec: &CrosEc) -> color_eyre::Result<Self> {
21        let led_capability = match ec
22            .get_fp_led_level()
23            .map_err(|error| Report::from(EcErrorWrapper(error)))?
24        {
25            (_, Some(_)) => FpLedBrightnessCapability::Percentage,
26            (_, None) => FpLedBrightnessCapability::Level,
27        };
28
29        Ok(Self {
30            led_brightness_capability: led_capability,
31        })
32    }
33
34    pub fn percentage() -> Self {
35        Self {
36            led_brightness_capability: FpLedBrightnessCapability::Percentage,
37        }
38    }
39
40    pub fn level() -> Self {
41        Self {
42            led_brightness_capability: FpLedBrightnessCapability::Level,
43        }
44    }
45
46    pub fn adjust_led_brightness_by_delta(&self, current: u8, delta: i8) -> u8 {
47        match self.led_brightness_capability {
48            FpLedBrightnessCapability::Level => {
49                let level = led_brightness_percentage_to_level(current);
50                let new_level = adjust_led_brightness_level_by_delta(level, delta);
51
52                led_brightness_level_to_percentage(current, new_level)
53            }
54            FpLedBrightnessCapability::Percentage => {
55                let new_value = current as i8 + delta;
56
57                // NOTE: disable setting the FP brightness to less than 5%
58                if new_value < 5 {
59                    current
60                } else {
61                    new_value as u8
62                }
63            }
64        }
65    }
66}
67
68pub fn led_brightness_percentage_to_level(value: u8) -> FpLedBrightnessLevel {
69    if value <= FP_LED_BRIGHTNESS_LEVEL_LOW {
70        FpLedBrightnessLevel::Low
71    } else if value <= FP_LED_BRIGHTNESS_LEVEL_MEDIUM {
72        FpLedBrightnessLevel::Medium
73    } else {
74        FpLedBrightnessLevel::High
75    }
76}
77
78pub fn led_brightness_percentage_to_level_name(value: u8) -> &'static str {
79    if value <= FP_LED_BRIGHTNESS_LEVEL_LOW {
80        "Low"
81    } else if value <= FP_LED_BRIGHTNESS_LEVEL_MEDIUM {
82        "Medium"
83    } else {
84        "High"
85    }
86}
87
88fn led_brightness_level_to_percentage(current: u8, level: FpLedBrightnessLevel) -> u8 {
89    match level {
90        FpLedBrightnessLevel::Low => FP_LED_BRIGHTNESS_LEVEL_LOW,
91        FpLedBrightnessLevel::Medium => FP_LED_BRIGHTNESS_LEVEL_MEDIUM,
92        FpLedBrightnessLevel::High => FP_LED_BRIGHTNESS_LEVEL_HIGH,
93        _ => current,
94    }
95}
96
97fn adjust_led_brightness_level_by_delta(
98    level: FpLedBrightnessLevel,
99    delta: i8,
100) -> FpLedBrightnessLevel {
101    match level {
102        FpLedBrightnessLevel::Low => {
103            if delta > 0 {
104                FpLedBrightnessLevel::Medium
105            } else {
106                FpLedBrightnessLevel::High
107            }
108        }
109        FpLedBrightnessLevel::Medium => {
110            if delta > 0 {
111                FpLedBrightnessLevel::High
112            } else {
113                FpLedBrightnessLevel::Low
114            }
115        }
116        FpLedBrightnessLevel::High => {
117            if delta > 0 {
118                FpLedBrightnessLevel::Low
119            } else {
120                FpLedBrightnessLevel::Medium
121            }
122        }
123        _ => level,
124    }
125}
126
127#[cfg(test)]
128mod tests {
129
130    use crate::framework::fingerprint::Fingerprint;
131
132    #[test]
133    fn adjust_led_brightness_by_delta_for_percentage() {
134        let fingerprint = Fingerprint::percentage();
135
136        let result_five = fingerprint.adjust_led_brightness_by_delta(10, -5);
137        let result_six = fingerprint.adjust_led_brightness_by_delta(11, -5);
138        let result_less_than_five = fingerprint.adjust_led_brightness_by_delta(9, -5);
139
140        assert!(result_five == 5);
141        assert!(result_six == 6);
142        assert!(result_less_than_five == 9);
143    }
144}