blob: e39695a9766c3648294a56230a93cf22dd0b9fb4 [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.
use crate::base::SettingType;
use crate::fidl_common::FidlResponseErrorLogger;
use crate::fidl_hanging_get_responder;
use crate::fidl_process_custom;
use crate::fidl_processor::settings::RequestContext;
use crate::handler::base::Request;
use crate::input::types::{DeviceStateSource, InputDevice, InputDeviceType};
use crate::request_respond;
use fidl::endpoints::ProtocolMarker;
use fidl_fuchsia_settings::{
Error, InputMarker, InputRequest, InputSettings, InputState as FidlInputState,
InputWatch2Responder, InputWatchResponder,
};
use fuchsia_async as fasync;
use fuchsia_syslog::fx_log_err;
fidl_hanging_get_responder!(InputMarker, InputSettings, InputWatch2Responder);
fidl_hanging_get_responder!(InputMarker, InputSettings, InputWatchResponder);
fn to_request(fidl_input_states: Vec<FidlInputState>) -> Option<Request> {
// Every device requires at least a device type and state flags.
let mut input_states_invalid_args = fidl_input_states
.iter()
.filter(|input_state| input_state.device_type.is_none() || input_state.state.is_none());
// If any devices were filtered out, the args were invalid, so exit.
if input_states_invalid_args.next().is_some() {
fx_log_err!("Failed to parse input request: missing args");
return None;
}
let input_states = fidl_input_states
.iter()
.map(|input_state| {
let device_type: InputDeviceType = input_state.device_type.unwrap().into();
let device_state = input_state.state.clone().unwrap().into();
let device_name = input_state.name.clone().unwrap_or_else(|| device_type.to_string());
let source_states = [(DeviceStateSource::SOFTWARE, device_state)].into();
InputDevice { name: device_name, device_type, state: device_state, source_states }
})
.collect();
Some(Request::SetInputStates(input_states))
}
fidl_process_custom!(
Input,
SettingType::Input,
InputWatchResponder,
InputSettings,
process_request,
SettingType::Input,
InputWatch2Responder,
InputSettings,
process_request_2,
);
// TODO(fxbug.dev/65686): Remove when clients are ported over to new version
async fn process_request_2(
context: RequestContext<InputSettings, InputWatch2Responder>,
req: InputRequest,
) -> Result<Option<InputRequest>, anyhow::Error> {
// Support future expansion of FIDL.
#[allow(unreachable_patterns)]
match req {
InputRequest::SetStates { input_states, responder } => {
if let Some(request) = to_request(input_states) {
fasync::Task::spawn(async move {
request_respond!(
context,
responder,
SettingType::Input,
request,
Ok(()),
Err(fidl_fuchsia_settings::Error::Failed),
InputMarker
);
})
.detach();
} else {
responder
.send(&mut Err(Error::Unsupported))
.log_fidl_response_error(InputMarker::DEBUG_NAME);
}
}
InputRequest::Watch2 { responder } => {
context.watch(responder, true).await;
}
_ => {
return Ok(Some(req));
}
}
Ok(None)
}
async fn process_request(
context: RequestContext<InputSettings, InputWatchResponder>,
req: InputRequest,
) -> Result<Option<InputRequest>, anyhow::Error> {
// Support future expansion of FIDL.
#[allow(unreachable_patterns)]
match req {
InputRequest::Set { input_states, responder } => {
if let Some(request) = to_request(input_states) {
fasync::Task::spawn(async move {
request_respond!(
context,
responder,
SettingType::Input,
request,
Ok(()),
Err(fidl_fuchsia_settings::Error::Failed),
InputMarker
);
})
.detach();
} else {
responder
.send(&mut Err(Error::Unsupported))
.log_fidl_response_error(InputMarker::DEBUG_NAME);
}
}
InputRequest::Watch { responder } => {
context.watch(responder, true).await;
}
_ => {
return Ok(Some(req));
}
}
Ok(None)
}