diff --git a/garnet/bin/setui/src/main.rs b/garnet/bin/setui/src/main.rs index 31d042f38afd4630cb4c38bc683c10836a58c942..fbed5784a129ba24f9469be4ab57b39af03eab9f 100644 --- a/garnet/bin/setui/src/main.rs +++ b/garnet/bin/setui/src/main.rs @@ -5,14 +5,17 @@ use { failure::Error, - fidl_fuchsia_setui::SetUiServiceRequestStream, + fidl_fuchsia_setui::*, fuchsia_async as fasync, fuchsia_component::server::ServiceFs, fuchsia_syslog::{self as syslog, fx_log_info}, - futures::{StreamExt, TryFutureExt}, + futures::StreamExt, + log::error, + setui_handler::SetUIHandler, + std::sync::Arc, }; -mod setui_service; +mod setui_handler; fn main() -> Result<(), Error> { syslog::init_with_tags(&["setui-service"]).expect("Can't init logger"); @@ -21,17 +24,20 @@ fn main() -> Result<(), Error> { let mut executor = fasync::Executor::new()?; let mut fs = ServiceFs::new(); - fs.dir("public").add_fidl_service(spawn_setui_service); - fs.take_and_serve_directory_handle()?; + let handler = Arc::new(SetUIHandler::new()); + + fs.dir("public").add_fidl_service(move |stream: SetUiServiceRequestStream| { + let handler_clone = handler.clone(); + fx_log_info!("Connecting to setui_service"); + fasync::spawn( + async move { + await!(handler_clone.handle_stream(stream)) + .unwrap_or_else(|e| error!("Failed to spawn {:?}", e)) + }, + ); + }); + fs.take_and_serve_directory_handle()?; let () = executor.run_singlethreaded(fs.collect()); Ok(()) } - -fn spawn_setui_service(stream: SetUiServiceRequestStream) { - fx_log_info!("Connecting to setui_service"); - fasync::spawn( - setui_service::start_setui_service(stream) - .unwrap_or_else(|e| eprintln!("Failed to spawn {:?}", e)), - ) -} diff --git a/garnet/bin/setui/src/setui_handler.rs b/garnet/bin/setui/src/setui_handler.rs new file mode 100644 index 0000000000000000000000000000000000000000..179b556747d3e3c17c41d144cadefd1549f3db44 --- /dev/null +++ b/garnet/bin/setui/src/setui_handler.rs @@ -0,0 +1,68 @@ +// 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 failure::Error; +use fidl_fuchsia_setui::*; +use futures::prelude::*; + +pub struct SetUIHandler {} + +/// SetUIHandler handles all API calls for the service. It is intended to be +/// used as a single instance to service multiple streams. +impl SetUIHandler { + /// In the future, will populate with supporting classes, such as adapters. + pub fn new() -> SetUIHandler { + Self {} + } + + /// Asynchronous handling of the given stream. Note that we must consider the + /// possibility of simultaneous active streams. + pub async fn handle_stream(&self, mut stream: SetUiServiceRequestStream) -> Result<(), Error> { + while let Some(req) = await!(stream.try_next())? { + await!(self.handle_request(req))?; + } + + Ok(()) + } + + /// Routes a given request to the proper handling function. + pub async fn handle_request(&self, req: SetUiServiceRequest) -> Result<(), fidl::Error> { + match req { + SetUiServiceRequest::Mutate { setting_type, mutation, responder } => { + let mut response = self.mutate(setting_type, mutation); + responder.send(&mut response)?; + } + _ => {} + } + Ok(()) + } + + /// Applies a mutation + fn mutate(&self, _setting_type: SettingType, _mutation: Mutation) -> MutationResponse { + MutationResponse { return_code: ReturnCode::Ok } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + /// A basic test to exercise that basic functionality works. In this case, we + /// mutate the unknown type, reserved for testing. We should always immediately + /// receive back an Ok response. + #[test] + fn test_ok() { + let handler = SetUIHandler::new(); + let string_mutation = + StringMutation { operation: StringOperation::Update, value: "Hi".to_string() }; + + let result = handler.mutate( + SettingType::Unknown, + fidl_fuchsia_setui::Mutation::StringMutationValue(string_mutation), + ); + + assert_eq!(result, MutationResponse { return_code: ReturnCode::Ok }); + } + +} diff --git a/garnet/bin/setui/src/setui_service.rs b/garnet/bin/setui/src/setui_service.rs deleted file mode 100644 index 5fd2e90ebffc9d5ffc809879613b829c977f464e..0000000000000000000000000000000000000000 --- a/garnet/bin/setui/src/setui_service.rs +++ /dev/null @@ -1,52 +0,0 @@ -// 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 { - failure::Error, - failure::ResultExt, - fidl_fuchsia_setui::*, - futures::prelude::*, -}; - -pub async fn start_setui_service(mut stream: SetUiServiceRequestStream) -> Result<(), Error> { - while let Some(event) = await!(stream.try_next()).context("error reading value from stream")? { - await!(handler(event))?; - } - // event_listener will now be dropped, closing the listener - Ok(()) -} - -async fn handler(event: SetUiServiceRequest) -> fidl::Result<()> { - match event { - SetUiServiceRequest::Mutate { setting_type, mutation, responder } => { - responder.send(&mut mutate(setting_type, mutation))?; - } - _ => {} - } - - Ok(()) -} - -fn mutate(_setting_type: SettingType, _mutation: Mutation) -> MutationResponse { - MutationResponse { return_code: ReturnCode::Ok } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_ok() { - let string_mutation = - StringMutation { operation: StringOperation::Update, value: "Hi".to_string() }; - - let result = mutate( - SettingType::Unknown, - fidl_fuchsia_setui::Mutation::StringMutationValue(string_mutation), - ); - - assert_eq!(result, MutationResponse { return_code: ReturnCode::Ok }); - } - -}