-
-
Save rust-play/6d27a91c1c8e402a181ddc3d47bca747 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(prelude_import)] | |
#[prelude_import] | |
use std::prelude::rust_2018::*; | |
#[macro_use] | |
extern crate std; | |
// Copyright 2019 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 anyhow::{Context as _, Error}; | |
use fuchsia_component::server::ServiceObjLocal; | |
use futures::lock::Mutex; | |
use futures::prelude::*; | |
use std::pin::Pin; | |
use std::sync::Arc; | |
// Include Brightness Control FIDL bindings | |
use backlight::Backlight; | |
use control::{Control, ControlTrait, WatcherAdjustmentResponder, | |
WatcherAutoResponder, WatcherCurrentResponder}; | |
use fidl_fuchsia_ui_brightness::ControlRequestStream; | |
use fuchsia_async::{self as fasync}; | |
use fuchsia_component::server::ServiceFs; | |
use fuchsia_syslog::{self, fx_log_err, fx_log_info}; | |
use futures::channel::mpsc::UnboundedReceiver; | |
use futures::future::{AbortHandle, Abortable}; | |
use sender_channel::SenderChannel; | |
use sensor::Sensor; | |
use watch_handler::WatchHandler; | |
mod backlight { | |
// TODO(kpt) Writes FIDL client unit test for this. | |
use anyhow::{Context as _, Error}; | |
use async_trait::async_trait; | |
use fidl_fuchsia_hardware_backlight::{DeviceMarker as BacklightMarker, | |
DeviceProxy as BacklightProxy, State | |
as BacklightCommand}; | |
use fuchsia_syslog::fx_log_info; | |
const MINIMUM_BRIGHTNESS: f64 = 0.0004; | |
fn open_backlight() -> Result<BacklightProxy, Error> { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Opening backlight"], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
}; | |
; | |
let (proxy, server) = | |
fidl::endpoints::create_proxy::<BacklightMarker>().context("Failed to create backlight proxy")?; | |
fdio::service_connect("/dev/class/backlight/000", | |
server.into_channel()).context("Failed to connect built-in service")?; | |
Ok(proxy) | |
} | |
pub struct Backlight { | |
proxy: BacklightProxy, | |
} | |
impl Backlight { | |
pub async fn new() -> Result<Backlight, Error> { | |
let proxy = open_backlight()?; | |
Ok(Backlight{proxy,}) | |
} | |
pub async fn get_max_absolute_brightness(&self) | |
-> Result<f64, Error> { | |
let connection_result = | |
self.proxy.get_max_absolute_brightness().await; | |
let connection = | |
connection_result.map_err(|e| | |
::anyhow::private::new_adhoc({ | |
let res = | |
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&["Didn\'t connect correctly, got err "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})); | |
res | |
}))?; | |
let max_brightness: f64 = | |
connection.map_err(|e| | |
{ | |
::anyhow::private::new_adhoc({ | |
let res = | |
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&["Didn\'t get the max_brightness back, got err "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})); | |
res | |
}) | |
})?; | |
Ok(max_brightness) | |
} | |
async fn get(&self) -> Result<f64, Error> { | |
let result = self.proxy.get_state_normalized().await?; | |
let backlight_info = | |
result.map_err(|e| | |
::anyhow::private::new_adhoc({ | |
let res = | |
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&["Failed to get state: "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Debug::fmt)], | |
})); | |
res | |
}))?; | |
if !(backlight_info.brightness >= 0.0) { | |
::core::panicking::panic("assertion failed: backlight_info.brightness >= 0.0") | |
}; | |
if !(backlight_info.brightness <= 1.0) { | |
::core::panicking::panic("assertion failed: backlight_info.brightness <= 1.0") | |
}; | |
Ok(if backlight_info.backlight_on { | |
backlight_info.brightness | |
} else { 0.0 }) | |
} | |
fn set(&mut self, value: f64) -> Result<(), Error> { | |
let regulated_value = | |
num_traits::clamp(value, MINIMUM_BRIGHTNESS, 1.0); | |
let _result = | |
self.proxy.set_state_normalized(&mut BacklightCommand{backlight_on: | |
value | |
> | |
0.0, | |
brightness: | |
regulated_value,}); | |
Ok(()) | |
} | |
} | |
pub trait BacklightControl: Send { | |
#[must_use] | |
fn get_brightness<'life0, 'async_trait>(&'life0 self) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = | |
Result<f64, | |
Error>> + | |
::core::marker::Send + 'async_trait>> | |
where | |
'life0: 'async_trait, | |
Self: 'async_trait; | |
fn set_brightness(&mut self, value: f64) | |
-> Result<(), Error>; | |
#[must_use] | |
fn get_max_absolute_brightness<'life0, 'async_trait>(&'life0 self) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = | |
Result<f64, | |
Error>> + | |
::core::marker::Send + 'async_trait>> | |
where | |
'life0: 'async_trait, | |
Self: 'async_trait; | |
} | |
impl BacklightControl for Backlight { | |
fn get_brightness<'life0, 'async_trait>(&'life0 self) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = | |
Result<f64, | |
Error>> + | |
::core::marker::Send + 'async_trait>> where | |
'life0: 'async_trait, Self: 'async_trait { | |
#[allow(unused_parens, clippy :: missing_docs_in_private_items, | |
clippy :: needless_lifetimes, clippy :: ptr_arg, clippy :: | |
trivially_copy_pass_by_ref, clippy :: | |
type_repetition_in_bounds, clippy :: | |
used_underscore_binding,)] | |
async fn __get_brightness(_self: &Backlight) | |
-> Result<f64, Error> { | |
_self.get().await | |
} | |
Box::pin(__get_brightness::<>(self)) | |
} | |
fn set_brightness(&mut self, value: f64) -> Result<(), Error> { | |
self.set(value) | |
} | |
fn get_max_absolute_brightness<'life0, 'async_trait>(&'life0 self) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = | |
Result<f64, | |
Error>> + | |
::core::marker::Send + 'async_trait>> where | |
'life0: 'async_trait, Self: 'async_trait { | |
#[allow(unused_parens, clippy :: missing_docs_in_private_items, | |
clippy :: needless_lifetimes, clippy :: ptr_arg, clippy :: | |
trivially_copy_pass_by_ref, clippy :: | |
type_repetition_in_bounds, clippy :: | |
used_underscore_binding,)] | |
async fn __get_max_absolute_brightness(_self: &Backlight) | |
-> Result<f64, Error> { | |
_self.get_max_absolute_brightness().await | |
} | |
Box::pin(__get_max_absolute_brightness::<>(self)) | |
} | |
} | |
} | |
mod control { | |
use crate::backlight::BacklightControl; | |
use crate::sender_channel::SenderChannel; | |
use crate::sensor::SensorControl; | |
use async_trait::async_trait; | |
use std::cmp; | |
use std::sync::Arc; | |
use anyhow::{format_err, Error}; | |
use fidl_fuchsia_ui_brightness::{ControlRequest as | |
BrightnessControlRequest, | |
ControlWatchAutoBrightnessAdjustmentResponder, | |
ControlWatchAutoBrightnessResponder, | |
ControlWatchCurrentBrightnessResponder}; | |
use fuchsia_async::{self as fasync, DurationExt}; | |
use fuchsia_syslog::{self, fx_log_err, fx_log_info}; | |
use fuchsia_zircon::sys::ZX_ERR_NOT_SUPPORTED; | |
use fuchsia_zircon::{Duration, DurationNum}; | |
use futures::channel::mpsc::UnboundedSender; | |
use futures::future::{AbortHandle, Abortable}; | |
use futures::lock::Mutex; | |
use futures::prelude::*; | |
use lazy_static::lazy_static; | |
use serde::{Deserialize, Serialize}; | |
use serde_json; | |
use splines::{Interpolation, Key, Spline}; | |
use std::{fs, io}; | |
use watch_handler::{Sender, WatchHandler}; | |
const SLOW_SCAN_TIMEOUT_MS: i64 = 2000; | |
const QUICK_SCAN_TIMEOUT_MS: i64 = 100; | |
const LARGE_CHANGE_THRESHOLD_NITS: i32 = 0.016 as i32; | |
const AUTO_MINIMUM_BRIGHTNESS: f32 = 0.004; | |
const BRIGHTNESS_USER_MULTIPLIER_CENTER: f32 = 1.0; | |
const BRIGHTNESS_USER_MULTIPLIER_MAX: f32 = 8.0; | |
const BRIGHTNESS_USER_MULTIPLIER_MIN: f32 = 0.25; | |
const BRIGHTNESS_TABLE_FILE_PATH: &str = "/data/brightness_table"; | |
const BRIGHTNESS_MINIMUM_CHANGE: f32 = 0.00001; | |
const BRIGHTNESS_STEP_SIZE: f32 = 0.001; | |
const MAX_BRIGHTNESS_STEP_TIME_MS: i64 = 100; | |
const BRIGHTNESS_CHANGE_DURATION_MS: i64 = 2000; | |
struct BrightnessPoint { | |
ambient_lux: f32, | |
display_nits: f32, | |
} | |
#[doc(hidden)] | |
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] | |
const _: () = | |
{ | |
#[allow(rust_2018_idioms, clippy :: useless_attribute)] | |
extern crate serde as _serde; | |
#[allow(unused_macros)] | |
macro_rules! try { | |
($ __expr : expr) => | |
{ | |
match $ __expr | |
{ | |
_serde :: export :: Ok(__val) => __val, _serde :: | |
export :: Err(__err) => | |
{ return _serde :: export :: Err(__err) ; } | |
} | |
} | |
} | |
#[automatically_derived] | |
impl _serde::Serialize for BrightnessPoint { | |
fn serialize<__S>(&self, __serializer: __S) | |
-> _serde::export::Result<__S::Ok, __S::Error> where | |
__S: _serde::Serializer { | |
let mut __serde_state = | |
match _serde::Serializer::serialize_struct(__serializer, | |
"BrightnessPoint", | |
false as | |
usize + | |
1 + 1) | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
}; | |
match _serde::ser::SerializeStruct::serialize_field(&mut __serde_state, | |
"ambient_lux", | |
&self.ambient_lux) | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
}; | |
match _serde::ser::SerializeStruct::serialize_field(&mut __serde_state, | |
"display_nits", | |
&self.display_nits) | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
}; | |
_serde::ser::SerializeStruct::end(__serde_state) | |
} | |
} | |
}; | |
#[doc(hidden)] | |
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] | |
const _: () = | |
{ | |
#[allow(rust_2018_idioms, clippy :: useless_attribute)] | |
extern crate serde as _serde; | |
#[allow(unused_macros)] | |
macro_rules! try { | |
($ __expr : expr) => | |
{ | |
match $ __expr | |
{ | |
_serde :: export :: Ok(__val) => __val, _serde :: | |
export :: Err(__err) => | |
{ return _serde :: export :: Err(__err) ; } | |
} | |
} | |
} | |
#[automatically_derived] | |
impl <'de> _serde::Deserialize<'de> for BrightnessPoint { | |
fn deserialize<__D>(__deserializer: __D) | |
-> _serde::export::Result<Self, __D::Error> where | |
__D: _serde::Deserializer<'de> { | |
#[allow(non_camel_case_types)] | |
enum __Field { __field0, __field1, __ignore, } | |
struct __FieldVisitor; | |
impl <'de> _serde::de::Visitor<'de> for __FieldVisitor { | |
type Value = __Field; | |
fn expecting(&self, | |
__formatter: | |
&mut _serde::export::Formatter) | |
-> _serde::export::fmt::Result { | |
_serde::export::Formatter::write_str(__formatter, | |
"field identifier") | |
} | |
fn visit_u64<__E>(self, __value: u64) | |
-> _serde::export::Result<Self::Value, __E> where | |
__E: _serde::de::Error { | |
match __value { | |
0u64 => _serde::export::Ok(__Field::__field0), | |
1u64 => _serde::export::Ok(__Field::__field1), | |
_ => | |
_serde::export::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value), | |
&"field index 0 <= i < 2")), | |
} | |
} | |
fn visit_str<__E>(self, __value: &str) | |
-> _serde::export::Result<Self::Value, __E> where | |
__E: _serde::de::Error { | |
match __value { | |
"ambient_lux" => | |
_serde::export::Ok(__Field::__field0), | |
"display_nits" => | |
_serde::export::Ok(__Field::__field1), | |
_ => { _serde::export::Ok(__Field::__ignore) } | |
} | |
} | |
fn visit_bytes<__E>(self, __value: &[u8]) | |
-> _serde::export::Result<Self::Value, __E> where | |
__E: _serde::de::Error { | |
match __value { | |
b"ambient_lux" => | |
_serde::export::Ok(__Field::__field0), | |
b"display_nits" => | |
_serde::export::Ok(__Field::__field1), | |
_ => { _serde::export::Ok(__Field::__ignore) } | |
} | |
} | |
} | |
impl <'de> _serde::Deserialize<'de> for __Field { | |
#[inline] | |
fn deserialize<__D>(__deserializer: __D) | |
-> _serde::export::Result<Self, __D::Error> where | |
__D: _serde::Deserializer<'de> { | |
_serde::Deserializer::deserialize_identifier(__deserializer, | |
__FieldVisitor) | |
} | |
} | |
struct __Visitor<'de> { | |
marker: _serde::export::PhantomData<BrightnessPoint>, | |
lifetime: _serde::export::PhantomData<&'de ()>, | |
} | |
impl <'de> _serde::de::Visitor<'de> for __Visitor<'de> { | |
type Value = BrightnessPoint; | |
fn expecting(&self, | |
__formatter: | |
&mut _serde::export::Formatter) | |
-> _serde::export::fmt::Result { | |
_serde::export::Formatter::write_str(__formatter, | |
"struct BrightnessPoint") | |
} | |
#[inline] | |
fn visit_seq<__A>(self, mut __seq: __A) | |
-> _serde::export::Result<Self::Value, __A::Error> | |
where __A: _serde::de::SeqAccess<'de> { | |
let __field0 = | |
match match _serde::de::SeqAccess::next_element::<f32>(&mut __seq) | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
} { | |
_serde::export::Some(__value) => __value, | |
_serde::export::None => { | |
return _serde::export::Err(_serde::de::Error::invalid_length(0usize, | |
&"struct BrightnessPoint with 2 elements")); | |
} | |
}; | |
let __field1 = | |
match match _serde::de::SeqAccess::next_element::<f32>(&mut __seq) | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
} { | |
_serde::export::Some(__value) => __value, | |
_serde::export::None => { | |
return _serde::export::Err(_serde::de::Error::invalid_length(1usize, | |
&"struct BrightnessPoint with 2 elements")); | |
} | |
}; | |
_serde::export::Ok(BrightnessPoint{ambient_lux: | |
__field0, | |
display_nits: | |
__field1,}) | |
} | |
#[inline] | |
fn visit_map<__A>(self, mut __map: __A) | |
-> _serde::export::Result<Self::Value, __A::Error> | |
where __A: _serde::de::MapAccess<'de> { | |
let mut __field0: _serde::export::Option<f32> = | |
_serde::export::None; | |
let mut __field1: _serde::export::Option<f32> = | |
_serde::export::None; | |
while let _serde::export::Some(__key) = | |
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
} { | |
match __key { | |
__Field::__field0 => { | |
if _serde::export::Option::is_some(&__field0) | |
{ | |
return _serde::export::Err(<__A::Error | |
as | |
_serde::de::Error>::duplicate_field("ambient_lux")); | |
} | |
__field0 = | |
_serde::export::Some(match _serde::de::MapAccess::next_value::<f32>(&mut __map) | |
{ | |
_serde::export::Ok(__val) | |
=> __val, | |
_serde::export::Err(__err) | |
=> { | |
return _serde::export::Err(__err); | |
} | |
}); | |
} | |
__Field::__field1 => { | |
if _serde::export::Option::is_some(&__field1) | |
{ | |
return _serde::export::Err(<__A::Error | |
as | |
_serde::de::Error>::duplicate_field("display_nits")); | |
} | |
__field1 = | |
_serde::export::Some(match _serde::de::MapAccess::next_value::<f32>(&mut __map) | |
{ | |
_serde::export::Ok(__val) | |
=> __val, | |
_serde::export::Err(__err) | |
=> { | |
return _serde::export::Err(__err); | |
} | |
}); | |
} | |
_ => { | |
let _ = | |
match _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map) | |
{ | |
_serde::export::Ok(__val) => | |
__val, | |
_serde::export::Err(__err) => | |
{ | |
return _serde::export::Err(__err); | |
} | |
}; | |
} | |
} | |
} | |
let __field0 = | |
match __field0 { | |
_serde::export::Some(__field0) => | |
__field0, | |
_serde::export::None => | |
match _serde::private::de::missing_field("ambient_lux") | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
}, | |
}; | |
let __field1 = | |
match __field1 { | |
_serde::export::Some(__field1) => | |
__field1, | |
_serde::export::None => | |
match _serde::private::de::missing_field("display_nits") | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
}, | |
}; | |
_serde::export::Ok(BrightnessPoint{ambient_lux: | |
__field0, | |
display_nits: | |
__field1,}) | |
} | |
} | |
const FIELDS: &'static [&'static str] = | |
&["ambient_lux", "display_nits"]; | |
_serde::Deserializer::deserialize_struct(__deserializer, | |
"BrightnessPoint", | |
FIELDS, | |
__Visitor{marker: | |
_serde::export::PhantomData::<BrightnessPoint>, | |
lifetime: | |
_serde::export::PhantomData,}) | |
} | |
} | |
}; | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::clone::Clone for BrightnessPoint { | |
#[inline] | |
fn clone(&self) -> BrightnessPoint { | |
match *self { | |
BrightnessPoint { | |
ambient_lux: ref __self_0_0, display_nits: ref __self_0_1 } => | |
BrightnessPoint{ambient_lux: | |
::core::clone::Clone::clone(&(*__self_0_0)), | |
display_nits: | |
::core::clone::Clone::clone(&(*__self_0_1)),}, | |
} | |
} | |
} | |
struct BrightnessTable { | |
points: Vec<BrightnessPoint>, | |
} | |
#[doc(hidden)] | |
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] | |
const _: () = | |
{ | |
#[allow(rust_2018_idioms, clippy :: useless_attribute)] | |
extern crate serde as _serde; | |
#[allow(unused_macros)] | |
macro_rules! try { | |
($ __expr : expr) => | |
{ | |
match $ __expr | |
{ | |
_serde :: export :: Ok(__val) => __val, _serde :: | |
export :: Err(__err) => | |
{ return _serde :: export :: Err(__err) ; } | |
} | |
} | |
} | |
#[automatically_derived] | |
impl _serde::Serialize for BrightnessTable { | |
fn serialize<__S>(&self, __serializer: __S) | |
-> _serde::export::Result<__S::Ok, __S::Error> where | |
__S: _serde::Serializer { | |
let mut __serde_state = | |
match _serde::Serializer::serialize_struct(__serializer, | |
"BrightnessTable", | |
false as | |
usize + | |
1) { | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
}; | |
match _serde::ser::SerializeStruct::serialize_field(&mut __serde_state, | |
"points", | |
&self.points) | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
}; | |
_serde::ser::SerializeStruct::end(__serde_state) | |
} | |
} | |
}; | |
#[doc(hidden)] | |
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] | |
const _: () = | |
{ | |
#[allow(rust_2018_idioms, clippy :: useless_attribute)] | |
extern crate serde as _serde; | |
#[allow(unused_macros)] | |
macro_rules! try { | |
($ __expr : expr) => | |
{ | |
match $ __expr | |
{ | |
_serde :: export :: Ok(__val) => __val, _serde :: | |
export :: Err(__err) => | |
{ return _serde :: export :: Err(__err) ; } | |
} | |
} | |
} | |
#[automatically_derived] | |
impl <'de> _serde::Deserialize<'de> for BrightnessTable { | |
fn deserialize<__D>(__deserializer: __D) | |
-> _serde::export::Result<Self, __D::Error> where | |
__D: _serde::Deserializer<'de> { | |
#[allow(non_camel_case_types)] | |
enum __Field { __field0, __ignore, } | |
struct __FieldVisitor; | |
impl <'de> _serde::de::Visitor<'de> for __FieldVisitor { | |
type Value = __Field; | |
fn expecting(&self, | |
__formatter: | |
&mut _serde::export::Formatter) | |
-> _serde::export::fmt::Result { | |
_serde::export::Formatter::write_str(__formatter, | |
"field identifier") | |
} | |
fn visit_u64<__E>(self, __value: u64) | |
-> _serde::export::Result<Self::Value, __E> where | |
__E: _serde::de::Error { | |
match __value { | |
0u64 => _serde::export::Ok(__Field::__field0), | |
_ => | |
_serde::export::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value), | |
&"field index 0 <= i < 1")), | |
} | |
} | |
fn visit_str<__E>(self, __value: &str) | |
-> _serde::export::Result<Self::Value, __E> where | |
__E: _serde::de::Error { | |
match __value { | |
"points" => | |
_serde::export::Ok(__Field::__field0), | |
_ => { _serde::export::Ok(__Field::__ignore) } | |
} | |
} | |
fn visit_bytes<__E>(self, __value: &[u8]) | |
-> _serde::export::Result<Self::Value, __E> where | |
__E: _serde::de::Error { | |
match __value { | |
b"points" => | |
_serde::export::Ok(__Field::__field0), | |
_ => { _serde::export::Ok(__Field::__ignore) } | |
} | |
} | |
} | |
impl <'de> _serde::Deserialize<'de> for __Field { | |
#[inline] | |
fn deserialize<__D>(__deserializer: __D) | |
-> _serde::export::Result<Self, __D::Error> where | |
__D: _serde::Deserializer<'de> { | |
_serde::Deserializer::deserialize_identifier(__deserializer, | |
__FieldVisitor) | |
} | |
} | |
struct __Visitor<'de> { | |
marker: _serde::export::PhantomData<BrightnessTable>, | |
lifetime: _serde::export::PhantomData<&'de ()>, | |
} | |
impl <'de> _serde::de::Visitor<'de> for __Visitor<'de> { | |
type Value = BrightnessTable; | |
fn expecting(&self, | |
__formatter: | |
&mut _serde::export::Formatter) | |
-> _serde::export::fmt::Result { | |
_serde::export::Formatter::write_str(__formatter, | |
"struct BrightnessTable") | |
} | |
#[inline] | |
fn visit_seq<__A>(self, mut __seq: __A) | |
-> _serde::export::Result<Self::Value, __A::Error> | |
where __A: _serde::de::SeqAccess<'de> { | |
let __field0 = | |
match match _serde::de::SeqAccess::next_element::<Vec<BrightnessPoint>>(&mut __seq) | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
} { | |
_serde::export::Some(__value) => __value, | |
_serde::export::None => { | |
return _serde::export::Err(_serde::de::Error::invalid_length(0usize, | |
&"struct BrightnessTable with 1 element")); | |
} | |
}; | |
_serde::export::Ok(BrightnessTable{points: | |
__field0,}) | |
} | |
#[inline] | |
fn visit_map<__A>(self, mut __map: __A) | |
-> _serde::export::Result<Self::Value, __A::Error> | |
where __A: _serde::de::MapAccess<'de> { | |
let mut __field0: | |
_serde::export::Option<Vec<BrightnessPoint>> = | |
_serde::export::None; | |
while let _serde::export::Some(__key) = | |
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
} { | |
match __key { | |
__Field::__field0 => { | |
if _serde::export::Option::is_some(&__field0) | |
{ | |
return _serde::export::Err(<__A::Error | |
as | |
_serde::de::Error>::duplicate_field("points")); | |
} | |
__field0 = | |
_serde::export::Some(match _serde::de::MapAccess::next_value::<Vec<BrightnessPoint>>(&mut __map) | |
{ | |
_serde::export::Ok(__val) | |
=> __val, | |
_serde::export::Err(__err) | |
=> { | |
return _serde::export::Err(__err); | |
} | |
}); | |
} | |
_ => { | |
let _ = | |
match _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map) | |
{ | |
_serde::export::Ok(__val) => | |
__val, | |
_serde::export::Err(__err) => | |
{ | |
return _serde::export::Err(__err); | |
} | |
}; | |
} | |
} | |
} | |
let __field0 = | |
match __field0 { | |
_serde::export::Some(__field0) => | |
__field0, | |
_serde::export::None => | |
match _serde::private::de::missing_field("points") | |
{ | |
_serde::export::Ok(__val) => __val, | |
_serde::export::Err(__err) => { | |
return _serde::export::Err(__err); | |
} | |
}, | |
}; | |
_serde::export::Ok(BrightnessTable{points: | |
__field0,}) | |
} | |
} | |
const FIELDS: &'static [&'static str] = &["points"]; | |
_serde::Deserializer::deserialize_struct(__deserializer, | |
"BrightnessTable", | |
FIELDS, | |
__Visitor{marker: | |
_serde::export::PhantomData::<BrightnessTable>, | |
lifetime: | |
_serde::export::PhantomData,}) | |
} | |
} | |
}; | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::clone::Clone for BrightnessTable { | |
#[inline] | |
fn clone(&self) -> BrightnessTable { | |
match *self { | |
BrightnessTable { points: ref __self_0_0 } => | |
BrightnessTable{points: | |
::core::clone::Clone::clone(&(*__self_0_0)),}, | |
} | |
} | |
} | |
impl From<fidl_fuchsia_ui_brightness::BrightnessPoint> for BrightnessPoint | |
{ | |
fn from(brightness_point: fidl_fuchsia_ui_brightness::BrightnessPoint) | |
-> Self { | |
return BrightnessPoint{ambient_lux: brightness_point.ambient_lux, | |
display_nits: | |
brightness_point.display_nits,}; | |
} | |
} | |
impl From<fidl_fuchsia_ui_brightness::BrightnessTable> for BrightnessTable | |
{ | |
fn from(brightness_table: fidl_fuchsia_ui_brightness::BrightnessTable) | |
-> Self { | |
let fidl_fuchsia_ui_brightness::BrightnessTable { points } = | |
brightness_table; | |
return BrightnessTable{points: | |
points.into_iter().map(|p| | |
p.into()).collect(),}; | |
} | |
} | |
#[allow(missing_copy_implementations)] | |
#[allow(non_camel_case_types)] | |
#[allow(dead_code)] | |
struct BRIGHTNESS_TABLE { | |
__private_field: (), | |
} | |
#[doc(hidden)] | |
static BRIGHTNESS_TABLE: BRIGHTNESS_TABLE = | |
BRIGHTNESS_TABLE{__private_field: (),}; | |
impl ::lazy_static::__Deref for BRIGHTNESS_TABLE { | |
type Target = Arc<Mutex<BrightnessTable>>; | |
fn deref(&self) -> &Arc<Mutex<BrightnessTable>> { | |
#[inline(always)] | |
fn __static_ref_initialize() -> Arc<Mutex<BrightnessTable>> { | |
{ | |
let mut lux_to_nits = Vec::new(); | |
lux_to_nits.push(BrightnessPoint{ambient_lux: 0., | |
display_nits: 0.,}); | |
lux_to_nits.push(BrightnessPoint{ambient_lux: 10., | |
display_nits: 3.33,}); | |
lux_to_nits.push(BrightnessPoint{ambient_lux: 30., | |
display_nits: 8.7,}); | |
lux_to_nits.push(BrightnessPoint{ambient_lux: 60., | |
display_nits: 18.27,}); | |
lux_to_nits.push(BrightnessPoint{ambient_lux: 100., | |
display_nits: 32.785,}); | |
lux_to_nits.push(BrightnessPoint{ambient_lux: 150., | |
display_nits: 36.82,}); | |
lux_to_nits.push(BrightnessPoint{ambient_lux: 210., | |
display_nits: 75.0,}); | |
lux_to_nits.push(BrightnessPoint{ambient_lux: 250., | |
display_nits: 124.16,}); | |
lux_to_nits.push(BrightnessPoint{ambient_lux: 300., | |
display_nits: 162.96,}); | |
lux_to_nits.push(BrightnessPoint{ambient_lux: 340., | |
display_nits: 300.,}); | |
Arc::new(Mutex::new(BrightnessTable{points: | |
lux_to_nits,})) | |
} | |
} | |
#[inline(always)] | |
fn __stability() -> &'static Arc<Mutex<BrightnessTable>> { | |
static LAZY: | |
::lazy_static::lazy::Lazy<Arc<Mutex<BrightnessTable>>> = | |
::lazy_static::lazy::Lazy::INIT; | |
LAZY.get(__static_ref_initialize) | |
} | |
__stability() | |
} | |
} | |
impl ::lazy_static::LazyStatic for BRIGHTNESS_TABLE { | |
fn initialize(lazy: &Self) { let _ = &**lazy; } | |
} | |
#[allow(missing_copy_implementations)] | |
#[allow(non_camel_case_types)] | |
#[allow(dead_code)] | |
struct AUTO_BRIGHTNESS_ADJUSTMENT { | |
__private_field: (), | |
} | |
#[doc(hidden)] | |
static AUTO_BRIGHTNESS_ADJUSTMENT: AUTO_BRIGHTNESS_ADJUSTMENT = | |
AUTO_BRIGHTNESS_ADJUSTMENT{__private_field: (),}; | |
impl ::lazy_static::__Deref for AUTO_BRIGHTNESS_ADJUSTMENT { | |
type Target = Arc<Mutex<f32>>; | |
fn deref(&self) -> &Arc<Mutex<f32>> { | |
#[inline(always)] | |
fn __static_ref_initialize() -> Arc<Mutex<f32>> { | |
Arc::new(Mutex::new(1.0)) | |
} | |
#[inline(always)] | |
fn __stability() -> &'static Arc<Mutex<f32>> { | |
static LAZY: ::lazy_static::lazy::Lazy<Arc<Mutex<f32>>> = | |
::lazy_static::lazy::Lazy::INIT; | |
LAZY.get(__static_ref_initialize) | |
} | |
__stability() | |
} | |
} | |
impl ::lazy_static::LazyStatic for AUTO_BRIGHTNESS_ADJUSTMENT { | |
fn initialize(lazy: &Self) { let _ = &**lazy; } | |
} | |
#[allow(missing_copy_implementations)] | |
#[allow(non_camel_case_types)] | |
#[allow(dead_code)] | |
struct GET_BRIGHTNESS_FAILED_FIRST { | |
__private_field: (), | |
} | |
#[doc(hidden)] | |
static GET_BRIGHTNESS_FAILED_FIRST: GET_BRIGHTNESS_FAILED_FIRST = | |
GET_BRIGHTNESS_FAILED_FIRST{__private_field: (),}; | |
impl ::lazy_static::__Deref for GET_BRIGHTNESS_FAILED_FIRST { | |
type Target = Arc<Mutex<bool>>; | |
fn deref(&self) -> &Arc<Mutex<bool>> { | |
#[inline(always)] | |
fn __static_ref_initialize() -> Arc<Mutex<bool>> { | |
Arc::new(Mutex::new(true)) | |
} | |
#[inline(always)] | |
fn __stability() -> &'static Arc<Mutex<bool>> { | |
static LAZY: ::lazy_static::lazy::Lazy<Arc<Mutex<bool>>> = | |
::lazy_static::lazy::Lazy::INIT; | |
LAZY.get(__static_ref_initialize) | |
} | |
__stability() | |
} | |
} | |
impl ::lazy_static::LazyStatic for GET_BRIGHTNESS_FAILED_FIRST { | |
fn initialize(lazy: &Self) { let _ = &**lazy; } | |
} | |
#[allow(missing_copy_implementations)] | |
#[allow(non_camel_case_types)] | |
#[allow(dead_code)] | |
struct LAST_SET_BRIGHTNESS { | |
__private_field: (), | |
} | |
#[doc(hidden)] | |
static LAST_SET_BRIGHTNESS: LAST_SET_BRIGHTNESS = | |
LAST_SET_BRIGHTNESS{__private_field: (),}; | |
impl ::lazy_static::__Deref for LAST_SET_BRIGHTNESS { | |
type Target = Arc<Mutex<f32>>; | |
fn deref(&self) -> &Arc<Mutex<f32>> { | |
#[inline(always)] | |
fn __static_ref_initialize() -> Arc<Mutex<f32>> { | |
Arc::new(Mutex::new(1.0)) | |
} | |
#[inline(always)] | |
fn __stability() -> &'static Arc<Mutex<f32>> { | |
static LAZY: ::lazy_static::lazy::Lazy<Arc<Mutex<f32>>> = | |
::lazy_static::lazy::Lazy::INIT; | |
LAZY.get(__static_ref_initialize) | |
} | |
__stability() | |
} | |
} | |
impl ::lazy_static::LazyStatic for LAST_SET_BRIGHTNESS { | |
fn initialize(lazy: &Self) { let _ = &**lazy; } | |
} | |
#[allow(missing_copy_implementations)] | |
#[allow(non_camel_case_types)] | |
#[allow(dead_code)] | |
struct BRIGHTNESS_CHANGE_DURATION { | |
__private_field: (), | |
} | |
#[doc(hidden)] | |
static BRIGHTNESS_CHANGE_DURATION: BRIGHTNESS_CHANGE_DURATION = | |
BRIGHTNESS_CHANGE_DURATION{__private_field: (),}; | |
impl ::lazy_static::__Deref for BRIGHTNESS_CHANGE_DURATION { | |
type Target = Arc<Mutex<Duration>>; | |
fn deref(&self) -> &Arc<Mutex<Duration>> { | |
#[inline(always)] | |
fn __static_ref_initialize() -> Arc<Mutex<Duration>> { | |
Arc::new(Mutex::new(BRIGHTNESS_CHANGE_DURATION_MS.millis())) | |
} | |
#[inline(always)] | |
fn __stability() -> &'static Arc<Mutex<Duration>> { | |
static LAZY: ::lazy_static::lazy::Lazy<Arc<Mutex<Duration>>> = | |
::lazy_static::lazy::Lazy::INIT; | |
LAZY.get(__static_ref_initialize) | |
} | |
__stability() | |
} | |
} | |
impl ::lazy_static::LazyStatic for BRIGHTNESS_CHANGE_DURATION { | |
fn initialize(lazy: &Self) { let _ = &**lazy; } | |
} | |
pub struct WatcherCurrentResponder { | |
watcher_current_responder: ControlWatchCurrentBrightnessResponder, | |
} | |
impl Sender<f32> for WatcherCurrentResponder { | |
fn send_response(self, data: f32) { | |
if let Err(e) = self.watcher_current_responder.send(data) { | |
{ | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&114u32, | |
&::core::fmt::Arguments::new_v1(&["Failed to reply to WatchCurrentBrightness: "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
}; | |
; | |
} | |
} | |
} | |
pub struct WatcherAutoResponder { | |
watcher_auto_responder: ControlWatchAutoBrightnessResponder, | |
} | |
impl Sender<bool> for WatcherAutoResponder { | |
fn send_response(self, data: bool) { | |
if let Err(e) = self.watcher_auto_responder.send(data) { | |
{ | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&126u32, | |
&::core::fmt::Arguments::new_v1(&["Failed to reply to WatchAutoBrightness: "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
}; | |
; | |
} | |
} | |
} | |
pub struct WatcherAdjustmentResponder { | |
watcher_adjustment_responder: ControlWatchAutoBrightnessAdjustmentResponder, | |
} | |
impl Sender<f32> for WatcherAdjustmentResponder { | |
fn send_response(self, data: f32) { | |
if let Err(e) = self.watcher_adjustment_responder.send(data) { | |
{ | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&138u32, | |
&::core::fmt::Arguments::new_v1(&["Failed to reply to WatchAutoBrightnessAdjustment: "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
}; | |
; | |
} | |
} | |
} | |
pub struct Control { | |
sensor: Arc<Mutex<dyn SensorControl>>, | |
backlight: Arc<Mutex<dyn BacklightControl>>, | |
set_brightness_abort_handle: Arc<Mutex<Option<AbortHandle>>>, | |
auto_brightness_abort_handle: Option<AbortHandle>, | |
spline: Spline<f32, f32>, | |
current_sender_channel: Arc<Mutex<SenderChannel<f32>>>, | |
auto_sender_channel: Arc<Mutex<SenderChannel<bool>>>, | |
adjustment_sender_channel: Arc<Mutex<SenderChannel<f32>>>, | |
} | |
impl Control { | |
pub async fn new(sensor: Arc<Mutex<dyn SensorControl>>, | |
backlight: Arc<Mutex<dyn BacklightControl>>, | |
current_sender_channel: | |
Arc<Mutex<SenderChannel<f32>>>, | |
auto_sender_channel: Arc<Mutex<SenderChannel<bool>>>, | |
adjustment_sender_channel: | |
Arc<Mutex<SenderChannel<f32>>>) -> Control { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["New Control class"], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
}; | |
; | |
let set_brightness_abort_handle = | |
Arc::new(Mutex::new(None::<AbortHandle>)); | |
let default_table_points = &*BRIGHTNESS_TABLE.lock().await.points; | |
let brightness_table = | |
read_brightness_table_file(BRIGHTNESS_TABLE_FILE_PATH).unwrap_or_else(|e| | |
{ | |
{ | |
let lvl = | |
::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&168u32, | |
&::core::fmt::Arguments::new_v1(&["Error occurred when trying to read existing settings: ", | |
", using default table instead."], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, | |
""); | |
}; | |
; | |
BrightnessTable{points: | |
default_table_points.to_vec(),} | |
}); | |
let spline = generate_spline(&brightness_table); | |
let auto_brightness_abort_handle = None::<AbortHandle>; | |
let mut result = | |
Control{backlight, | |
sensor, | |
set_brightness_abort_handle, | |
auto_brightness_abort_handle, | |
spline, | |
current_sender_channel, | |
auto_sender_channel, | |
adjustment_sender_channel,}; | |
result.start_auto_brightness_task(); | |
result | |
} | |
pub async fn handle_request(&mut self, | |
request: BrightnessControlRequest, | |
watch_current_handler: | |
Arc<Mutex<WatchHandler<f32, | |
WatcherCurrentResponder>>>, | |
watch_auto_handler: | |
Arc<Mutex<WatchHandler<bool, | |
WatcherAutoResponder>>>, | |
watch_adjustment_handler: | |
Arc<Mutex<WatchHandler<f32, | |
WatcherAdjustmentResponder>>>) { | |
match request { | |
BrightnessControlRequest::SetAutoBrightness { | |
control_handle: _ } => { | |
self.set_auto_brightness().await; | |
} | |
BrightnessControlRequest::WatchAutoBrightness { responder } => | |
{ | |
let watch_auto_result = | |
self.watch_auto_brightness(watch_auto_handler, | |
responder).await; | |
match watch_auto_result { | |
Ok(_v) => { } | |
Err(e) => { | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&208u32, | |
&::core::fmt::Arguments::new_v1(&["Watch auto brightness failed due to err ", | |
"."], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
} | |
} | |
} | |
BrightnessControlRequest::SetManualBrightness { | |
value, control_handle: _ } => { | |
let value = num_traits::clamp(value, 0.0, 1.0); | |
self.set_manual_brightness(value).await; | |
} | |
BrightnessControlRequest::SetManualBrightnessSmooth { | |
value, duration, control_handle: _ } => { | |
self.set_manual_brightness_smooth(value, duration).await; | |
} | |
BrightnessControlRequest::WatchCurrentBrightness { responder } | |
=> { | |
let watch_current_result = | |
self.watch_current_brightness(watch_current_handler, | |
responder).await; | |
match watch_current_result { | |
Ok(_v) => { } | |
Err(e) => { | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&227u32, | |
&::core::fmt::Arguments::new_v1(&["Watch current brightness failed due to err ", | |
"."], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
} | |
} | |
} | |
BrightnessControlRequest::SetBrightnessTable { | |
table, control_handle: _ } => { | |
let result = | |
self.check_brightness_table_and_set_new_curve(&table.into()).await; | |
match result { | |
Ok(_v) => { | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Brightness table is valid and set"], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
} | |
Err(e) => { | |
{ | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&236u32, | |
&::core::fmt::Arguments::new_v1(&["Brightness table is not valid because "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
}; | |
; | |
} | |
} | |
} | |
BrightnessControlRequest::SetAutoBrightnessAdjustment { | |
adjustment, control_handle: _ } => { | |
self.scale_new_adjustment(adjustment).await; | |
} | |
BrightnessControlRequest::WatchAutoBrightnessAdjustment { | |
responder } => { | |
let watch_adjustment_result = | |
self.watch_auto_brightness_adjustment(watch_adjustment_handler, | |
responder).await; | |
match watch_adjustment_result { | |
Ok(_v) => { } | |
Err(e) => { | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&253u32, | |
&::core::fmt::Arguments::new_v1(&["Watch adjustment failed due to err ", | |
"."], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
} | |
} | |
} | |
BrightnessControlRequest::GetMaxAbsoluteBrightness { responder | |
} => { | |
let result = self.get_max_absolute_brightness(); | |
match result.await { | |
Ok(value) => { | |
if let Err(e) = responder.send(&mut Ok(value)) { | |
{ | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&261u32, | |
&::core::fmt::Arguments::new_v1(&["Failed to reply to GetMaxAbsoluteBrightness: "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
}; | |
; | |
} | |
} | |
Err(e) => { | |
{ | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&265u32, | |
&::core::fmt::Arguments::new_v1(&["Failed to get max absolute brightness: "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
}; | |
; | |
if let Err(e) = | |
responder.send(&mut Err(ZX_ERR_NOT_SUPPORTED)) | |
{ | |
{ | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&268u32, | |
&::core::fmt::Arguments::new_v1(&["Failed to reply to GetMaxAbsoluteBrightness: "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
}; | |
; | |
} | |
} | |
} | |
} | |
} | |
} | |
pub async fn add_current_sender_channel(&mut self, | |
sender: | |
UnboundedSender<f32>) { | |
self.current_sender_channel.lock().await.add_sender_channel(sender).await; | |
} | |
pub async fn add_auto_sender_channel(&mut self, | |
sender: UnboundedSender<bool>) { | |
self.auto_sender_channel.lock().await.add_sender_channel(sender).await; | |
} | |
pub async fn add_adjustment_sender_channel(&mut self, | |
sender: | |
UnboundedSender<f32>) { | |
self.adjustment_sender_channel.lock().await.add_sender_channel(sender).await; | |
} | |
pub fn get_backlight_and_auto_brightness_on(&mut self) | |
-> (Arc<Mutex<dyn BacklightControl>>, bool) { | |
(self.backlight.clone(), | |
self.auto_brightness_abort_handle.is_some()) | |
} | |
async fn set_auto_brightness(&mut self) { | |
if self.auto_brightness_abort_handle.is_none() { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Auto-brightness turned on"], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
}; | |
; | |
self.start_auto_brightness_task(); | |
self.auto_sender_channel.lock().await.send_value(self.auto_brightness_abort_handle.is_some()); | |
} | |
} | |
async fn watch_auto_brightness(&mut self, | |
watch_auto_handler: | |
Arc<Mutex<WatchHandler<bool, | |
WatcherAutoResponder>>>, | |
responder: | |
ControlWatchAutoBrightnessResponder) | |
-> Result<(), Error> { | |
let mut hanging_get_lock = watch_auto_handler.lock().await; | |
hanging_get_lock.watch(WatcherAutoResponder{watcher_auto_responder: | |
responder,})?; | |
Ok(()) | |
} | |
fn start_auto_brightness_task(&mut self) { | |
if let Some(handle) = &self.auto_brightness_abort_handle.take() { | |
handle.abort(); | |
} | |
let backlight = self.backlight.clone(); | |
let sensor = self.sensor.clone(); | |
let set_brightness_abort_handle = | |
self.set_brightness_abort_handle.clone(); | |
let current_sender_channel = self.current_sender_channel.clone(); | |
let spline = self.spline.clone(); | |
let (abort_handle, abort_registration) = AbortHandle::new_pair(); | |
fasync::Task::spawn(Abortable::new(async move | |
{ | |
let backlight = | |
backlight.clone(); | |
let max_brightness = | |
{ | |
let backlight = | |
backlight.clone(); | |
let backlight = | |
backlight.lock().await; | |
let max_result = | |
backlight.get_max_absolute_brightness(); | |
match max_result.await | |
{ | |
Ok(max_value) | |
=> | |
max_value, | |
Err(_e) => | |
250.0, | |
} | |
}; | |
let mut last_value: | |
i32 = -1; | |
loop { | |
let current_sender_channel = | |
current_sender_channel.clone(); | |
let sensor = | |
sensor.clone(); | |
let mut value = | |
read_sensor_and_get_brightness(sensor, | |
&spline, | |
max_brightness).await; | |
let adjustment = | |
*AUTO_BRIGHTNESS_ADJUSTMENT.lock().await; | |
value = | |
num_traits::clamp(value | |
* | |
adjustment, | |
AUTO_MINIMUM_BRIGHTNESS, | |
1.0); | |
set_brightness(value, | |
set_brightness_abort_handle.clone(), | |
backlight.clone(), | |
current_sender_channel).await; | |
let large_change = | |
(last_value as | |
i32 - | |
value as | |
i32).abs() | |
> | |
LARGE_CHANGE_THRESHOLD_NITS; | |
last_value = | |
value as i32; | |
let delay_timeout = | |
if large_change | |
{ | |
QUICK_SCAN_TIMEOUT_MS | |
} else { | |
SLOW_SCAN_TIMEOUT_MS | |
}; | |
fuchsia_async::Timer::new(Duration::from_millis(delay_timeout).after_now()).await; | |
} | |
}, | |
abort_registration).unwrap_or_else(|_| | |
())).detach(); | |
self.auto_brightness_abort_handle = Some(abort_handle); | |
} | |
async fn set_manual_brightness(&mut self, value: f32) { | |
if let Some(handle) = self.auto_brightness_abort_handle.take() { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Auto-brightness off, brightness set to "], | |
&match (&value,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
}; | |
; | |
handle.abort(); | |
} | |
self.auto_sender_channel.lock().await.send_value(false); | |
let current_sender_channel = self.current_sender_channel.clone(); | |
set_brightness(value, self.set_brightness_abort_handle.clone(), | |
self.backlight.clone(), | |
current_sender_channel).await; | |
} | |
async fn set_manual_brightness_smooth(&mut self, value: f32, | |
duration: i64) { | |
let duration_nanos = Duration::from_nanos(duration); | |
*BRIGHTNESS_CHANGE_DURATION.lock().await = | |
duration_nanos.into_millis().millis(); | |
let value = num_traits::clamp(value, 0.0, 1.0); | |
self.set_manual_brightness(value).await; | |
} | |
async fn watch_current_brightness(&mut self, | |
watch_current_handler: | |
Arc<Mutex<WatchHandler<f32, | |
WatcherCurrentResponder>>>, | |
responder: | |
ControlWatchCurrentBrightnessResponder) | |
-> Result<(), Error> { | |
let mut hanging_get_lock = watch_current_handler.lock().await; | |
hanging_get_lock.watch(WatcherCurrentResponder{watcher_current_responder: | |
responder,})?; | |
Ok(()) | |
} | |
async fn set_brightness_curve(&mut self, table: &BrightnessTable) { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Setting new brightness curve."], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
}; | |
; | |
self.spline = generate_spline(table); | |
self.start_auto_brightness_task(); | |
let result = | |
self.store_brightness_table(table, | |
BRIGHTNESS_TABLE_FILE_PATH); | |
match result { | |
Ok(_v) => { | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Stored successfully"], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
} | |
Err(e) => { | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Didn\'t store successfully due to error "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
} | |
} | |
} | |
fn store_brightness_table(&mut self, table: &BrightnessTable, | |
file_path: &str) -> Result<(), Error> { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Storing brightness table set."], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
}; | |
; | |
let file = fs::File::create(file_path)?; | |
serde_json::to_writer(io::BufWriter::new(file), | |
&table).map_err(|e| | |
::anyhow::private::new_adhoc({ | |
let res = | |
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&["Failed to write to file, ran into error: "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Debug::fmt)], | |
})); | |
res | |
})) | |
} | |
async fn check_brightness_table_and_set_new_curve(&mut self, | |
table: | |
&BrightnessTable) | |
-> Result<(), Error> { | |
let BrightnessTable { points } = table; | |
if points.is_empty() { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Brightness table can not be empty, use the default table instead."], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
}; | |
; | |
let BrightnessTable { points } = | |
&*BRIGHTNESS_TABLE.lock().await; | |
let brightness_table = | |
BrightnessTable{points: points.to_vec(),}; | |
self.set_brightness_curve(&brightness_table).await; | |
return Ok(()); | |
} | |
let mut last_lux = -1.0; | |
for brightness_point in points { | |
if brightness_point.ambient_lux < 0.0 || | |
brightness_point.display_nits < 0.0 { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Lux or nits in this table is negative."], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
}; | |
; | |
return Err({ | |
use ::anyhow::private::kind::*; | |
match { | |
let res = | |
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&["Lux or nits in this table is negative."], | |
&match () | |
{ | |
() | |
=> | |
[], | |
})); | |
res | |
} { | |
error => | |
(&error).anyhow_kind().new(error), | |
} | |
}); | |
} | |
if brightness_point.ambient_lux > last_lux { | |
last_lux = brightness_point.ambient_lux; | |
} else { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Not increasing lux in this table."], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
}; | |
; | |
return Err({ | |
use ::anyhow::private::kind::*; | |
match { | |
let res = | |
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&["Not increasing lux in this table."], | |
&match () | |
{ | |
() | |
=> | |
[], | |
})); | |
res | |
} { | |
error => | |
(&error).anyhow_kind().new(error), | |
} | |
}); | |
} | |
} | |
self.set_brightness_curve(&table).await; | |
Ok(()) | |
} | |
async fn scale_new_adjustment(&mut self, mut adjustment: f32) -> f32 { | |
self.adjustment_sender_channel.lock().await.send_value(adjustment); | |
if adjustment >= 0.0 { | |
adjustment = | |
adjustment * | |
(BRIGHTNESS_USER_MULTIPLIER_MAX - | |
BRIGHTNESS_USER_MULTIPLIER_CENTER) + | |
BRIGHTNESS_USER_MULTIPLIER_CENTER; | |
} else { | |
adjustment = | |
adjustment * | |
(BRIGHTNESS_USER_MULTIPLIER_CENTER - | |
BRIGHTNESS_USER_MULTIPLIER_MIN) + | |
BRIGHTNESS_USER_MULTIPLIER_CENTER; | |
} | |
*AUTO_BRIGHTNESS_ADJUSTMENT.lock().await = adjustment; | |
return adjustment; | |
} | |
async fn watch_auto_brightness_adjustment(&mut self, | |
watch_adjustment_handler: | |
Arc<Mutex<WatchHandler<f32, | |
WatcherAdjustmentResponder>>>, | |
responder: | |
ControlWatchAutoBrightnessAdjustmentResponder) | |
-> Result<(), Error> { | |
let mut hanging_get_lock = watch_adjustment_handler.lock().await; | |
hanging_get_lock.watch(WatcherAdjustmentResponder{watcher_adjustment_responder: | |
responder,})?; | |
Ok(()) | |
} | |
async fn get_max_absolute_brightness(&mut self) | |
-> Result<f64, Error> { | |
let backlight = self.backlight.lock().await; | |
backlight.get_max_absolute_brightness().await | |
} | |
} | |
pub trait ControlTrait { | |
#[must_use] | |
fn handle_request<'life0, | |
'async_trait>(&'life0 mut self, | |
request: BrightnessControlRequest, | |
watch_current_handler: | |
Arc<Mutex<WatchHandler<f32, | |
WatcherCurrentResponder>>>, | |
watch_auto_handler: | |
Arc<Mutex<WatchHandler<bool, | |
WatcherAutoResponder>>>, | |
watch_adjustment_handler: | |
Arc<Mutex<WatchHandler<f32, | |
WatcherAdjustmentResponder>>>) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> + | |
'async_trait>> | |
where | |
'life0: 'async_trait, | |
Self: 'async_trait; | |
#[must_use] | |
fn add_current_sender_channel<'life0, | |
'async_trait>(&'life0 mut self, | |
sender: | |
UnboundedSender<f32>) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> + | |
'async_trait>> | |
where | |
'life0: 'async_trait, | |
Self: 'async_trait; | |
#[must_use] | |
fn add_auto_sender_channel<'life0, | |
'async_trait>(&'life0 mut self, | |
sender: | |
UnboundedSender<bool>) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> + | |
'async_trait>> | |
where | |
'life0: 'async_trait, | |
Self: 'async_trait; | |
#[must_use] | |
fn add_adjustment_sender_channel<'life0, | |
'async_trait>(&'life0 mut self, | |
sender: | |
UnboundedSender<f32>) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> + | |
'async_trait>> | |
where | |
'life0: 'async_trait, | |
Self: 'async_trait; | |
fn get_backlight_and_auto_brightness_on(&mut self) | |
-> (Arc<Mutex<dyn BacklightControl>>, bool); | |
} | |
impl ControlTrait for Control { | |
fn handle_request<'life0, | |
'async_trait>(&'life0 mut self, | |
request: BrightnessControlRequest, | |
watch_current_handler: | |
Arc<Mutex<WatchHandler<f32, | |
WatcherCurrentResponder>>>, | |
watch_auto_handler: | |
Arc<Mutex<WatchHandler<bool, | |
WatcherAutoResponder>>>, | |
watch_adjustment_handler: | |
Arc<Mutex<WatchHandler<f32, | |
WatcherAdjustmentResponder>>>) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> + | |
'async_trait>> where 'life0: 'async_trait, | |
Self: 'async_trait { | |
#[allow(unused_parens, clippy :: missing_docs_in_private_items, | |
clippy :: needless_lifetimes, clippy :: ptr_arg, clippy :: | |
trivially_copy_pass_by_ref, clippy :: | |
type_repetition_in_bounds, clippy :: | |
used_underscore_binding,)] | |
async fn __handle_request(_self: &mut Control, | |
request: BrightnessControlRequest, | |
watch_current_handler: | |
Arc<Mutex<WatchHandler<f32, | |
WatcherCurrentResponder>>>, | |
watch_auto_handler: | |
Arc<Mutex<WatchHandler<bool, | |
WatcherAutoResponder>>>, | |
watch_adjustment_handler: | |
Arc<Mutex<WatchHandler<f32, | |
WatcherAdjustmentResponder>>>) { | |
_self.handle_request(request, watch_current_handler, | |
watch_auto_handler, | |
watch_adjustment_handler).await; | |
} | |
Box::pin(__handle_request::<>(self, request, | |
watch_current_handler, | |
watch_auto_handler, | |
watch_adjustment_handler)) | |
} | |
fn add_current_sender_channel<'life0, | |
'async_trait>(&'life0 mut self, | |
sender: | |
UnboundedSender<f32>) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> + | |
'async_trait>> where 'life0: 'async_trait, | |
Self: 'async_trait { | |
#[allow(unused_parens, clippy :: missing_docs_in_private_items, | |
clippy :: needless_lifetimes, clippy :: ptr_arg, clippy :: | |
trivially_copy_pass_by_ref, clippy :: | |
type_repetition_in_bounds, clippy :: | |
used_underscore_binding,)] | |
async fn __add_current_sender_channel(_self: &mut Control, | |
sender: | |
UnboundedSender<f32>) { | |
_self.add_current_sender_channel(sender).await; | |
} | |
Box::pin(__add_current_sender_channel::<>(self, sender)) | |
} | |
fn add_auto_sender_channel<'life0, | |
'async_trait>(&'life0 mut self, | |
sender: | |
UnboundedSender<bool>) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> + | |
'async_trait>> where 'life0: 'async_trait, | |
Self: 'async_trait { | |
#[allow(unused_parens, clippy :: missing_docs_in_private_items, | |
clippy :: needless_lifetimes, clippy :: ptr_arg, clippy :: | |
trivially_copy_pass_by_ref, clippy :: | |
type_repetition_in_bounds, clippy :: | |
used_underscore_binding,)] | |
async fn __add_auto_sender_channel(_self: &mut Control, | |
sender: | |
UnboundedSender<bool>) { | |
_self.add_auto_sender_channel(sender).await; | |
} | |
Box::pin(__add_auto_sender_channel::<>(self, sender)) | |
} | |
fn add_adjustment_sender_channel<'life0, | |
'async_trait>(&'life0 mut self, | |
sender: | |
UnboundedSender<f32>) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> + | |
'async_trait>> where 'life0: 'async_trait, | |
Self: 'async_trait { | |
#[allow(unused_parens, clippy :: missing_docs_in_private_items, | |
clippy :: needless_lifetimes, clippy :: ptr_arg, clippy :: | |
trivially_copy_pass_by_ref, clippy :: | |
type_repetition_in_bounds, clippy :: | |
used_underscore_binding,)] | |
async fn __add_adjustment_sender_channel(_self: &mut Control, | |
sender: | |
UnboundedSender<f32>) { | |
_self.add_adjustment_sender_channel(sender).await; | |
} | |
Box::pin(__add_adjustment_sender_channel::<>(self, sender)) | |
} | |
fn get_backlight_and_auto_brightness_on(&mut self) | |
-> (Arc<Mutex<dyn BacklightControl>>, bool) { | |
self.get_backlight_and_auto_brightness_on() | |
} | |
} | |
fn read_brightness_table_file(path: &str) | |
-> Result<BrightnessTable, Error> { | |
let file = fs::File::open(path)?; | |
let result = serde_json::from_reader(io::BufReader::new(file)); | |
let result = | |
result.map_err(|e| | |
::anyhow::private::new_adhoc({ | |
let res = | |
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&["Failed to read from file, ran into error: "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Debug::fmt)], | |
})); | |
res | |
})); | |
result | |
} | |
fn generate_spline(table: &BrightnessTable) -> Spline<f32, f32> { | |
let BrightnessTable { points } = table; | |
let mut lux_to_nits_table_to_splines = Vec::new(); | |
for brightness_point in points { | |
lux_to_nits_table_to_splines.push(Key::new(brightness_point.ambient_lux, | |
brightness_point.display_nits, | |
Interpolation::Linear)); | |
} | |
Spline::from_iter(lux_to_nits_table_to_splines.iter().cloned()) | |
} | |
/// Runs the main auto-brightness code. | |
/// This task monitors its running boolean and terminates if it goes false. | |
async fn get_current_brightness(backlight: | |
Arc<Mutex<dyn BacklightControl>>) | |
-> f32 { | |
let backlight = backlight.lock().await; | |
let fut = backlight.get_brightness(); | |
match fut.await { | |
Ok(brightness) => brightness as f32, | |
Err(e) => { | |
if *GET_BRIGHTNESS_FAILED_FIRST.lock().await { | |
{ | |
let lvl = ::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&584u32, | |
&::core::fmt::Arguments::new_v1(&["Failed to get backlight: ", | |
". assuming 1.0"], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, ""); | |
}; | |
; | |
*GET_BRIGHTNESS_FAILED_FIRST.lock().await = false; | |
} | |
*LAST_SET_BRIGHTNESS.lock().await | |
} | |
} | |
} | |
async fn read_sensor_and_get_brightness(sensor: | |
Arc<Mutex<dyn SensorControl>>, | |
spline: &Spline<f32, f32>, | |
max_brightness: f64) -> f32 { | |
let lux = | |
{ | |
let sensor = sensor.lock().await; | |
let fut = sensor.read(); | |
let report = | |
fut.await.expect("Could not read from the sensor"); | |
report.illuminance | |
}; | |
brightness_curve_lux_to_nits(lux, spline).await / | |
max_brightness as f32 | |
} | |
async fn brightness_curve_lux_to_nits(lux: u16, spline: &Spline<f32, f32>) | |
-> f32 { | |
let result = (*spline).clamped_sample(lux as f32); | |
match result { Some(nits) => { return nits; } None => return 1.0, } | |
} | |
/// Sets the brightness of the backlight to a specific value. | |
/// An abortable task is spawned to handle this as it can take a while to do. | |
async fn set_brightness(value: f32, | |
set_brightness_abort_handle: | |
Arc<Mutex<Option<AbortHandle>>>, | |
backlight: Arc<Mutex<dyn BacklightControl>>, | |
current_sender_channel: | |
Arc<Mutex<SenderChannel<f32>>>) { | |
let value = num_traits::clamp(value, 0.0, 1.0); | |
let current_value = get_current_brightness(backlight.clone()).await; | |
if (current_value - value).abs() >= BRIGHTNESS_STEP_SIZE { | |
let mut set_brightness_abort_handle = | |
set_brightness_abort_handle.lock().await; | |
if let Some(handle) = set_brightness_abort_handle.take() { | |
handle.abort(); | |
} | |
let (abort_handle, abort_registration) = AbortHandle::new_pair(); | |
let backlight = backlight.clone(); | |
let current_sender_channel = current_sender_channel.clone(); | |
fasync::Task::spawn(Abortable::new(async move | |
{ | |
set_brightness_impl(value, | |
backlight, | |
current_sender_channel).await; | |
}, | |
abort_registration).unwrap_or_else(|_task_aborted| | |
())).detach(); | |
*set_brightness_abort_handle = Some(abort_handle); | |
} else if (current_value - value).abs() > BRIGHTNESS_MINIMUM_CHANGE { | |
set_brightness_impl(value, backlight, | |
current_sender_channel).await; | |
} | |
} | |
async fn set_brightness_impl(value: f32, | |
backlight: Arc<Mutex<dyn BacklightControl>>, | |
current_sender_channel: | |
Arc<Mutex<SenderChannel<f32>>>) { | |
let current_value = get_current_brightness(backlight.clone()).await; | |
let mut backlight = backlight.lock().await; | |
let set_brightness = | |
|value| | |
{ | |
backlight.set_brightness(value).unwrap_or_else(|e| | |
{ | |
let lvl = | |
::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/control.rs".trim_start_matches("../"), | |
&662u32, | |
&::core::fmt::Arguments::new_v1(&["Failed to set backlight: "], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, | |
""); | |
}) | |
}; | |
let current_sender_channel = current_sender_channel.clone(); | |
set_brightness_slowly(current_value, value, set_brightness, | |
*BRIGHTNESS_CHANGE_DURATION.lock().await, | |
current_sender_channel).await; | |
} | |
/// Change the brightness of the screen slowly to `nits` nits. We don't want to change the screen | |
/// suddenly so we smooth the transition by doing it in a series of small steps. | |
/// The time per step can be changed if needed e.g. to fade up slowly and down quickly. | |
/// When testing we set time_per_step to zero. | |
async fn set_brightness_slowly(current_value: f32, to_value: f32, | |
mut set_brightness: impl FnMut(f64), | |
duration: Duration, | |
current_sender_channel: | |
Arc<Mutex<SenderChannel<f32>>>) { | |
let mut current_value = current_value; | |
let to_value = num_traits::clamp(to_value, 0.0, 1.0); | |
if !(to_value <= 1.0) { | |
::core::panicking::panic("assertion failed: to_value <= 1.0") | |
}; | |
if !(current_value <= 1.0) { | |
::core::panicking::panic("assertion failed: current_value <= 1.0") | |
}; | |
let current_sender_channel = current_sender_channel.clone(); | |
let difference = to_value - current_value; | |
let steps = (difference.abs() / BRIGHTNESS_STEP_SIZE) as u16; | |
if steps > 0 { | |
let time_per_step = | |
cmp::min(duration / steps, | |
MAX_BRIGHTNESS_STEP_TIME_MS.millis()); | |
let step_size = difference / steps as f32; | |
for _i in 0..steps { | |
let current_sender_channel = current_sender_channel.clone(); | |
current_value = current_value + step_size; | |
set_brightness(current_value as f64); | |
current_sender_channel.lock().await.send_value(current_value); | |
if time_per_step.into_millis() > 0 { | |
fuchsia_async::Timer::new(time_per_step.after_now()).await; | |
} | |
} | |
} | |
set_brightness(to_value as f64); | |
current_sender_channel.lock().await.send_value(current_value); | |
*LAST_SET_BRIGHTNESS.lock().await = to_value; | |
} | |
} | |
mod sender_channel { | |
use futures::channel::mpsc::UnboundedSender; | |
use parking_lot::RwLock; | |
use std::sync::Arc; | |
/// Class for storing a list of senders and certain operations on them. | |
/// add_sender_channel adds a sender to the list. | |
/// send_value sends the new_value to the receivers. | |
/// If there is a new channel, the sender will be added to the list in the class. | |
/// Whenever value is changed, every sender in the list should send the new value to the sender. | |
/// If the channel is closed, remove corresponding sender from the list. | |
pub struct SenderChannel<T> { | |
pub sender_channel_vec: Arc<RwLock<Vec<UnboundedSender<T>>>>, | |
} | |
impl <T> SenderChannel<T> where T: Copy { | |
pub fn new() -> SenderChannel<T> { | |
SenderChannel{sender_channel_vec: | |
Arc::new(RwLock::new(Vec::new())),} | |
} | |
pub async fn add_sender_channel(&mut self, | |
sender: UnboundedSender<T>) { | |
self.sender_channel_vec.write().push(sender); | |
} | |
pub fn send_value(&mut self, new_value: T) { | |
let mut sender_channel_vec = self.sender_channel_vec.write(); | |
sender_channel_vec.retain(|sender| | |
{ | |
let sender_success = | |
sender.unbounded_send(new_value); | |
match sender_success { | |
Ok(_v) => true, | |
Err(_e) => false, | |
} | |
}) | |
} | |
} | |
} | |
mod sensor { | |
use std::path::Path; | |
use std::{fs, io}; | |
use anyhow::{format_err, Context as _, Error}; | |
use async_trait::async_trait; | |
use byteorder::{ByteOrder, LittleEndian}; | |
use fidl_fuchsia_hardware_input::{DeviceMarker as SensorMarker, | |
DeviceProxy as SensorProxy, ReportType}; | |
use fuchsia_syslog::fx_log_info; | |
/// Unique signature for the light sensor | |
const HID_SENSOR_DESCRIPTOR: [u8; 4] = [5, 32, 9, 65]; | |
pub struct AmbientLightInputRpt { | |
pub rpt_id: u8, | |
pub state: u8, | |
pub event: u8, | |
pub illuminance: u16, | |
pub red: u16, | |
pub green: u16, | |
pub blue: u16, | |
} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::fmt::Debug for AmbientLightInputRpt { | |
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { | |
match *self { | |
AmbientLightInputRpt { | |
rpt_id: ref __self_0_0, | |
state: ref __self_0_1, | |
event: ref __self_0_2, | |
illuminance: ref __self_0_3, | |
red: ref __self_0_4, | |
green: ref __self_0_5, | |
blue: ref __self_0_6 } => { | |
let debug_trait_builder = | |
&mut ::core::fmt::Formatter::debug_struct(f, | |
"AmbientLightInputRpt"); | |
let _ = | |
::core::fmt::DebugStruct::field(debug_trait_builder, | |
"rpt_id", | |
&&(*__self_0_0)); | |
let _ = | |
::core::fmt::DebugStruct::field(debug_trait_builder, | |
"state", | |
&&(*__self_0_1)); | |
let _ = | |
::core::fmt::DebugStruct::field(debug_trait_builder, | |
"event", | |
&&(*__self_0_2)); | |
let _ = | |
::core::fmt::DebugStruct::field(debug_trait_builder, | |
"illuminance", | |
&&(*__self_0_3)); | |
let _ = | |
::core::fmt::DebugStruct::field(debug_trait_builder, | |
"red", | |
&&(*__self_0_4)); | |
let _ = | |
::core::fmt::DebugStruct::field(debug_trait_builder, | |
"green", | |
&&(*__self_0_5)); | |
let _ = | |
::core::fmt::DebugStruct::field(debug_trait_builder, | |
"blue", | |
&&(*__self_0_6)); | |
::core::fmt::DebugStruct::finish(debug_trait_builder) | |
} | |
} | |
} | |
} | |
/// Opens the sensor's device file. | |
/// Tries all the input devices until the one with the correct signature is found. | |
async fn open_sensor() -> Result<SensorProxy, Error> { | |
let input_devices_directory = "/dev/class/input"; | |
let path = Path::new(input_devices_directory); | |
let entries = fs::read_dir(path)?; | |
for entry in entries { | |
let entry = entry?; | |
let device = | |
open_input_device(entry.path().to_str().expect("Bad path"))?; | |
if let Ok(device_descriptor) = device.get_report_desc().await { | |
if device_descriptor.len() < 4 { | |
return Err(::anyhow::private::new_adhoc("Short HID header")); | |
} | |
let device_header = &device_descriptor[0..4]; | |
if device_header == HID_SENSOR_DESCRIPTOR { | |
return Ok(device); | |
} | |
} | |
} | |
Err(io::Error::new(io::ErrorKind::NotFound, "no sensor found").into()) | |
} | |
/// Reads the sensor's HID record and decodes it. | |
async fn read_sensor(sensor: &SensorProxy) | |
-> Result<AmbientLightInputRpt, Error> { | |
let report = sensor.get_report(ReportType::Input, 1).await?; | |
let report = report.1; | |
if report.len() < 11 { | |
return Err(::anyhow::private::new_adhoc("Sensor HID report too short")); | |
} | |
Ok(AmbientLightInputRpt{rpt_id: report[0], | |
state: report[1], | |
event: report[2], | |
illuminance: | |
LittleEndian::read_u16(&report[3..5]), | |
red: LittleEndian::read_u16(&report[5..7]), | |
blue: LittleEndian::read_u16(&report[7..9]), | |
green: | |
LittleEndian::read_u16(&report[9..11]),}) | |
} | |
/// TODO(lingxueluo) Default and temporary report when sensor is not valid(fxbug.dev/42782). | |
fn default_report() -> Result<AmbientLightInputRpt, Error> { | |
Ok(AmbientLightInputRpt{rpt_id: 0, | |
state: 0, | |
event: 0, | |
illuminance: 200, | |
red: 200, | |
green: 200, | |
blue: 200,}) | |
} | |
fn open_input_device(path: &str) -> Result<SensorProxy, Error> { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Opening sensor at "], | |
&match (&path,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Debug::fmt)], | |
}), | |
lvl, ""); | |
}; | |
; | |
let (proxy, server) = | |
fidl::endpoints::create_proxy::<SensorMarker>().context("Failed to create sensor proxy")?; | |
fdio::service_connect(path, | |
server.into_channel()).context("Failed to connect built-in service")?; | |
Ok(proxy) | |
} | |
pub struct Sensor { | |
proxy: Option<SensorProxy>, | |
} | |
impl Sensor { | |
pub async fn new() -> Sensor { | |
let proxy = open_sensor().await; | |
match proxy { | |
Ok(proxy) => return Sensor{proxy: Some(proxy),}, | |
Err(_e) => { | |
{ | |
::std::io::_print(::core::fmt::Arguments::new_v1(&["No valid sensor found.\n"], | |
&match () | |
{ | |
() | |
=> | |
[], | |
})); | |
}; | |
return Sensor{proxy: None,}; | |
} | |
} | |
} | |
async fn read(&self) -> Result<AmbientLightInputRpt, Error> { | |
if self.proxy.is_none() { | |
default_report() | |
} else { read_sensor(self.proxy.as_ref().unwrap()).await } | |
} | |
} | |
pub trait SensorControl: Send { | |
#[must_use] | |
fn read<'life0, 'async_trait>(&'life0 self) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = | |
Result<AmbientLightInputRpt, | |
Error>> + | |
::core::marker::Send + 'async_trait>> | |
where | |
'life0: 'async_trait, | |
Self: 'async_trait; | |
} | |
impl SensorControl for Sensor { | |
fn read<'life0, 'async_trait>(&'life0 self) | |
-> | |
::core::pin::Pin<Box<dyn ::core::future::Future<Output = | |
Result<AmbientLightInputRpt, | |
Error>> + | |
::core::marker::Send + 'async_trait>> where | |
'life0: 'async_trait, Self: 'async_trait { | |
#[allow(unused_parens, clippy :: missing_docs_in_private_items, | |
clippy :: needless_lifetimes, clippy :: ptr_arg, clippy :: | |
trivially_copy_pass_by_ref, clippy :: | |
type_repetition_in_bounds, clippy :: | |
used_underscore_binding,)] | |
async fn __read(_self: &Sensor) | |
-> Result<AmbientLightInputRpt, Error> { | |
_self.read().await | |
} | |
Box::pin(__read::<>(self)) | |
} | |
} | |
} | |
const ADJUSTMENT_DELTA: f32 = 0.1; | |
async fn run_brightness_server(mut stream: ControlRequestStream, | |
control: Arc<Mutex<dyn ControlTrait>>) | |
-> Result<(), Error> { | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["New brightness server"], | |
&match () | |
{ | |
() => | |
[], | |
}), lvl, | |
""); | |
}; | |
; | |
let (initial_current, initial_auto) = | |
get_initial_value(control.clone()).await?; | |
let watch_auto_handler: | |
Arc<Mutex<WatchHandler<bool, WatcherAutoResponder>>> = | |
Arc::new(Mutex::new(WatchHandler::create(Some(initial_auto)))); | |
let (auto_channel_sender, auto_channel_receiver) = | |
futures::channel::mpsc::unbounded::<bool>(); | |
let watch_current_handler: | |
Arc<Mutex<WatchHandler<f32, WatcherCurrentResponder>>> = | |
Arc::new(Mutex::new(WatchHandler::create(Some(initial_current)))); | |
let (current_channel_sender, current_channel_receiver) = | |
futures::channel::mpsc::unbounded::<f32>(); | |
let watch_adjustment_handler: | |
Arc<Mutex<WatchHandler<f32, WatcherAdjustmentResponder>>> = | |
Arc::new(Mutex::new(WatchHandler::create_with_change_fn(Box::new(move | |
|old_data: | |
&f32, | |
new_data: | |
&f32| | |
{ | |
(*new_data | |
- | |
*old_data).abs() | |
>= | |
ADJUSTMENT_DELTA | |
}), | |
Some(0.0)))); | |
let (adjustment_channel_sender, adjustment_channel_receiver) = | |
futures::channel::mpsc::unbounded::<f32>(); | |
let control_clone = control.clone(); | |
{ | |
let mut control = control_clone.lock().await; | |
control.add_current_sender_channel(current_channel_sender).await; | |
control.add_auto_sender_channel(auto_channel_sender).await; | |
control.add_adjustment_sender_channel(adjustment_channel_sender).await; | |
} | |
let listen_current_task_abort_handle = | |
start_listen_task(watch_current_handler.clone(), | |
Arc::new(Mutex::new(current_channel_receiver))); | |
let listen_auto_task_abort_handle = | |
start_listen_task(watch_auto_handler.clone(), | |
Arc::new(Mutex::new(auto_channel_receiver))); | |
let listen_adjustment_task_abort_handle = | |
start_listen_task(watch_adjustment_handler.clone(), | |
Arc::new(Mutex::new(adjustment_channel_receiver))); | |
while let Some(request) = | |
stream.try_next().await.context("error running brightness server")? | |
{ | |
let mut control = control.lock().await; | |
control.handle_request(request, watch_current_handler.clone(), | |
watch_auto_handler.clone(), | |
watch_adjustment_handler.clone()).await; | |
} | |
listen_current_task_abort_handle.abort(); | |
listen_auto_task_abort_handle.abort(); | |
listen_adjustment_task_abort_handle.abort(); | |
Ok(()) | |
} | |
fn start_listen_task<T: std::marker::Send, | |
ST: std::marker::Send>(watch_handler: | |
Arc<Mutex<WatchHandler<T, | |
ST>>>, | |
receiver: | |
Arc<Mutex<UnboundedReceiver<T>>>) | |
-> AbortHandle where T: std::clone::Clone + 'static, | |
ST: watch_handler::Sender<T> + 'static { | |
let (abort_handle, abort_registration) = AbortHandle::new_pair(); | |
let receiver = receiver.clone(); | |
fasync::Task::spawn(Abortable::new(async move | |
{ | |
while let Some(value) = | |
receiver.lock().await.next().await | |
{ | |
let mut handler_lock = | |
watch_handler.lock().await; | |
handler_lock.set_value(value); | |
} | |
}, | |
abort_registration).unwrap_or_else(|_| | |
())).detach(); | |
abort_handle | |
} | |
async fn get_initial_value(control: Arc<Mutex<dyn ControlTrait>>) | |
-> Result<(f32, bool), Error> { | |
let mut control = control.lock().await; | |
let (backlight, auto_brightness_on) = | |
control.get_backlight_and_auto_brightness_on(); | |
let backlight = backlight.lock().await; | |
let initial_brightness = | |
backlight.get_brightness().await.unwrap_or_else(|e| | |
{ | |
{ | |
let lvl = | |
::fuchsia_syslog::levels::ERROR; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["[", | |
"(", | |
")] "], | |
&match (&"../../src/ui/bin/brightness_manager/src/main.rs".trim_start_matches("../"), | |
&130u32, | |
&::core::fmt::Arguments::new_v1(&["Didn\'t get the initial brightness in watch due to err ", | |
", assuming 1.0."], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt)], | |
})) | |
{ | |
(arg0, | |
arg1, | |
arg2) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg1, | |
::core::fmt::Display::fmt), | |
::core::fmt::ArgumentV1::new(arg2, | |
::core::fmt::Display::fmt)], | |
}), | |
lvl, | |
""); | |
}; | |
; | |
1.0 | |
}); | |
Ok((initial_brightness as f32, auto_brightness_on)) | |
} | |
async fn run_brightness_service(fs: | |
ServiceFs<ServiceObjLocal<'static, | |
ControlRequestStream>>, | |
control: Arc<Mutex<dyn ControlTrait>>, | |
run_server: | |
impl Fn(ControlRequestStream, | |
Arc<Mutex<dyn ControlTrait>>) | |
-> | |
Pin<Box<dyn Future<Output = | |
Result<(), | |
Error>>>>) | |
-> Result<(), Error> { | |
const MAX_CONCURRENT: usize = 10_000; | |
let fut = | |
fs.for_each_concurrent(MAX_CONCURRENT, | |
|stream| | |
{ | |
let control = control.clone(); | |
run_server(stream, | |
control).unwrap_or_else(|e| | |
{ | |
let lvl = | |
::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&[""], | |
&match (&e,) | |
{ | |
(arg0,) | |
=> | |
[::core::fmt::ArgumentV1::new(arg0, | |
::core::fmt::Debug::fmt)], | |
}), | |
lvl, | |
""); | |
}) | |
}); | |
fut.await; | |
Ok(()) | |
} | |
fn main() -> Result<(), Error> { | |
async fn func() -> Result<(), Error> { | |
{ | |
fuchsia_syslog::init_with_tags(&["brightness"])?; | |
{ | |
let lvl = ::fuchsia_syslog::levels::INFO; | |
::fuchsia_syslog::log_helper(::core::fmt::Arguments::new_v1(&["Started"], | |
&match () | |
{ | |
() | |
=> | |
[], | |
}), | |
lvl, ""); | |
}; | |
; | |
let mut fs = ServiceFs::new_local(); | |
fs.dir("svc").add_fidl_service(|stream: ControlRequestStream| | |
stream); | |
fs.take_and_serve_directory_handle()?; | |
let backlight = Backlight::new().await?; | |
let backlight = Arc::new(Mutex::new(backlight)); | |
let sensor = Sensor::new().await; | |
let sensor = Arc::new(Mutex::new(sensor)); | |
let current_sender_channel: SenderChannel<f32> = | |
SenderChannel::new(); | |
let current_sender_channel = | |
Arc::new(Mutex::new(current_sender_channel)); | |
let auto_sender_channel: SenderChannel<bool> = | |
SenderChannel::new(); | |
let auto_sender_channel = | |
Arc::new(Mutex::new(auto_sender_channel)); | |
let adjustment_sender_channel: SenderChannel<f32> = | |
SenderChannel::new(); | |
let adjustment_sender_channel = | |
Arc::new(Mutex::new(adjustment_sender_channel)); | |
let control = | |
Control::new(sensor, backlight, current_sender_channel, | |
auto_sender_channel, | |
adjustment_sender_channel).await; | |
let control = Arc::new(Mutex::new(control)); | |
let run_server: | |
fn(stream: ControlRequestStream, | |
control: Arc<Mutex<dyn ControlTrait>>) | |
-> Pin<Box<dyn Future<Output = Result<(), Error>>>> = | |
|stream, control| | |
Box::pin(run_brightness_server(stream, control)); | |
run_brightness_service(fs, control, run_server).await?; | |
Ok(()) | |
} | |
} | |
::fuchsia_async::Executor::new().expect("Failed to create executor").run_singlethreaded(func()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment