| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use crate::light::light_hardware_configuration::DisableConditions; |
| use serde::{Deserialize, Serialize}; |
| use std::collections::HashMap; |
| use std::convert::TryFrom; |
| |
| #[derive(PartialEq, Debug, Clone, Serialize, Deserialize)] |
| pub struct LightInfo { |
| pub light_groups: HashMap<String, LightGroup>, |
| } |
| |
| impl LightInfo { |
| pub fn contains_light_group_name(self, name: String) -> bool { |
| self.light_groups.contains_key(name.as_str()) |
| } |
| } |
| |
| /// Internal representation of a light group. |
| #[derive(PartialEq, Debug, Clone, Serialize, Deserialize)] |
| pub struct LightGroup { |
| pub name: String, |
| pub enabled: bool, |
| pub light_type: LightType, |
| pub lights: Vec<LightState>, |
| |
| /// Each light in the underlying fuchsia.hardware.light API has a unique, fixed index. We need |
| /// to remember the index of the lights in this light group in order to write values back. |
| pub hardware_index: Vec<u32>, |
| |
| /// A list of conditions under which the "enabled" field of the light group should be false, |
| /// which signals to clients the light's state is being overridden by external conditions, such |
| /// as an LED dedicated to showing that a device's mic is muted that is off when the mic is not |
| /// muted. |
| /// |
| /// Lights that are disabled can still have their value set, but the changes may not be |
| /// noticeable to the user until the condition disabling/overriding ends. |
| pub disable_conditions: Vec<DisableConditions>, |
| } |
| |
| impl From<LightGroup> for fidl_fuchsia_settings::LightGroup { |
| fn from(src: LightGroup) -> Self { |
| fidl_fuchsia_settings::LightGroup { |
| name: Some(src.name), |
| enabled: Some(src.enabled), |
| type_: Some(src.light_type.into()), |
| lights: Some(src.lights.into_iter().map(LightState::into).collect()), |
| ..fidl_fuchsia_settings::LightGroup::EMPTY |
| } |
| } |
| } |
| |
| #[derive(PartialEq, Debug, Copy, Clone, Serialize, Deserialize)] |
| pub enum LightType { |
| Brightness, |
| Rgb, |
| Simple, |
| } |
| |
| impl From<fidl_fuchsia_settings::LightType> for LightType { |
| fn from(src: fidl_fuchsia_settings::LightType) -> Self { |
| match src { |
| fidl_fuchsia_settings::LightType::Brightness => LightType::Brightness, |
| fidl_fuchsia_settings::LightType::Rgb => LightType::Rgb, |
| fidl_fuchsia_settings::LightType::Simple => LightType::Simple, |
| } |
| } |
| } |
| |
| impl From<LightType> for fidl_fuchsia_settings::LightType { |
| fn from(src: LightType) -> Self { |
| match src { |
| LightType::Brightness => fidl_fuchsia_settings::LightType::Brightness, |
| LightType::Rgb => fidl_fuchsia_settings::LightType::Rgb, |
| LightType::Simple => fidl_fuchsia_settings::LightType::Simple, |
| } |
| } |
| } |
| |
| /// Converts between a Capability and a LightType for convenience for tests. |
| impl From<fidl_fuchsia_hardware_light::Capability> for LightType { |
| fn from(src: fidl_fuchsia_hardware_light::Capability) -> Self { |
| match src { |
| fidl_fuchsia_hardware_light::Capability::Brightness => LightType::Brightness, |
| fidl_fuchsia_hardware_light::Capability::Rgb => LightType::Rgb, |
| fidl_fuchsia_hardware_light::Capability::Simple => LightType::Simple, |
| } |
| } |
| } |
| |
| /// Converts between a LightType and a Capability for convenience for tests. |
| impl From<LightType> for fidl_fuchsia_hardware_light::Capability { |
| fn from(src: LightType) -> Self { |
| match src { |
| LightType::Brightness => fidl_fuchsia_hardware_light::Capability::Brightness, |
| LightType::Rgb => fidl_fuchsia_hardware_light::Capability::Rgb, |
| LightType::Simple => fidl_fuchsia_hardware_light::Capability::Simple, |
| } |
| } |
| } |
| |
| #[derive(PartialEq, Debug, Clone, Serialize, Deserialize)] |
| pub struct LightState { |
| pub value: Option<LightValue>, |
| } |
| |
| impl From<fidl_fuchsia_settings::LightState> for LightState { |
| fn from(src: fidl_fuchsia_settings::LightState) -> Self { |
| LightState { value: src.value.map(LightValue::from) } |
| } |
| } |
| |
| impl From<LightState> for fidl_fuchsia_settings::LightState { |
| fn from(src: LightState) -> Self { |
| fidl_fuchsia_settings::LightState { |
| value: src.value.map(fidl_fuchsia_settings::LightValue::from), |
| ..fidl_fuchsia_settings::LightState::EMPTY |
| } |
| } |
| } |
| |
| #[derive(PartialEq, Debug, Clone, Serialize, Deserialize)] |
| pub enum LightValue { |
| Brightness(f64), |
| Rgb(ColorRgb), |
| Simple(bool), |
| } |
| |
| impl From<fidl_fuchsia_settings::LightValue> for LightValue { |
| fn from(src: fidl_fuchsia_settings::LightValue) -> Self { |
| match src { |
| fidl_fuchsia_settings::LightValue::On(on) => LightValue::Simple(on), |
| fidl_fuchsia_settings::LightValue::Brightness(brightness) => { |
| LightValue::Brightness(brightness) |
| } |
| fidl_fuchsia_settings::LightValue::Color(color) => LightValue::Rgb(color.into()), |
| } |
| } |
| } |
| |
| impl From<fidl_fuchsia_hardware_light::Rgb> for LightValue { |
| fn from(src: fidl_fuchsia_hardware_light::Rgb) -> Self { |
| LightValue::Rgb(ColorRgb { |
| red: src.red as f32, |
| green: src.green as f32, |
| blue: src.blue as f32, |
| }) |
| } |
| } |
| |
| impl From<LightValue> for fidl_fuchsia_settings::LightValue { |
| fn from(src: LightValue) -> Self { |
| match src { |
| LightValue::Simple(on) => fidl_fuchsia_settings::LightValue::On(on), |
| LightValue::Brightness(brightness) => { |
| fidl_fuchsia_settings::LightValue::Brightness(brightness) |
| } |
| LightValue::Rgb(color) => fidl_fuchsia_settings::LightValue::Color(color.into()), |
| } |
| } |
| } |
| |
| #[derive(PartialEq, Debug, Clone, Serialize, Deserialize)] |
| pub struct ColorRgb { |
| pub red: f32, |
| pub green: f32, |
| pub blue: f32, |
| } |
| |
| impl From<fidl_fuchsia_ui_types::ColorRgb> for ColorRgb { |
| fn from(src: fidl_fuchsia_ui_types::ColorRgb) -> Self { |
| ColorRgb { red: src.red.into(), green: src.green.into(), blue: src.blue.into() } |
| } |
| } |
| |
| impl From<ColorRgb> for fidl_fuchsia_ui_types::ColorRgb { |
| fn from(src: ColorRgb) -> Self { |
| fidl_fuchsia_ui_types::ColorRgb { |
| red: src.red.into(), |
| green: src.green.into(), |
| blue: src.blue.into(), |
| } |
| } |
| } |
| |
| /// Converts between internal RGB representation and underlying fuchsia.hardware.light |
| /// representation. |
| impl TryFrom<ColorRgb> for fidl_fuchsia_hardware_light::Rgb { |
| type Error = &'static str; |
| fn try_from(src: ColorRgb) -> Result<Self, Self::Error> { |
| if src.red > 1.0 |
| || src.green > 1.0 |
| || src.blue > 1.0 |
| || src.red < 0.0 |
| || src.green < 0.0 |
| || src.blue < 0.0 |
| { |
| return Err("values must be between 0.0 and 1.0 inclusive"); |
| } |
| |
| Ok(fidl_fuchsia_hardware_light::Rgb { |
| red: src.red as f64, |
| green: src.green as f64, |
| blue: src.blue as f64, |
| }) |
| } |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use crate::light::types::ColorRgb; |
| use std::convert::TryFrom; |
| |
| #[test] |
| fn test_try_from_rgb() { |
| assert!(fidl_fuchsia_hardware_light::Rgb::try_from(ColorRgb { |
| red: -0.0, |
| green: 0.1, |
| blue: 1.0 |
| }) |
| .is_ok()); |
| |
| assert!(fidl_fuchsia_hardware_light::Rgb::try_from(ColorRgb { |
| red: 0.0 - f32::EPSILON, |
| green: 0.1, |
| blue: 0.2 |
| }) |
| .is_err()); |
| |
| assert!(fidl_fuchsia_hardware_light::Rgb::try_from(ColorRgb { |
| red: 0.3, |
| green: 1.0 + f32::EPSILON, |
| blue: 0.2 |
| }) |
| .is_err()); |
| |
| assert_eq!( |
| fidl_fuchsia_hardware_light::Rgb::try_from(ColorRgb { |
| red: 0.0, |
| green: 1.0, |
| blue: 0.5 |
| }), |
| Ok(fidl_fuchsia_hardware_light::Rgb { red: 0.0, green: 1.0, blue: 0.5 }) |
| ); |
| } |
| } |