| // Copyright 2018 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. |
| |
| #![feature(async_await, await_macro, futures_api)] |
| |
| mod ime; |
| mod ime_service; |
| #[cfg(test)] |
| mod test_helpers; |
| |
| use failure::{Error, ResultExt}; |
| use fidl::endpoints::ServiceMarker; |
| use fidl_fuchsia_ui_input::{ImeServiceMarker, ImeVisibilityServiceMarker}; |
| use fidl_fuchsia_ui_text::TextInputContextMarker; |
| use fuchsia_app::server::ServicesServer; |
| use fuchsia_syslog; |
| |
| fn main() -> Result<(), Error> { |
| fuchsia_syslog::init_with_tags(&["ime_service"]).expect("ime syslog init should not fail"); |
| let mut executor = fuchsia_async::Executor::new() |
| .context("Creating fuchsia_async executor for IME service failed")?; |
| let ime_service = ime_service::ImeService::new(); |
| let ime_service1 = ime_service.clone(); |
| let ime_service2 = ime_service.clone(); |
| let ime_service3 = ime_service.clone(); |
| let done = ServicesServer::new() |
| .add_service((ImeServiceMarker::NAME, move |chan| { |
| ime_service1.bind_ime_service(chan); |
| })) |
| .add_service((ImeVisibilityServiceMarker::NAME, move |chan| { |
| ime_service2.bind_ime_visibility_service(chan); |
| })) |
| .add_service((TextInputContextMarker::NAME, move |chan| { |
| ime_service3.bind_text_input_context(chan); |
| })) |
| .start() |
| .context("Creating ServicesServer for IME service failed")?; |
| executor |
| .run_singlethreaded(done) |
| .context("Attempt to start up IME services on async::Executor failed")?; |
| |
| Ok(()) |
| } |
| |
| #[cfg(test)] |
| mod test { |
| use fidl_fuchsia_ui_input as uii; |
| use fidl_fuchsia_ui_text as txt; |
| use fidl_fuchsia_ui_text_testing as txt_testing; |
| use fuchsia_app::client::Launcher; |
| use futures::prelude::*; |
| |
| #[test] |
| // implementation is not complete, so we're ignoring this test for now. |
| #[ignore] |
| fn test_external_text_field_implementation() { |
| fuchsia_syslog::init_with_tags(&["ime_service"]).expect("ime syslog init should not fail"); |
| let mut executor = fuchsia_async::Executor::new() |
| .expect("Creating fuchsia_async executor for IME service failed"); |
| let launcher = Launcher::new().expect("Failed to open launcher service"); |
| let app = launcher |
| .launch( |
| "fuchsia-pkg://fuchsia.com/text_test_suite#meta/test_suite.cmx".to_string(), |
| None, |
| ) |
| .expect("Failed to launch testing service"); |
| let tester = app |
| .connect_to_service(txt_testing::TextFieldTestSuiteMarker) |
| .expect("Failed to connect to testing service"); |
| let done = (async move || { |
| let mut passed = true; |
| let test_list = await!(tester.list_tests()).expect("Failed to get list of tests"); |
| for test in test_list { |
| if let Err(e) = await!(run_test(&tester, test.id)) { |
| passed = false; |
| eprintln!("[ FAIL ] {}\n{}", test.name, e); |
| } else { |
| eprintln!("[ ok ] {}", test.name); |
| } |
| } |
| if !passed { |
| panic!("Text integration tests failed"); |
| } |
| })(); |
| executor.run_singlethreaded(done); |
| } |
| |
| async fn run_test( |
| tester: &txt_testing::TextFieldTestSuiteProxy, |
| test_id: u64, |
| ) -> Result<(), String> { |
| let mut ime_service = crate::ime_service::ImeService::new(); |
| let (text_proxy, server_end) = |
| fidl::endpoints::create_proxy::<txt::TextInputContextMarker>() |
| .expect("Failed to create proxy"); |
| let (imec_client, _imec_server) = |
| fidl::endpoints::create_endpoints::<uii::InputMethodEditorClientMarker>() |
| .expect("Failed to create endpoints"); |
| let (_ime_client, ime_server) = |
| fidl::endpoints::create_endpoints::<uii::InputMethodEditorMarker>() |
| .expect("Failed to create endpoints"); |
| let chan = fuchsia_async::Channel::from_channel(server_end.into_channel()) |
| .expect("Failed to create channel"); |
| ime_service.bind_text_input_context(chan); |
| ime_service.get_input_method_editor( |
| uii::KeyboardType::Text, |
| uii::InputMethodAction::Done, |
| crate::test_helpers::default_state(), |
| imec_client, |
| ime_server, |
| ); |
| let mut stream = text_proxy.take_event_stream(); |
| let msg = await!(stream.try_next()) |
| .expect("Failed to get event.") |
| .expect("TextInputContext event stream unexpectedly closed."); |
| let text_field = match msg { |
| txt::TextInputContextEvent::OnFocus { text_field, .. } => text_field, |
| _ => panic!("Expected text_field to pass OnFocus event type"), |
| }; |
| let (passed, msg) = await!(tester.run_test(text_field, test_id)) |
| .expect("Call to text testing service failed"); |
| if passed { |
| Ok(()) |
| } else { |
| Err(msg) |
| } |
| } |
| } |