|
18 | 18 | #include "flutter/flow/embedded_views.h"
|
19 | 19 | #include "flutter/lib/ui/window/platform_message.h"
|
20 | 20 | #include "flutter/lib/ui/window/window.h"
|
| 21 | +#include "gmock/gmock.h" |
21 | 22 | #include "gtest/gtest.h"
|
22 | 23 |
|
23 | 24 | #include "surface.h"
|
@@ -131,14 +132,28 @@ class MockFocuser : public fuchsia::ui::views::Focuser {
|
131 | 132 | ~MockFocuser() override = default;
|
132 | 133 |
|
133 | 134 | bool request_focus_called = false;
|
| 135 | + bool fail_request_focus = false; |
134 | 136 |
|
135 | 137 | private:
|
136 | 138 | void RequestFocus(fuchsia::ui::views::ViewRef view_ref,
|
137 | 139 | RequestFocusCallback callback) override {
|
138 | 140 | request_focus_called = true;
|
| 141 | + auto result = |
| 142 | + fail_request_focus |
| 143 | + ? fuchsia::ui::views::Focuser_RequestFocus_Result::WithErr( |
| 144 | + fuchsia::ui::views::Error::DENIED) |
| 145 | + : fuchsia::ui::views::Focuser_RequestFocus_Result::WithResponse( |
| 146 | + fuchsia::ui::views::Focuser_RequestFocus_Response()); |
| 147 | + callback(std::move(result)); |
139 | 148 | }
|
140 | 149 | };
|
141 | 150 |
|
| 151 | +class MockResponse : public flutter::PlatformMessageResponse { |
| 152 | + public: |
| 153 | + MOCK_METHOD1(Complete, void(std::unique_ptr<fml::Mapping> data)); |
| 154 | + MOCK_METHOD0(CompleteEmpty, void()); |
| 155 | +}; |
| 156 | + |
142 | 157 | TEST_F(PlatformViewTests, ChangesAccessibilitySettings) {
|
143 | 158 | sys::testing::ServiceDirectoryProvider services_provider(dispatcher());
|
144 | 159 |
|
@@ -513,16 +528,115 @@ TEST_F(PlatformViewTests, RequestFocusTest) {
|
513 | 528 | "}",
|
514 | 529 | b.get());
|
515 | 530 |
|
| 531 | + // Define a custom gmock matcher to capture the response to platform message. |
| 532 | + struct DataArg { |
| 533 | + void Complete(std::unique_ptr<fml::Mapping> data) { |
| 534 | + this->data = std::move(data); |
| 535 | + } |
| 536 | + std::unique_ptr<fml::Mapping> data; |
| 537 | + }; |
| 538 | + DataArg data_arg; |
| 539 | + fml::RefPtr<MockResponse> response = fml::MakeRefCounted<MockResponse>(); |
| 540 | + EXPECT_CALL(*response, Complete(testing::_)) |
| 541 | + .WillOnce(testing::Invoke(&data_arg, &DataArg::Complete)); |
| 542 | + |
516 | 543 | fml::RefPtr<flutter::PlatformMessage> message =
|
517 | 544 | fml::MakeRefCounted<flutter::PlatformMessage>(
|
518 | 545 | "flutter/platform_views",
|
519 |
| - std::vector<uint8_t>(buff, buff + sizeof(buff)), |
520 |
| - fml::RefPtr<flutter::PlatformMessageResponse>()); |
| 546 | + std::vector<uint8_t>(buff, buff + sizeof(buff)), response); |
| 547 | + base_view->HandlePlatformMessage(message); |
| 548 | + |
| 549 | + RunLoopUntilIdle(); |
| 550 | + |
| 551 | + EXPECT_TRUE(mock_focuser.request_focus_called); |
| 552 | + auto result = std::string((const char*)data_arg.data->GetMapping(), |
| 553 | + data_arg.data->GetSize()); |
| 554 | + EXPECT_EQ(std::string("[0]"), result); |
| 555 | +} |
| 556 | + |
| 557 | +// Test to make sure that PlatformView correctly registers messages sent on |
| 558 | +// the "flutter/platform_views" channel, correctly parses the JSON it receives |
| 559 | +// and calls the focuser's RequestFocus with the appropriate args. |
| 560 | +TEST_F(PlatformViewTests, RequestFocusFailTest) { |
| 561 | + sys::testing::ServiceDirectoryProvider services_provider(dispatcher()); |
| 562 | + MockPlatformViewDelegate delegate; |
| 563 | + zx::eventpair a, b; |
| 564 | + zx::eventpair::create(/* flags */ 0u, &a, &b); |
| 565 | + auto view_ref = fuchsia::ui::views::ViewRef({ |
| 566 | + .reference = std::move(a), |
| 567 | + }); |
| 568 | + flutter::TaskRunners task_runners = |
| 569 | + flutter::TaskRunners("test_runners", nullptr, nullptr, nullptr, nullptr); |
| 570 | + |
| 571 | + MockFocuser mock_focuser; |
| 572 | + mock_focuser.fail_request_focus = true; |
| 573 | + fidl::BindingSet<fuchsia::ui::views::Focuser> focuser_bindings; |
| 574 | + auto focuser_handle = focuser_bindings.AddBinding(&mock_focuser); |
| 575 | + |
| 576 | + auto platform_view = flutter_runner::PlatformView( |
| 577 | + delegate, // delegate |
| 578 | + "test_platform_view", // label |
| 579 | + std::move(view_ref), // view_refs |
| 580 | + std::move(task_runners), // task_runners |
| 581 | + services_provider.service_directory(), // runner_services |
| 582 | + nullptr, // parent_environment_service_provider_handle |
| 583 | + nullptr, // session_listener_request |
| 584 | + std::move(focuser_handle), // focuser, |
| 585 | + nullptr, // on_session_listener_error_callback |
| 586 | + nullptr, // on_enable_wireframe_callback, |
| 587 | + nullptr, // on_create_view_callback, |
| 588 | + nullptr, // on_update_view_callback, |
| 589 | + nullptr, // on_destroy_view_callback, |
| 590 | + nullptr, // on_create_surface_callback, |
| 591 | + fml::TimeDelta::Zero(), // vsync_offset |
| 592 | + ZX_HANDLE_INVALID // vsync_event_handle |
| 593 | + ); |
| 594 | + |
| 595 | + // Cast platform_view to its base view so we can have access to the public |
| 596 | + // "HandlePlatformMessage" function. |
| 597 | + auto base_view = dynamic_cast<flutter::PlatformView*>(&platform_view); |
| 598 | + EXPECT_TRUE(base_view); |
| 599 | + |
| 600 | + // JSON for the message to be passed into the PlatformView. |
| 601 | + char buff[254]; |
| 602 | + snprintf(buff, sizeof(buff), |
| 603 | + "{" |
| 604 | + " \"method\":\"View.requestFocus\"," |
| 605 | + " \"args\": {" |
| 606 | + " \"viewRef\":%u" |
| 607 | + " }" |
| 608 | + "}", |
| 609 | + b.get()); |
| 610 | + |
| 611 | + // Define a custom gmock matcher to capture the response to platform message. |
| 612 | + struct DataArg { |
| 613 | + void Complete(std::unique_ptr<fml::Mapping> data) { |
| 614 | + this->data = std::move(data); |
| 615 | + } |
| 616 | + std::unique_ptr<fml::Mapping> data; |
| 617 | + }; |
| 618 | + DataArg data_arg; |
| 619 | + fml::RefPtr<MockResponse> response = fml::MakeRefCounted<MockResponse>(); |
| 620 | + EXPECT_CALL(*response, Complete(testing::_)) |
| 621 | + .WillOnce(testing::Invoke(&data_arg, &DataArg::Complete)); |
| 622 | + |
| 623 | + fml::RefPtr<flutter::PlatformMessage> message = |
| 624 | + fml::MakeRefCounted<flutter::PlatformMessage>( |
| 625 | + "flutter/platform_views", |
| 626 | + std::vector<uint8_t>(buff, buff + sizeof(buff)), response); |
521 | 627 | base_view->HandlePlatformMessage(message);
|
522 | 628 |
|
523 | 629 | RunLoopUntilIdle();
|
524 | 630 |
|
525 | 631 | EXPECT_TRUE(mock_focuser.request_focus_called);
|
| 632 | + auto result = std::string((const char*)data_arg.data->GetMapping(), |
| 633 | + data_arg.data->GetSize()); |
| 634 | + std::ostringstream out; |
| 635 | + out << "[" |
| 636 | + << static_cast<std::underlying_type_t<fuchsia::ui::views::Error>>( |
| 637 | + fuchsia::ui::views::Error::DENIED) |
| 638 | + << "]"; |
| 639 | + EXPECT_EQ(out.str(), result); |
526 | 640 | }
|
527 | 641 |
|
528 | 642 | // Test to make sure that PlatformView correctly returns a Surface instance
|
|
0 commit comments