blob: 0ca50ebc9a80cf2e336aa3d08cf40b7f2aaa6b82 [file] [log] [blame]
// 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 fidl::endpoints::ServiceMarker;
use fidl_fuchsia_settings::{
Error, IntlMarker, IntlRequest, IntlRequestStream, IntlSetResponder, IntlSettings,
IntlWatchResponder,
};
use fuchsia_async as fasync;
use futures::future::LocalBoxFuture;
use futures::FutureExt;
use crate::fidl_processor::{process_stream, RequestContext};
use crate::switchboard::base::{
FidlResponseErrorLogger, SettingRequest, SettingResponse, SettingType, SwitchboardClient,
};
use crate::switchboard::hanging_get_handler::Sender;
impl Sender<IntlSettings> for IntlWatchResponder {
fn send_response(self, data: IntlSettings) {
self.send(&mut Ok(data)).log_fidl_response_error(IntlMarker::DEBUG_NAME);
}
}
impl From<SettingResponse> for IntlSettings {
fn from(response: SettingResponse) -> Self {
if let SettingResponse::Intl(info) = response {
return info.into();
}
panic!("incorrect value sent to intl");
}
}
impl From<IntlSettings> for SettingRequest {
fn from(settings: IntlSettings) -> Self {
SettingRequest::SetIntlInfo(settings.into())
}
}
async fn set(
context: RequestContext<IntlSettings, IntlWatchResponder>,
settings: IntlSettings,
responder: IntlSetResponder,
) {
match context.switchboard_client.request(SettingType::Intl, settings.into()).await {
Ok(response_rx) => {
fasync::spawn(async move {
let result = match response_rx.await {
Ok(Ok(_)) => responder.send(&mut Ok(())),
_ => responder.send(&mut Err(Error::Failed)),
};
result.log_fidl_response_error(IntlMarker::DEBUG_NAME);
});
}
Err(_) => {
// Report back an error immediately if we could not successfully make the intl set
// request. The return result can be ignored as there is no actionable steps that
// can be taken.
responder.send(&mut Err(Error::Failed)).log_fidl_response_error(IntlMarker::DEBUG_NAME);
}
}
}
pub fn spawn_intl_fidl_handler(switchboard_client: SwitchboardClient, stream: IntlRequestStream) {
process_stream::<IntlMarker, IntlSettings, IntlWatchResponder>(
stream,
switchboard_client,
SettingType::Intl,
Box::new(
move |context, req| -> LocalBoxFuture<'_, Result<Option<IntlRequest>, anyhow::Error>> {
async move {
// Support future expansion of FIDL
#[allow(unreachable_patterns)]
match req {
IntlRequest::Set { settings, responder } => {
set(context.clone(), settings, responder).await;
}
IntlRequest::Watch { responder } => context.watch(responder).await,
_ => {
return Ok(Some(req));
}
}
return Ok(None);
}
.boxed_local()
},
),
);
}
#[cfg(test)]
mod tests {
use crate::switchboard::intl_types::{HourCycle, IntlInfo, LocaleId, TemperatureUnit};
use super::*;
#[fuchsia_async::run_singlethreaded(test)]
async fn test_request_from_settings_empty() {
let request = SettingRequest::from(IntlSettings::empty());
assert_eq!(
request,
SettingRequest::SetIntlInfo(IntlInfo {
locales: None,
temperature_unit: None,
time_zone_id: None,
hour_cycle: None,
})
);
}
#[fuchsia_async::run_singlethreaded(test)]
async fn test_request_from_settings() {
const TIME_ZONE_ID: &'static str = "PDT";
let intl_settings = IntlSettings {
locales: Some(vec![fidl_fuchsia_intl::LocaleId { id: "blah".into() }]),
temperature_unit: Some(fidl_fuchsia_intl::TemperatureUnit::Celsius),
time_zone_id: Some(fidl_fuchsia_intl::TimeZoneId { id: TIME_ZONE_ID.to_string() }),
hour_cycle: Some(fidl_fuchsia_settings::HourCycle::H12),
};
let request = SettingRequest::from(intl_settings);
assert_eq!(
request,
SettingRequest::SetIntlInfo(IntlInfo {
locales: Some(vec![LocaleId { id: "blah".into() }]),
temperature_unit: Some(TemperatureUnit::Celsius),
time_zone_id: Some(TIME_ZONE_ID.to_string()),
hour_cycle: Some(HourCycle::H12),
})
);
}
}