| // 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. |
| |
| #include <fuchsia/ui/views/accessibility/cpp/fidl.h> |
| #include <lib/fidl/cpp/binding_set.h> |
| #include <lib/sys/cpp/testing/test_with_environment.h> |
| #include <lib/syslog/cpp/macros.h> |
| #include <lib/ui/scenic/cpp/view_ref_pair.h> |
| #include <lib/ui/scenic/cpp/view_token_pair.h> |
| |
| #include "src/ui/bin/root_presenter/app.h" |
| #include "src/ui/bin/root_presenter/tests/fakes/fake_keyboard_focus_controller.h" |
| #include "src/ui/bin/root_presenter/tests/fakes/fake_scenic.h" |
| |
| namespace root_presenter { |
| namespace testing { |
| |
| class AccessibilityFocuserRegistryTest : public sys::testing::TestWithEnvironment { |
| protected: |
| void SetUp() override { |
| auto services = CreateServices(); |
| |
| // Add the service under test using its launch info. |
| // Here, Root Presenter will have the interface |
| // fuchsia::ui::views::accessibility::FocuserRegistry tested. |
| // The component is a singleton. This means that the same Root Presenter will handle the two |
| // services added here. |
| zx_status_t status = services->AddServiceWithLaunchInfo( |
| {.url = "fuchsia-pkg://fuchsia.com/root_presenter#meta/root_presenter.cmx"}, |
| fuchsia::ui::views::accessibility::FocuserRegistry::Name_); |
| ASSERT_EQ(ZX_OK, status); |
| |
| status = services->AddServiceWithLaunchInfo( |
| {.url = "fuchsia-pkg://fuchsia.com/root_presenter#meta/root_presenter.cmx"}, |
| fuchsia::ui::policy::Presenter::Name_); |
| ASSERT_EQ(ZX_OK, status); |
| |
| services->AddService(fake_scenic_.GetHandler(), fuchsia::ui::scenic::Scenic::Name_); |
| services->AddService(fake_keyboard_focus_controller_.GetHandler(), |
| fuchsia::ui::keyboard::focus::Controller::Name_); |
| |
| // Create the synthetic environment. |
| environment_ = |
| CreateNewEnclosingEnvironment("accessibility_focuser_registry", std::move(services)); |
| WaitForEnclosingEnvToStart(environment_.get()); |
| |
| // Instantiate the registry. This is the interface being tested. |
| environment_->ConnectToService(registry_.NewRequest()); |
| // Instantiate the presenter_. This is a helper interface to initialize Scenic services inside |
| // Root Presenter. |
| environment_->ConnectToService(presenter_.NewRequest()); |
| |
| ASSERT_TRUE(registry_.is_bound()); |
| ASSERT_TRUE(presenter_.is_bound()); |
| } |
| |
| fuchsia::ui::views::accessibility::FocuserRegistryPtr registry_; |
| fuchsia::ui::policy::PresenterPtr presenter_; |
| |
| FakeScenic fake_scenic_; |
| std::unique_ptr<sys::testing::EnclosingEnvironment> environment_; |
| FakeKeyboardFocusController fake_keyboard_focus_controller_; |
| }; |
| |
| TEST_F(AccessibilityFocuserRegistryTest, AccessibilityFocusRequestIsDeferredUntilScenicConnects) { |
| fuchsia::ui::views::FocuserPtr view_focuser; |
| registry_->RegisterFocuser(view_focuser.NewRequest()); |
| RunLoopUntil([&view_focuser] { return view_focuser.is_bound(); }); |
| bool callback_ran = false; |
| auto callback = [&callback_ran](fuchsia::ui::views::Focuser_RequestFocus_Result result) { |
| EXPECT_FALSE(result.is_err()); |
| callback_ran = true; |
| }; |
| auto [view_control_ref, view_ref] = scenic::ViewRefPair::New(); |
| view_focuser->RequestFocus(std::move(view_ref), std::move(callback)); |
| RunLoopUntilIdle(); |
| // The request is deferred, because scenic hasn't started yet. |
| EXPECT_FALSE(callback_ran); |
| // Here, a dummy call to PresentView() is done so that Scenic services are initialized. |
| auto [view_token, view_holder_token] = scenic::ViewTokenPair::New(); |
| presenter_->PresentView(std::move(view_holder_token), nullptr); |
| // Now, the deferred requests are dispatched. |
| RunLoopUntil([&callback_ran] { return callback_ran; }); |
| } |
| |
| TEST_F(AccessibilityFocuserRegistryTest, AccessibilityFocusRequestIsForwardedToScenic) { |
| fuchsia::ui::views::FocuserPtr view_focuser; |
| registry_->RegisterFocuser(view_focuser.NewRequest()); |
| RunLoopUntil([&view_focuser] { return view_focuser.is_bound(); }); |
| bool callback_ran = false; |
| auto callback = [&callback_ran](fuchsia::ui::views::Focuser_RequestFocus_Result result) { |
| EXPECT_FALSE(result.is_err()); |
| callback_ran = true; |
| }; |
| // Here, a dummy call to PresentView() is done so that Scenic services are initialized. |
| auto [view_token, view_holder_token] = scenic::ViewTokenPair::New(); |
| presenter_->PresentView(std::move(view_holder_token), nullptr); |
| RunLoopUntilIdle(); |
| auto [view_control_ref, view_ref] = scenic::ViewRefPair::New(); |
| view_focuser->RequestFocus(std::move(view_ref), std::move(callback)); |
| RunLoopUntil([&callback_ran] { return callback_ran; }); |
| } |
| |
| } // namespace testing |
| } // namespace root_presenter |