blob: c0a1e624e3a588577e3580a4b51c3d9df70ab969 [file] [log] [blame]
// 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.
//! Service-wide definitions.
//!
//! # Summary
//!
//! The base mod houses the core definitions for communicating information
//! across the service. Note that there are currently references to types in
//! other nested base mods. It is the long-term intention that the common
//! general (non-domain specific or overarching) definitions are migrated here,
//! while particular types, such as setting-specific definitions, are moved to
//! a common base mod underneath the parent setting mod.
use crate::accessibility::types::AccessibilityInfo;
use crate::audio::types::AudioInfo;
use crate::device::types::DeviceInfo;
use crate::display::types::{DisplayInfo, LightData};
use crate::do_not_disturb::types::DoNotDisturbInfo;
use crate::factory_reset::types::FactoryResetInfo;
use crate::input::types::InputInfo;
use crate::intl::types::IntlInfo;
use crate::light::types::LightInfo;
use crate::night_mode::types::NightModeInfo;
use crate::privacy::types::PrivacyInfo;
use crate::setup::types::SetupInfo;
use serde::{Deserialize, Serialize};
use std::array;
use std::collections::HashSet;
use std::convert::TryFrom;
/// The setting types supported by the service.
#[derive(PartialEq, Debug, Eq, Hash, Clone, Copy, Serialize, Deserialize)]
pub enum SettingType {
/// This value is reserved for testing purposes.
#[cfg(test)]
Unknown,
Accessibility,
Account,
Audio,
Device,
Display,
DoNotDisturb,
FactoryReset,
Input,
Intl,
Light,
LightSensor,
NightMode,
Power,
Privacy,
Setup,
}
/// This macro takes an enum, which has variants associated with exactly one data, and
/// generates the same enum and implements a for_inspect method.
/// The for_inspect method returns variants' names and formated data contents.
#[macro_export]
macro_rules! generate_inspect_with_info {
($(#[$metas:meta])* pub enum $name:ident {
$(
$(#[doc = $str:expr])*
$(#[cfg($test:meta)])?
$variant:ident ( $data:ty )
),* $(,)?
}
) => {
$(#[$metas])*
pub enum $name {
$(
$(#[doc = $str])*
$(#[cfg($test)])?
$variant($data),
)*
}
impl $name {
/// Returns the name of the enum and its value, debug-formatted, for writing to inspect.
pub fn for_inspect(&self) -> (&'static str, String) {
match self {
$(
$(#[cfg($test)])?
$name::$variant(info) => (stringify!($variant), format!("{:?}", info)),
)*
}
}
}
};
}
generate_inspect_with_info! {
/// Enumeration over the possible info types available in the service.
#[derive(PartialEq, Debug, Clone)]
pub enum SettingInfo {
/// This value is reserved for testing purposes.
#[cfg(test)]
Unknown(UnknownInfo),
Accessibility(AccessibilityInfo),
Audio(AudioInfo),
Brightness(DisplayInfo),
Device(DeviceInfo),
FactoryReset(FactoryResetInfo),
Light(LightInfo),
LightSensor(LightData),
DoNotDisturb(DoNotDisturbInfo),
Input(InputInfo),
Intl(IntlInfo),
NightMode(NightModeInfo),
Privacy(PrivacyInfo),
Setup(SetupInfo),
}
}
pub trait HasSettingType {
const SETTING_TYPE: SettingType;
}
macro_rules! conversion_impls {
($($(#[cfg($test:meta)])? $variant:ident($info_ty:ty) => $ty_variant:ident ),+ $(,)?) => {
$(
$(#[cfg($test)])?
impl HasSettingType for $info_ty {
const SETTING_TYPE: SettingType = SettingType::$ty_variant;
}
$(#[cfg($test)])?
impl TryFrom<SettingInfo> for $info_ty {
type Error = ();
fn try_from(setting_info: SettingInfo) -> Result<Self, ()> {
match setting_info {
SettingInfo::$variant(info) => Ok(info),
_ => Err(()),
}
}
}
)+
}
}
conversion_impls! {
#[cfg(test)] Unknown(UnknownInfo) => Unknown,
Accessibility(AccessibilityInfo) => Accessibility,
Audio(AudioInfo) => Audio,
Brightness(DisplayInfo) => Display,
Device(DeviceInfo) => Device,
FactoryReset(FactoryResetInfo) => FactoryReset,
Light(LightInfo) => Light,
LightSensor(LightData) => LightSensor,
DoNotDisturb(DoNotDisturbInfo) => DoNotDisturb,
Input(InputInfo) => Input,
Intl(IntlInfo) => Intl,
NightMode(NightModeInfo) => NightMode,
Privacy(PrivacyInfo) => Privacy,
Setup(SetupInfo) => Setup,
}
impl Into<SettingType> for &SettingInfo {
fn into(self) -> SettingType {
match self {
#[cfg(test)]
SettingInfo::Unknown(_) => SettingType::Unknown,
SettingInfo::Accessibility(_) => SettingType::Accessibility,
SettingInfo::Audio(_) => SettingType::Audio,
SettingInfo::Brightness(_) => SettingType::Display,
SettingInfo::Device(_) => SettingType::Device,
SettingInfo::DoNotDisturb(_) => SettingType::DoNotDisturb,
SettingInfo::FactoryReset(_) => SettingType::FactoryReset,
SettingInfo::Input(_) => SettingType::Input,
SettingInfo::Intl(_) => SettingType::Intl,
SettingInfo::Light(_) => SettingType::Light,
SettingInfo::LightSensor(_) => SettingType::LightSensor,
SettingInfo::NightMode(_) => SettingType::NightMode,
SettingInfo::Privacy(_) => SettingType::Privacy,
SettingInfo::Setup(_) => SettingType::Setup,
}
}
}
/// This struct is reserved for testing purposes. Some tests need to verify data changes, bool value
/// can be used for this purpose.
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
#[cfg(test)]
pub struct UnknownInfo(pub bool);
/// The `Merge` trait allows merging two structs.
pub trait Merge<Other = Self> {
/// Returns a copy of the original struct where the values of all fields set in `other`
/// replace the matching fields in the copy of `self`.
fn merge(&self, other: Other) -> Self;
}
/// Returns default setting types. These types should be product-agnostic,
/// capable of operating with platform level support.
pub fn get_default_setting_types() -> HashSet<SettingType> {
return array::IntoIter::new([
SettingType::Accessibility,
SettingType::Device,
SettingType::Intl,
SettingType::Power,
SettingType::Privacy,
SettingType::Setup,
])
.collect();
}
/// Returns all known setting types. New additions to SettingType should also
/// be inserted here.
pub fn get_all_setting_types() -> HashSet<SettingType> {
return array::IntoIter::new([
SettingType::Accessibility,
SettingType::Audio,
SettingType::Device,
SettingType::Display,
SettingType::DoNotDisturb,
SettingType::FactoryReset,
SettingType::Input,
SettingType::Intl,
SettingType::Light,
SettingType::LightSensor,
SettingType::NightMode,
SettingType::Power,
SettingType::Privacy,
SettingType::Setup,
])
.collect();
}
#[cfg(test)]
mod testing {
use super::{SettingInfo, UnknownInfo};
use crate::handler::device_storage::DeviceStorageCompatible;
impl DeviceStorageCompatible for UnknownInfo {
const KEY: &'static str = "unknown_info";
fn default_value() -> Self {
Self(false)
}
}
impl Into<SettingInfo> for UnknownInfo {
fn into(self) -> SettingInfo {
SettingInfo::Unknown(self)
}
}
}